Merge branch 'easysetup'
[platform/upstream/iotivity.git] / service / resource-container / src / Configuration.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "Configuration.h"
22
23 #include <stdexcept>
24 #include <utility>
25 #include "InternalTypes.h"
26
27 #define CONTAINER_TAG "RESOURCE_CONTAINER"
28 #define DISCOVER_TAG "DISCOVER_RESOURCE_UNIT"
29
30 namespace OIC
31 {
32     namespace Service
33     {
34         static inline std::string trim_both(const std::string &str)
35         {
36             size_t npos = str.find_first_not_of(" \t\v\n\r");
37
38             if (npos == std::string::npos)
39             {
40                 return "";
41             }
42
43             std::string tempString = str.substr(npos, str.length());
44             npos = tempString.find_last_not_of(" \t\v\n\r");
45
46             return npos == std::string::npos ? tempString : tempString.substr(0, npos + 1);
47         }
48
49         Configuration::Configuration()
50         {
51             m_loaded = false;
52         }
53
54         Configuration::Configuration(string configFile)
55         {
56             m_loaded = false;
57
58             m_pathConfigFile.append(configFile);
59
60             getConfigDocument(m_pathConfigFile);
61         }
62
63         Configuration::~Configuration()
64         {
65         }
66
67         bool Configuration::isLoaded() const
68         {
69             return m_loaded;
70         }
71
72         bool Configuration::isHasInput(std::string &bundleId) const
73         {
74
75             try
76             {
77                 OIC_LOG_V(INFO, CONTAINER_TAG, "isHasInput: (%d) %s",m_mapisHasInput.at(bundleId), bundleId.c_str() );
78                 return m_mapisHasInput.at(bundleId);
79             }
80             catch (std::out_of_range &e)
81             {
82                 OIC_LOG_V(INFO, CONTAINER_TAG, "isHasInput out of range %s.", bundleId.c_str());
83                 return false;
84             }
85         }
86
87         void Configuration::getConfiguredBundles(configInfo *configOutput)
88         {
89             rapidxml::xml_node< char > *bundle;
90             rapidxml::xml_node< char > *subItem;
91
92             string strKey, strValue;
93
94             if (m_loaded)
95             {
96                 try
97                 {
98                     if (m_xmlDoc.first_node())
99                     {
100                         for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
101                                  bundle->next_sibling())
102                         {
103                             std::map< std::string, std::string > bundleMap;
104                             for (subItem = bundle->first_node(); subItem;
105                                  subItem = subItem->next_sibling())
106                             {
107                                 strKey = subItem->name();
108                                 strValue = subItem->value();
109
110                                 if (strlen(subItem->value()) > 0)
111                                 {
112                                     bundleMap.insert(
113                                         std::make_pair(trim_both(strKey), trim_both(strValue)));
114                                 }
115                             }
116                             configOutput->push_back(bundleMap);
117                         }
118                     }
119
120                 }
121                 catch (rapidxml::parse_error &e)
122                 {
123                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
124                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception : (%s)", e.what());
125                 }
126             }
127         }
128
129         void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
130         {
131             rapidxml::xml_node< char > *bundle;
132
133             string strBundleId, strPath, strVersion;
134
135             if (m_loaded)
136             {
137                 try
138                 {
139                     std::map< std::string, std::string > bundleConfigMap;
140
141                     // <bundle>
142                     if (m_xmlDoc.first_node())
143                     {
144                         for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
145                                  bundle->next_sibling())
146                         {
147                             // <id>
148                             if (bundle->first_node(BUNDLE_ID))
149                             {
150                                 strBundleId = bundle->first_node(BUNDLE_ID)->value();
151                             }
152                             else{
153                                 strBundleId = "";
154                             }
155
156                             if (!strBundleId.compare(bundleId))
157                             {
158                                 bundleConfigMap.insert(std::make_pair(BUNDLE_ID, trim_both(strBundleId)));
159
160                                 // <path>
161                                 if (bundle->first_node(BUNDLE_PATH)){
162                                     strPath = bundle->first_node(BUNDLE_PATH)->value();
163                                 }
164                                 else{
165                                     strPath = "";
166                                 }
167                                 bundleConfigMap.insert(std::make_pair(BUNDLE_PATH, trim_both(strPath)));
168
169                                 // <version>
170                                 if (bundle->first_node(BUNDLE_VERSION)){
171                                     strVersion = bundle->first_node(BUNDLE_VERSION)->value();
172                                 }
173                                 else{
174                                     strVersion = "";
175                                 }
176                                 bundleConfigMap.insert(
177                                     std::make_pair(BUNDLE_VERSION, trim_both(strVersion)));
178
179                                 configOutput->push_back(bundleConfigMap);
180
181                                 break;
182                             }
183                         }
184                     }
185                 }
186                 catch (rapidxml::parse_error &e)
187                 {
188                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
189                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
190                 }
191             }
192         }
193
194         void Configuration::getResourceConfiguration(std::string bundleId, std::string resourceName,
195                         resourceInfo *resourceInfoOut){
196             rapidxml::xml_node< char > *bundle;
197             rapidxml::xml_node< char > *resource;
198             rapidxml::xml_node< char > *item, *subItem, *subItem2;
199
200             string strBundleId;
201             string strKey, strValue;
202             OIC_LOG_V(INFO, CONTAINER_TAG, "Loading resource configuration for %s %s!",
203                     bundleId.c_str(), resourceName.c_str());
204
205             if (m_loaded)
206             {
207                 try
208                 {
209                     // <bundle>
210                     if (m_xmlDoc.first_node())
211                     {
212                         for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
213                                  bundle->next_sibling())
214                         {
215                             // <id>
216                             strBundleId = bundle->first_node(BUNDLE_ID)->value();
217
218                             OIC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle id %s - %s !",
219                                     strBundleId.c_str(), bundleId.c_str());
220
221                             if (!strBundleId.compare(bundleId))
222                             {
223                                 OIC_LOG_V(INFO, CONTAINER_TAG, "Inspecting");
224                                 // <resourceInfo>
225                                 if (bundle->first_node(OUTPUT_RESOURCES_TAG)){
226                                     for (resource = bundle->first_node(OUTPUT_RESOURCES_TAG)->
227                                             first_node(OUTPUT_RESOURCE_INFO);
228                                          resource; resource = resource->next_sibling())
229                                     {
230
231                                         for (item = resource->first_node(); item; item =
232                                                  item->next_sibling())
233                                         {
234                                             strKey = item->name();
235                                             strValue = item->value();
236
237                                             if (!strKey.compare(OUTPUT_RESOURCE_NAME))
238                                                 resourceInfoOut->name = trim_both(strValue);
239
240                                             else if (!strKey.compare(OUTPUT_RESOURCE_URI))
241                                                 resourceInfoOut->uri = trim_both(strValue);
242
243                                             else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
244                                                 resourceInfoOut->address = trim_both(strValue);
245
246                                             else if (!strKey.compare(OUTPUT_RESOURCE_TYPE))
247                                                 resourceInfoOut->resourceType = trim_both(strValue);
248
249                                             else
250                                             {
251                                                 for (subItem = item->first_node(); subItem; subItem =
252                                                          subItem->next_sibling())
253                                                 {
254                                                     map< string, string > propertyMap;
255
256                                                     strKey = subItem->name();
257
258                                                     if (strKey.compare(INPUT_RESOURCE))
259                                                     {
260                                                         m_mapisHasInput[strBundleId] = true;
261                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
262                                                                 "Bundle has input (%s)",
263                                                                 strBundleId.c_str());
264                                                     }
265
266                                                     for (subItem2 = subItem->first_node(); subItem2;
267                                                          subItem2 = subItem2->next_sibling())
268                                                     {
269                                                         string newStrKey = subItem2->name();
270                                                         string newStrValue = subItem2->value();
271                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
272                                                                 "key: %s, value %s",
273                                                                 newStrKey.c_str(), newStrValue.c_str());
274
275                                                         propertyMap[trim_both(newStrKey)] =
276                                                                 trim_both(newStrValue);
277                                                     }
278
279                                                     resourceInfoOut->resourceProperty[trim_both(strKey)].push_back(
280                                                         propertyMap);
281                                                 }
282                                             }
283                                         }
284
285                                     }
286                                 }
287                             }
288                         }
289                     }
290                 }
291                 catch (rapidxml::parse_error &e)
292                 {
293                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
294                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
295                 }
296             }
297             else{
298                 OIC_LOG(INFO, CONTAINER_TAG, "config is not loaded yet !!");
299             }
300         }
301
302         void Configuration::getResourceConfiguration(std::string bundleId,
303                 std::vector< resourceInfo > *configOutput)
304         {
305             rapidxml::xml_node< char > *bundle;
306             rapidxml::xml_node< char > *resource;
307             rapidxml::xml_node< char > *item, *subItem, *subItem2;
308
309             string strBundleId;
310             string strKey, strValue;
311             OIC_LOG(INFO, CONTAINER_TAG, "Loading resource configuration!");
312
313             if (m_loaded)
314             {
315                 try
316                 {
317                     // <bundle>
318                     if (m_xmlDoc.first_node())
319                     {
320                         for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
321                                  bundle->next_sibling())
322                         {
323                             // <id>
324                             strBundleId = bundle->first_node(BUNDLE_ID)->value();
325
326                             OIC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle ids %s - %s !",
327                                     strBundleId.c_str(), bundleId.c_str());
328
329                             if (!strBundleId.compare(bundleId))
330                             {
331                                 OIC_LOG_V(INFO, CONTAINER_TAG, "Inspecting");
332                                 // <resourceInfo>
333                                 if (bundle->first_node(OUTPUT_RESOURCES_TAG))
334                                 {
335                                     for (resource = bundle->first_node(OUTPUT_RESOURCES_TAG)->
336                                             first_node(OUTPUT_RESOURCE_INFO);
337                                          resource; resource = resource->next_sibling())
338                                     {
339                                         resourceInfo tempResourceInfo;
340
341                                         for (item = resource->first_node(); item; item =
342                                                  item->next_sibling())
343                                         {
344                                             strKey = item->name();
345                                             strValue = item->value();
346
347                                             if (!strKey.compare(OUTPUT_RESOURCE_NAME))
348                                                 tempResourceInfo.name = trim_both(strValue);
349
350                                             else if (!strKey.compare(OUTPUT_RESOURCE_URI))
351                                                 tempResourceInfo.uri = trim_both(strValue);
352
353                                             else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
354                                                 tempResourceInfo.address = trim_both(strValue);
355
356                                             else if (!strKey.compare(OUTPUT_RESOURCE_TYPE))
357                                                 tempResourceInfo.resourceType = trim_both(strValue);
358
359                                             else
360                                             {
361                                                 for (subItem = item->first_node(); subItem; subItem =
362                                                          subItem->next_sibling())
363                                                 {
364                                                     map< string, string > propertyMap;
365
366                                                     strKey = subItem->name();
367
368                                                     if (strKey.compare(INPUT_RESOURCE))
369                                                     {
370                                                         m_mapisHasInput[strBundleId] = true;
371                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
372                                                                 "Bundle has input (%s)",
373                                                                 strBundleId.c_str());
374                                                     }
375
376                                                     for (subItem2 = subItem->first_node(); subItem2;
377                                                          subItem2 = subItem2->next_sibling())
378                                                     {
379                                                         string newStrKey = subItem2->name();
380                                                         string newStrValue = subItem2->value();
381                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
382                                                                 "key: %s, value %s",
383                                                                 newStrKey.c_str(),
384                                                                 newStrValue.c_str());
385
386                                                         propertyMap[trim_both(newStrKey)] =
387                                                                 trim_both(newStrValue);
388                                                     }
389
390                                                     tempResourceInfo.resourceProperty[trim_both(strKey)].
391                                                     push_back(propertyMap);
392                                                 }
393                                             }
394                                         }
395                                         configOutput->push_back(tempResourceInfo);
396                                     }
397                                 }
398                             }
399                         }
400                     }
401                 }
402                 catch (rapidxml::parse_error &e)
403                 {
404                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
405                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
406                 }
407             }
408             else{
409                 OIC_LOG(INFO, CONTAINER_TAG, "config is not loaded yet !!");
410             }
411         }
412
413         void Configuration::getConfigDocument(std::string pathConfigFile)
414         {
415             std::basic_ifstream< char > xmlFile(pathConfigFile.c_str());
416
417             if (!xmlFile.fail())
418             {
419                 xmlFile.seekg(0, std::ios::end);
420                 unsigned int size = (unsigned int) xmlFile.tellg();
421                 xmlFile.seekg(0);
422
423                 std::vector< char > xmlData(size + 1);
424                 xmlData[size] = 0;
425
426                 xmlFile.read(&xmlData.front(), (std::streamsize) size);
427                 xmlFile.close();
428                 m_strConfigData = std::string(xmlData.data());
429
430                 try
431                 {
432                     m_xmlDoc.parse< 0 >((char *) m_strConfigData.c_str());
433                     m_loaded = true;
434                 }
435                 catch (rapidxml::parse_error &e)
436                 {
437                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
438                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
439                 }
440             }
441             else
442             {
443                 OIC_LOG(ERROR, CONTAINER_TAG, "Configuration File load failed !!");
444             }
445         }
446     }
447 }