Tizen 2.0 Release
[framework/system/sync-agent.git] / src / framework / device-manager / mo_ddf_parser.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <string.h>
19
20 #include "utility/sync_util.h"
21
22 #include <libxml/xmlreader.h>
23 #include <glib.h>
24 #include <glib/gprintf.h>
25
26 #include "device-manager/mo_parser_properties.h"
27 #include "device-manager/mo_ddf_parser.h"
28 #include "device-manager/mo_accessor_internal.h"
29
30 #ifndef SYNC_AGENT_LOG
31 #undef LOG_TAG
32 #define LOG_TAG "AF_MO"
33 #endif
34
35 #define DELIMETER "/"
36
37 static dm_mo_parse_properties_cb parsing_properties[DM_FRAMEWORK_PROPERTY_COUNT] = {
38         dm_parse_property_access_type,
39         dm_parse_property_default_value,
40         dm_parse_property_description,
41         dm_parse_property_dffFormat,
42         dm_parse_property_occurrence,
43         dm_parse_property_scope,
44         dm_parse_property_df_title,
45         dm_parse_property_df_type
46 };
47
48 static void _processNode(sync_agent_dm_mo_type_e mo_type, xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node);
49
50 static void __set_Node(sync_agent_dm_mo_type_e mo_type, xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node);
51
52 static void __set_Path(xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node);
53
54 static void __set_Properties(xmlTextReaderPtr reader, sync_agent_dm_mo_framework_property_s * property);
55
56 sync_agent_dm_mo_error_e dm_mo_construct_mo_tree_ddf(sync_agent_dm_mo_type_e mo_type, const char *vendar_file, sync_agent_dm_mo_node_s * root_node)
57 {
58         _EXTERN_FUNC_ENTER;
59
60         retvm_if(vendar_file == NULL, SYNC_AGENT_DM_MO_FAIL, "vendar_file is NULL !!");
61         retvm_if(root_node == NULL, SYNC_AGENT_DM_MO_FAIL, "sync_agent_dm_mo_node_s is NULL !!");
62
63         xmlTextReaderPtr reader = xmlReaderForFile(vendar_file, NULL, 0);
64         if (reader != NULL) {
65                 _processNode(mo_type, reader, root_node);
66                 xmlFreeTextReader(reader);
67         } else {
68                 _DEBUG_ERROR("Unable to open %s", vendar_file);
69                 return SYNC_AGENT_DM_MO_FAIL;
70         }
71
72         _EXTERN_FUNC_EXIT;
73
74         return SYNC_AGENT_DM_MO_SUCCESS;
75 }
76
77 static void _processNode(sync_agent_dm_mo_type_e mo_type, xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node)
78 {
79         _INNER_FUNC_ENTER;
80
81         retm_if(mo_node == NULL, "sync_agent_dm_mo_node_s is NULL !!");
82
83         int node_type;
84         const char *name = NULL;
85
86         do {
87                 int ret = xmlTextReaderRead(reader);
88                 if (ret != 1) {
89                         _DEBUG_TRACE("End Parsing XML");
90                         break;
91                 }
92                 node_type = xmlTextReaderNodeType(reader);
93                 name = (const char *)xmlTextReaderConstName(reader);
94                 if (node_type == XML_ELEMENT_NODE) {
95                         if (!strcmp(name, "NodeName")) {
96                                 __set_Node(mo_type, reader, mo_node);
97                         } else if (!strcmp(name, "DFProperties")) {
98                                 __set_Properties(reader, mo_node->framework_property);
99                         } else if (!strcmp(name, "Path")) {
100                                 mo_node->type = SYNC_AGENT_DM_MO_NODE_FIRST;
101                                 __set_Path(reader, mo_node);
102                         } else if (!strcmp(name, "Node")) {
103                                 sync_agent_dm_mo_node_s *child_node = (sync_agent_dm_mo_node_s *) calloc(1, sizeof(sync_agent_dm_mo_node_s));
104                                 if (child_node == NULL) {
105                                         _DEBUG_ERROR("CALLOC failed !!!");
106                                         return;
107                                 }
108                                 child_node->full_path = strdup(mo_node->full_path);
109                                 child_node->type = SYNC_AGENT_DM_MO_NODE_LEAF;
110                                 child_node->child_node_cnt = 0;
111                                 child_node->framework_property = calloc(1, sizeof(sync_agent_dm_mo_framework_property_s));
112                                 if (child_node->framework_property == NULL) {
113                                         _DEBUG_ERROR("CALLOC failed !!!");
114                                         dm_free_mo(child_node, 1);
115                                         return;
116                                 }
117                                 child_node->runtime_property = calloc(1, sizeof(sync_agent_dm_mo_runtime_property_s));
118                                 if (child_node->runtime_property == NULL) {
119                                         _DEBUG_ERROR("CALLOC failed !!!");
120                                         dm_free_mo(child_node, 1);
121                                         return;
122                                 }
123                                 child_node->child_node_list = NULL;
124                                 child_node->next_node = NULL;
125                                 child_node->parent_node = mo_node;
126                                 /*
127                                  * Add to Child list
128                                  */
129                                 mo_node->child_node_cnt++;
130                                 sync_agent_dm_mo_node_s *pCursor = mo_node->child_node_list;
131                                 if (pCursor == NULL) {
132                                         mo_node->child_node_list = child_node;
133                                 } else {
134                                         while (pCursor->next_node != NULL) {
135                                                 pCursor = pCursor->next_node;
136                                         }
137
138                                         pCursor->next_node = child_node;
139                                 }
140
141                                 if ((mo_node->type != SYNC_AGENT_DM_MO_NODE_ROOT) && (mo_node->type != SYNC_AGENT_DM_MO_NODE_FIRST)) {
142                                         mo_node->type = SYNC_AGENT_DM_MO_NODE_INTERIOR;
143                                 }
144
145                                 _processNode(mo_type, reader, child_node);
146                         }
147                 }
148         } while (!(node_type == XML_ELEMENT_DECL && !strcmp(name, "Node")));
149
150         _INNER_FUNC_EXIT;
151 }
152
153 static void __set_Node(sync_agent_dm_mo_type_e mo_type, xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node)
154 {
155         _INNER_FUNC_ENTER;
156
157         retm_if(mo_node == NULL, "sync_agent_dm_mo_node_s is NULL !!");
158
159         int node_type;
160         const char *name = NULL;
161
162         do {
163                 xmlTextReaderRead(reader);
164
165                 node_type = xmlTextReaderNodeType(reader);
166                 name = (const char *)xmlTextReaderConstValue(reader);
167
168                 if (node_type == XML_TEXT_NODE) {
169                         if (name == NULL) {
170                                 name = "";
171                         }
172
173                         if (mo_node->full_path != NULL) {
174                                 char *temp = mo_node->full_path;
175                                 int full_path_len = strlen(mo_node->full_path) + strlen(name) + strlen(DELIMETER) + 1;
176                                 int len = 0;
177                                 mo_node->full_path = (char *)calloc(full_path_len, sizeof(char));
178
179                                 if (mo_node->full_path != NULL) {
180                                         len = g_strlcat(mo_node->full_path, temp, full_path_len);
181                                         len = g_strlcat(mo_node->full_path, DELIMETER, full_path_len);
182                                         len = g_strlcat(mo_node->full_path, name, full_path_len);
183                                         _DEBUG_VERBOSE(" mo_node->full_path : %s!!", mo_node->full_path);
184
185                                         if (len >= full_path_len) {
186                                                 _DEBUG_ERROR("mo_node->full_path buffer overflow !!");
187                                                 /* todo : exception handling */
188                                         }
189
190                                         _DEBUG_VERBOSE(" mo_node name : %s!!", name);
191                                         mo_node->name = strdup(name);
192
193                                         free(temp);
194                                 } else {
195                                         _DEBUG_ERROR("alloc fail !!");
196                                         break;
197                                 }
198                         }
199                         break;
200                 }
201         } while (!(node_type == XML_ELEMENT_DECL && !strcmp(name, "NodeName")));
202
203         _INNER_FUNC_EXIT;
204 }
205
206 static void __set_Path(xmlTextReaderPtr reader, sync_agent_dm_mo_node_s * mo_node)
207 {
208         _INNER_FUNC_ENTER;
209
210         retm_if(mo_node == NULL, "sync_agent_dm_mo_node_s is NULL !!");
211
212         int node_type;
213         char *name = NULL;
214
215         do {
216                 xmlTextReaderRead(reader);
217
218                 node_type = xmlTextReaderNodeType(reader);
219                 name = (char *)xmlTextReaderConstValue(reader);
220
221                 if (node_type == XML_TEXT_NODE) {
222                         if (name == NULL) {
223                                 name = "";
224                         }
225                         _DEBUG_VERBOSE("name : %s", name);
226                         _DEBUG_VERBOSE("mo_parent_node : %s", mo_node->parent_node->name);
227                         if (!strcmp(name, mo_node->parent_node->name)) {
228                                 _DEBUG_VERBOSE("Already <Path> is same root path");
229                                 break;
230                         }
231
232                         sync_agent_dm_mo_node_s *parent_node = mo_node->parent_node;
233                         char *last_delimit = name;
234
235                         do {
236                                 last_delimit = strchr(last_delimit, '/');
237                                 if (last_delimit == NULL) {
238                                         break;
239                                 }
240                                 last_delimit += 1;
241
242                                 char *cursor = last_delimit;
243                                 while (*cursor != '\0') {
244                                         if (*cursor == '/') {
245                                                 break;
246                                         }
247                                         cursor++;
248                                 }
249
250                                 int node_len = cursor - last_delimit;
251                                 char *node_name = (char *)calloc(node_len + 1, sizeof(char));
252                                 if (node_name == NULL) {
253                                         _DEBUG_ERROR("CALLOC failed !!!");
254                                         return;
255                                 }
256                                 strncpy(node_name, last_delimit, node_len);
257
258                                 int full_path_len = cursor - name;
259                                 char *full_path = (char *)calloc(full_path_len + 1, sizeof(char));
260                                 if (full_path == NULL) {
261                                         _DEBUG_ERROR("CALLOC failed !!!");
262                                         free(node_name);
263                                         return;
264                                 }
265                                 strncpy(full_path, name, full_path_len);
266
267                                 _DEBUG_VERBOSE("node_name : %s", node_name);
268                                 _DEBUG_VERBOSE("full_path : %s", full_path);
269
270                                 /*
271                                  * Resetting Link
272                                  */
273                                 sync_agent_dm_mo_node_s *new_mo_node = (sync_agent_dm_mo_node_s *) calloc(1, sizeof(sync_agent_dm_mo_node_s));
274                                 if (new_mo_node == NULL) {
275                                         _DEBUG_ERROR("CALLOC failed !!!");
276                                         free(node_name);
277                                         free(full_path);
278                                         return;
279                                 }
280                                 new_mo_node->name = node_name;
281                                 new_mo_node->full_path = full_path;
282                                 new_mo_node->type = SYNC_AGENT_DM_MO_NODE_INTERIOR;
283                                 new_mo_node->framework_property = (sync_agent_dm_mo_framework_property_s *) calloc(1, sizeof(sync_agent_dm_mo_framework_property_s));
284                                 if (new_mo_node->framework_property == NULL) {
285                                         _DEBUG_ERROR("CALLOC failed !!!");
286                                         dm_free_mo(new_mo_node, 1);
287                                         return;
288                                 }
289                                 new_mo_node->runtime_property = (sync_agent_dm_mo_runtime_property_s *) calloc(1, sizeof(sync_agent_dm_mo_runtime_property_s));
290                                 if (new_mo_node->runtime_property == NULL) {
291                                         _DEBUG_ERROR("CALLOC failed !!!");
292                                         dm_free_mo(new_mo_node, 1);
293                                         return;
294                                 }
295                                 new_mo_node->parent_node = parent_node;
296                                 parent_node->child_node_list = new_mo_node;
297
298                                 parent_node = new_mo_node;
299
300                         } while (last_delimit != NULL);
301
302                         _DEBUG_VERBOSE("New=========");
303                         /*
304                          * Resetting full_path of mo_node
305                          */
306                         parent_node->child_node_list = mo_node;
307                         mo_node->parent_node = parent_node;
308
309                         if (parent_node->full_path != NULL) {
310                                 int full_path_len = strlen(parent_node->full_path) + strlen("/") + strlen(mo_node->name) + 1;
311                                 int len = 0;
312                                 mo_node->full_path = (char *)calloc(full_path_len, sizeof(char));
313
314                                 if (mo_node->full_path != NULL) {
315                                         len = g_strlcat(mo_node->full_path, parent_node->full_path, full_path_len);
316                                         len = g_strlcat(mo_node->full_path, "/", full_path_len);
317                                         len = g_strlcat(mo_node->full_path, mo_node->name, full_path_len);
318
319                                         if (len >= full_path_len) {
320                                                 _DEBUG_ERROR("mo_node->full_path buffer overflow !!");
321                                                 /* todo : exception handling */
322                                         }
323
324                                         _DEBUG_VERBOSE("New Full_path : %s, %d", mo_node->full_path, mo_node->type);
325                                 }
326                         }
327                         break;
328                 }
329         } while (!(node_type == XML_ELEMENT_DECL && !strcmp(name, "Path")));
330
331         _INNER_FUNC_EXIT;
332 }
333
334 static void __set_Properties(xmlTextReaderPtr reader, sync_agent_dm_mo_framework_property_s * property)
335 {
336         _INNER_FUNC_ENTER;
337
338         retm_if(property == NULL, "sync_agent_dm_mo_framework_property_s is NULL !!");
339
340         int node_type;
341         const char *name = NULL;
342
343         do {
344                 xmlTextReaderRead(reader);
345
346                 node_type = xmlTextReaderNodeType(reader);
347                 name = (const char *)xmlTextReaderConstName(reader);
348
349                 dm_framework_property_e index = DM_FRAMEWORK_PROPERTY_COUNT;
350
351                 if (node_type == XML_ELEMENT_NODE) {
352                         if (!strcmp(name, "AccessType")) {
353                                 index = DM_FRAMEWORK_PROPERTY_ACCESSTYPE;
354                         } else if (!strcmp(name, "DefaultValue")) {
355                                 index = DM_FRAMEWORK_PROPERTY_DEFAULT_VALUE;
356                         } else if (!strcmp(name, "Description")) {
357                                 index = DM_FRAMEWORK_PROPERTY_DESCRIPTION;
358                         } else if (!strcmp(name, "DFFormat")) {
359                                 index = DM_FRAMEWORK_PROPERTY_DFF_FORMAT;
360                         } else if (!strcmp(name, "Occurrence")) {
361                                 index = DM_FRAMEWORK_PROPERTY_OCCURRENCE;
362                         } else if (!strcmp(name, "Scope")) {
363                                 index = DM_FRAMEWORK_PROPERTY_SCOPE;
364                         } else if (!strcmp(name, "DFTitle")) {
365                                 index = DM_FRAMEWORK_PROPERTY_DF_TITLE;
366                         } else if (!strcmp(name, "DFType")) {
367                                 index = DM_FRAMEWORK_PROPERTY_DF_TYPE;
368                         }
369
370                         if (index != DM_FRAMEWORK_PROPERTY_COUNT) {
371                                 parsing_properties[index] (&reader, property);
372                         }
373                 }
374         } while (!(node_type == XML_ELEMENT_DECL && !strcmp(name, "DFProperties")));
375
376         _INNER_FUNC_EXIT;
377 }