2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file config_generator.cpp
18 * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
22 #include "config_generator.h"
24 #include <dpl/binary_queue.h>
25 #include <dpl/log/log.h>
26 #include <dpl/foreach.h>
27 #include <libxml/xmlversion.h>
28 #include <libxml/xmlstring.h>
29 #include <libxml/tree.h>
35 XmlDocWrapper(xmlDocPtr doc) : m_doc(doc) {}
36 ~XmlDocWrapper() { xmlFreeDoc(m_doc); }
37 xmlDocPtr get() const { return m_doc; }
43 class XmlNodeWrapper {
45 XmlNodeWrapper(xmlNodePtr node) : m_node(node) {}
46 xmlNodePtr get() const { return m_node; }
56 const xmlChar* _DOC_VERSION_ = BAD_CAST "1.0";
57 const xmlChar* _WIDGET_ = BAD_CAST "widget";
58 const xmlChar* _SRC_ = BAD_CAST "src";
59 const xmlChar* _REQUIRED_ = BAD_CAST "required";
60 const xmlChar* _TRUE_ = BAD_CAST "true";
61 const xmlChar* _FALSE_ = BAD_CAST "false";
62 const xmlChar* _NAME_ = BAD_CAST "name";
63 const xmlChar* _VALUE_ = BAD_CAST "value";
64 const xmlChar* _XMLNS_ = BAD_CAST "xmlns";
65 const xmlChar* _NAMESPACE_ = BAD_CAST "http://www.w3.org/ns/widgets";
66 const xmlChar* _ID_ = BAD_CAST "id";
67 const xmlChar* _VERSION_ = BAD_CAST "version";
68 const xmlChar* _HEIGHT_ = BAD_CAST "height";
69 const xmlChar* _WIDTH_ = BAD_CAST "width";
70 const xmlChar* _VIEWMODES_ = BAD_CAST "viewmodes";
71 const xmlChar* _ORIGIN_ = BAD_CAST "origin";
72 const xmlChar* _SUBDOMAINS_ = BAD_CAST "subdomains";
73 const xmlChar* _HREF_ = BAD_CAST "href";
74 const xmlChar* _EMAIL_ = BAD_CAST "email";
75 const xmlChar* _READONLY_ = BAD_CAST "readonly";
78 const xmlChar* name; // Tag name
79 const Tag parent; // Tag parent
82 const TagInfo TAG[TAG_COUNT] = {
83 {BAD_CAST "widget", INVALID},
84 {BAD_CAST "name", WIDGET},
85 {BAD_CAST "icon", WIDGET},
86 {BAD_CAST "content", WIDGET},
87 {BAD_CAST "author", WIDGET},
88 {BAD_CAST "license", WIDGET},
89 {BAD_CAST "feature", WIDGET},
90 {BAD_CAST "param", FEATURE},
91 {BAD_CAST "description", WIDGET},
92 {BAD_CAST "preference", WIDGET},
93 {BAD_CAST "access", WIDGET},
94 {BAD_CAST "tizen:setting", WIDGET}
98 xmlNodePtr NewNode(xmlNodePtr parent, Tag tagId)
100 LogDebug("Adding node " << TAG[tagId].name);
103 Assert(0==xmlStrcmp(parent->name,TAG[TAG[tagId].parent].name) &&
106 xmlNodePtr node = xmlNewNode(NULL, TAG[tagId].name);
108 Throw(NodeCreationError);
110 if (NULL == xmlAddChild(parent,node)) {
111 Throw(ChildCreationError);
116 void AddProperty(xmlNodePtr node, const xmlChar* name, const xmlChar* value)
118 if (!xmlNewProp(node, name, value)) {
119 Throw(PropertyCreationError);
123 void AddBoolProp(xmlNodePtr node, const xmlChar* name, bool value)
125 AddProperty(node, name, (value ? _TRUE_ : _FALSE_));
129 void AddCharProp(xmlNodePtr node, const xmlChar* name, const char* value)
132 AddProperty(node, name, BAD_CAST value);
136 void AddCharProp(xmlNodePtr node, const char* name, const char* value)
139 AddProperty(node, BAD_CAST name, BAD_CAST value);
143 void AddNameAndValue(xmlNodePtr node, const char* name, const char* value)
145 AddCharProp(node, _NAME_, name);
146 AddCharProp(node, _VALUE_, value);
151 // ELEMENT ///////////////////////////////////////////////////////////////
154 #define DECLARE_HANDLER_CONTENT(tag) \
156 XmlNodeWrapperPtr Element::Handler<tag, const char*>::CreateNode( \
159 xmlNodePtr node = NewNode(m_parent->get(), tag); \
160 xmlNodeSetContent(node, BAD_CAST value); \
161 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); \
165 // <tag src="value"></tag>
166 #define DECLARE_HANDLER_SRC_ATTRIBUTE(tag) \
168 XmlNodeWrapperPtr Element::Handler<tag, const char*>::CreateNode( \
171 xmlNodePtr node = NewNode(m_parent->get(), tag); \
172 AddCharProp(node, _SRC_, value); \
173 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); \
177 DECLARE_HANDLER_CONTENT(NAME);
178 DECLARE_HANDLER_CONTENT(DESCRIPTION);
179 DECLARE_HANDLER_SRC_ATTRIBUTE(ICON);
180 DECLARE_HANDLER_SRC_ATTRIBUTE(CONTENT);
182 // <author href="href" email="email">author</author>
184 XmlNodeWrapperPtr Element::
185 Handler<AUTHOR, const char*, const char*, const char*>::
186 CreateNode(const char* href, const char* email, const char* author)
188 xmlNodePtr node = NewNode(m_parent->get(), AUTHOR);
189 AddCharProp(node, _HREF_, href);
190 AddCharProp(node, _EMAIL_, email);
191 xmlNodeSetContent(node, BAD_CAST author);
192 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
196 // <license href="href">license</license>
198 XmlNodeWrapperPtr Element::Handler<LICENSE, const char*, const char*>::
199 CreateNode(const char* href, const char* license)
201 xmlNodePtr node = NewNode(m_parent->get(), LICENSE);
202 AddCharProp(node, _HREF_, href);
203 xmlNodeSetContent(node, BAD_CAST license);
204 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
208 // <feature name="value" required="true"></feature>
210 XmlNodeWrapperPtr Element::Handler<FEATURE, const char*, bool>::CreateNode(
214 xmlNodePtr node = NewNode(m_parent->get(), FEATURE);
215 AddCharProp(node, _NAME_, value);
216 AddBoolProp(node, _REQUIRED_, required);
217 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
221 // <param name="name" value="true"></param>
223 XmlNodeWrapperPtr Element::Handler<PARAM, const char*, bool>::CreateNode(
227 xmlNodePtr node = NewNode(m_parent->get(), PARAM);
228 AddCharProp(node, _NAME_, name);
229 AddBoolProp(node, _VALUE_, value);
230 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
234 // <param name="name" value="value"></param>
236 XmlNodeWrapperPtr Element::Handler<PARAM, const char*, const char*>::CreateNode(
240 xmlNodePtr node = NewNode(m_parent->get(), PARAM);
241 AddNameAndValue(node, name, value);
242 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
246 // <preference name="name" value="value"></preference>
248 XmlNodeWrapperPtr Element::Handler<PREFERENCE, const char*, const char*>::
249 CreateNode(const char* name, const char* value)
251 xmlNodePtr node = NewNode(m_parent->get(), PREFERENCE);
252 AddNameAndValue(node, name, value);
253 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
257 // <preference name="name" value="value" readonly="true"></preference>
259 XmlNodeWrapperPtr Element::Handler<PREFERENCE, const char*, const char*, bool>::
260 CreateNode(const char* name, const char* value, bool readonly)
262 xmlNodePtr node = NewNode(m_parent->get(), PREFERENCE);
263 AddNameAndValue(node, name, value);
264 AddBoolProp(node, _READONLY_, readonly);
265 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
269 // <access name="value"></access>
271 XmlNodeWrapperPtr Element::Handler<ACCESS, const char*>::CreateNode(
274 xmlNodePtr node = NewNode(m_parent->get(), ACCESS);
275 AddCharProp(node, _ORIGIN_, value);
276 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
280 // <access name="value" subdomains="true"></access>
282 XmlNodeWrapperPtr Element::Handler<ACCESS, const char*, bool>::CreateNode(
286 xmlNodePtr node = NewNode(m_parent->get(), ACCESS);
287 AddCharProp(node, _ORIGIN_, value);
288 AddBoolProp(node, _SUBDOMAINS_, required);
289 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
293 // <tizen:setting name="value"></tizen:setting>
295 XmlNodeWrapperPtr Element::Handler<TIZEN_SETTING, const char*, const char*>::
296 CreateNode(const char* name, const char* value)
298 xmlNodePtr node = NewNode(m_parent->get(), TIZEN_SETTING);
299 AddCharProp(node, name, value);
300 XmlNodeWrapperPtr ret(new XmlNodeWrapper(node));
304 // DOCUMENT //////////////////////////////////////////////////////////////
306 // <widget xmlns="value" id="id" viewmodes="viewmodes"></widget>
308 XmlNodeWrapperPtr Document::
309 Handler<WIDGET, const char*, const char*, const char*>::
310 CreateRoot(const char* id, const char* version, const char* viewmodes)
312 Assert(NULL == xmlDocGetRootElement(m_document->get()) &&
313 "The document already has root node");
316 xmlNodePtr root = xmlNewNode(NULL, _WIDGET_);
318 Throw(NodeCreationError);
320 xmlDocSetRootElement(m_document->get(), root);
321 AddProperty(root, _XMLNS_, _NAMESPACE_ );
322 AddCharProp(root, _ID_, id);
323 AddCharProp(root, _VERSION_, version);
324 AddCharProp(root, _VIEWMODES_, viewmodes);
325 XmlNodeWrapperPtr ret(new XmlNodeWrapper(root));
330 * <widget xmlns="value" id="id" height="height" width="width"
331 * viewmodes="viewmodes"></widget>
334 XmlNodeWrapperPtr Document::
335 Handler<WIDGET, const char*, const char*, int, int>::
336 CreateRoot(const char* id, const char* version, int height, int width)
339 xmlNodePtr root = xmlNewNode(NULL, _WIDGET_);
341 Throw(NodeCreationError);
343 xmlDocSetRootElement(m_document->get(), root);
344 AddProperty(root, _XMLNS_, _NAMESPACE_ );
345 AddCharProp(root, _ID_, id);
346 AddCharProp(root, _VERSION_, version);
347 std::ostringstream hstream;
349 AddProperty(root, _HEIGHT_, BAD_CAST hstream.str().c_str());
350 std::ostringstream wstream;
352 AddProperty(root, _WIDTH_, BAD_CAST wstream.str().c_str());
353 XmlNodeWrapperPtr ret(new XmlNodeWrapper(root));
357 DocumentPtr Document::Create()
359 // check libxml version
362 xmlDocPtr xmlDoc = xmlNewDoc(_DOC_VERSION_);
363 if( NULL == xmlDoc) {
364 Throw(DocCreationError);
368 XmlDocWrapperPtr document(new XmlDocWrapper(xmlDoc));
370 DocumentPtr doc(new Document(document));
374 Document::~Document()
378 void Document::Write(DPL::AbstractOutput& output)
381 xmlChar* buffer = NULL;
384 xmlDocDumpFormatMemory(m_document->get(), &buffer, &size, 1);
385 std::unique_ptr<xmlChar, xmlFreeFunc> bufferPtr(buffer, xmlFree);
388 bq.AppendCopy(static_cast<unsigned char*>(buffer), size);
389 output.Write(bq, bq.Size());