c1dd082cab45bb8c3c95a1b1ed6dd79b9610b6c5
[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                     bundle = m_xmlDoc.first_node();
99                     if (bundle)
100                     {
101                         for (bundle = bundle->first_node(BUNDLE_TAG); bundle; bundle =
102                                  bundle->next_sibling())
103                         {
104                             std::map< std::string, std::string > bundleMap;
105                             for (subItem = bundle->first_node(); subItem;
106                                  subItem = subItem->next_sibling())
107                             {
108                                 strKey = subItem->name();
109                                 strValue = subItem->value();
110
111                                 if (strlen(subItem->value()) > 0)
112                                 {
113                                     bundleMap.insert(
114                                         std::make_pair(trim_both(strKey), trim_both(strValue)));
115                                 }
116                             }
117                             configOutput->push_back(bundleMap);
118                         }
119                     }
120
121                 }
122                 catch (rapidxml::parse_error &e)
123                 {
124                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
125                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception : (%s)", e.what());
126                 }
127             }
128         }
129
130         void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
131         {
132             rapidxml::xml_node< char > *bundle;
133
134             string strBundleId, strPath, strVersion;
135
136             if (m_loaded)
137             {
138                 try
139                 {
140                     std::map< std::string, std::string > bundleConfigMap;
141
142                     // <bundle>
143                     bundle = m_xmlDoc.first_node();
144                     if (bundle)
145                     {
146                         for (bundle = bundle->first_node(BUNDLE_TAG); bundle; bundle =
147                                  bundle->next_sibling())
148                         {
149                             // <id>
150                             if (bundle->first_node(BUNDLE_ID))
151                             {
152                                 strBundleId = bundle->first_node(BUNDLE_ID)->value();
153                             }
154                             else{
155                                 strBundleId = "";
156                             }
157
158                             if (!strBundleId.compare(bundleId))
159                             {
160                                 bundleConfigMap.insert(std::make_pair(BUNDLE_ID, trim_both(strBundleId)));
161
162                                 // <path>
163                                 if (bundle->first_node(BUNDLE_PATH)){
164                                     strPath = bundle->first_node(BUNDLE_PATH)->value();
165                                 }
166                                 else{
167                                     strPath = "";
168                                 }
169                                 bundleConfigMap.insert(std::make_pair(BUNDLE_PATH, trim_both(strPath)));
170
171                                 // <version>
172                                 if (bundle->first_node(BUNDLE_VERSION)){
173                                     strVersion = bundle->first_node(BUNDLE_VERSION)->value();
174                                 }
175                                 else{
176                                     strVersion = "";
177                                 }
178                                 bundleConfigMap.insert(
179                                     std::make_pair(BUNDLE_VERSION, trim_both(strVersion)));
180
181                                 configOutput->push_back(bundleConfigMap);
182
183                                 break;
184                             }
185                         }
186                     }
187                 }
188                 catch (rapidxml::parse_error &e)
189                 {
190                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
191                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
192                 }
193             }
194         }
195
196         void Configuration::getResourceConfiguration(std::string bundleId, std::string resourceUri,
197                         resourceInfo *resourceInfoOut){
198             rapidxml::xml_node< char > *bundle;
199             rapidxml::xml_node< char > *resource;
200             rapidxml::xml_node< char > *item, *subItem, *subItem2;
201
202             string strBundleId;
203             string strKey, strValue;
204             OIC_LOG_V(INFO, CONTAINER_TAG, "Loading resource configuration for %s %s!",
205                 bundleId.c_str(), resourceUri.c_str());
206
207             if (m_loaded)
208             {
209                 try
210                 {
211                     // <bundle>
212                     bundle = m_xmlDoc.first_node();
213                     if (bundle)
214                     {
215                         for (bundle = bundle->first_node(BUNDLE_TAG); bundle;
216                             bundle = bundle->next_sibling())
217                         {
218                             // <id>
219                             strBundleId = bundle->first_node(BUNDLE_ID)->value();
220
221                             OIC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle id %s - %s !",
222                                     strBundleId.c_str(), bundleId.c_str());
223
224                             if (!strBundleId.compare(bundleId))
225                             {
226                                 OIC_LOG_V(INFO, CONTAINER_TAG, "Inspecting");
227                                 // <resourceInfo>
228                                 bundle = bundle->first_node(OUTPUT_RESOURCES_TAG);
229                                 if (bundle){
230                                     for (resource = bundle->first_node(OUTPUT_RESOURCE_INFO);
231                                          resource; resource = resource->next_sibling())
232                                     {
233
234                                         for (item = resource->first_node(); item; item =
235                                                  item->next_sibling())
236                                         {
237                                             strKey = item->name();
238                                             strValue = item->value();
239
240                                             if (!strKey.compare(OUTPUT_RESOURCE_NAME))
241                                             {
242                                                 
243                                                 resourceInfoOut->name = trim_both(strValue);
244                                             }
245
246                                             else if (!strKey.compare(OUTPUT_RESOURCE_URI))
247                                             {
248                                                 if (trim_both(strValue).compare(resourceUri) != 0)
249                                                 {
250                                                     break;
251                                                 }
252                                                 resourceInfoOut->uri = trim_both(strValue);
253                                             }
254
255                                             else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
256                                                 resourceInfoOut->address = trim_both(strValue);
257
258                                             else if (!strKey.compare(OUTPUT_RESOURCE_TYPE))
259                                                 resourceInfoOut->resourceType = trim_both(strValue);
260
261                                             else
262                                             {
263                                                 for (subItem = item->first_node(); subItem; subItem =
264                                                          subItem->next_sibling())
265                                                 {
266                                                     map< string, string > propertyMap;
267
268                                                     strKey = subItem->name();
269
270                                                     if (strKey.compare(INPUT_RESOURCE))
271                                                     {
272                                                         m_mapisHasInput[strBundleId] = true;
273                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
274                                                                 "Bundle has input (%s)",
275                                                                 strBundleId.c_str());
276                                                     }
277
278                                                     for (subItem2 = subItem->first_node(); subItem2;
279                                                          subItem2 = subItem2->next_sibling())
280                                                     {
281                                                         string newStrKey = subItem2->name();
282                                                         string newStrValue = subItem2->value();
283                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
284                                                                 "key: %s, value %s",
285                                                                 newStrKey.c_str(), newStrValue.c_str());
286
287                                                         propertyMap[trim_both(newStrKey)] =
288                                                                 trim_both(newStrValue);
289                                                     }
290
291                                                     resourceInfoOut->resourceProperty[trim_both(strKey)].push_back(
292                                                         propertyMap);
293                                                 }
294                                             }
295                                         }
296
297                                     }
298                                 }
299                             }
300                         }
301                     }
302                 }
303                 catch (rapidxml::parse_error &e)
304                 {
305                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
306                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
307                 }
308             }
309             else{
310                 OIC_LOG(INFO, CONTAINER_TAG, "config is not loaded yet !!");
311             }
312         }
313
314         void Configuration::getResourceConfiguration(std::string bundleId,
315                 std::vector< resourceInfo > *configOutput)
316         {
317             rapidxml::xml_node< char > *bundle;
318             rapidxml::xml_node< char > *resource;
319             rapidxml::xml_node< char > *item, *subItem, *subItem2;
320
321             string strBundleId;
322             string strKey, strValue;
323             OIC_LOG(INFO, CONTAINER_TAG, "Loading resource configuration!");
324
325             if (m_loaded)
326             {
327                 try
328                 {
329                     // <bundle>
330                     bundle = m_xmlDoc.first_node();
331                     if (bundle)
332                     {
333                         for (bundle = bundle->first_node(BUNDLE_TAG); bundle; bundle =
334                                  bundle->next_sibling())
335                         {
336                             // <id>
337                             strBundleId = bundle->first_node(BUNDLE_ID)->value();
338
339                             OIC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle ids %s - %s !",
340                                     strBundleId.c_str(), bundleId.c_str());
341
342                             if (!strBundleId.compare(bundleId))
343                             {
344                                 OIC_LOG_V(INFO, CONTAINER_TAG, "Inspecting");
345                                 // <resourceInfo>
346                                 bundle = bundle->first_node(OUTPUT_RESOURCES_TAG);
347                                 if (bundle)
348                                 {
349                                     for (resource = bundle->
350                                             first_node(OUTPUT_RESOURCE_INFO);
351                                          resource; resource = resource->next_sibling())
352                                     {
353                                         resourceInfo tempResourceInfo;
354
355                                         for (item = resource->first_node(); item; item =
356                                                  item->next_sibling())
357                                         {
358                                             strKey = item->name();
359                                             strValue = item->value();
360
361                                             if (!strKey.compare(OUTPUT_RESOURCE_NAME))
362                                                 tempResourceInfo.name = trim_both(strValue);
363
364                                             else if (!strKey.compare(OUTPUT_RESOURCE_URI))
365                                                 tempResourceInfo.uri = trim_both(strValue);
366
367                                             else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
368                                                 tempResourceInfo.address = trim_both(strValue);
369
370                                             else if (!strKey.compare(OUTPUT_RESOURCE_TYPE))
371                                                 tempResourceInfo.resourceType = trim_both(strValue);
372
373                                             else
374                                             {
375                                                 for (subItem = item->first_node(); subItem; subItem =
376                                                          subItem->next_sibling())
377                                                 {
378                                                     map< string, string > propertyMap;
379
380                                                     strKey = subItem->name();
381
382                                                     if (strKey.compare(INPUT_RESOURCE))
383                                                     {
384                                                         m_mapisHasInput[strBundleId] = true;
385                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
386                                                                 "Bundle has input (%s)",
387                                                                 strBundleId.c_str());
388                                                     }
389
390                                                     for (subItem2 = subItem->first_node(); subItem2;
391                                                          subItem2 = subItem2->next_sibling())
392                                                     {
393                                                         string newStrKey = subItem2->name();
394                                                         string newStrValue = subItem2->value();
395                                                         OIC_LOG_V(INFO, CONTAINER_TAG,
396                                                                 "key: %s, value %s",
397                                                                 newStrKey.c_str(),
398                                                                 newStrValue.c_str());
399
400                                                         propertyMap[trim_both(newStrKey)] =
401                                                                 trim_both(newStrValue);
402                                                     }
403
404                                                     tempResourceInfo.resourceProperty[trim_both(strKey)].
405                                                     push_back(propertyMap);
406                                                 }
407                                             }
408                                         }
409                                         configOutput->push_back(tempResourceInfo);
410                                     }
411                                 }
412                             }
413                         }
414                     }
415                 }
416                 catch (rapidxml::parse_error &e)
417                 {
418                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
419                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
420                 }
421             }
422             else{
423                 OIC_LOG(INFO, CONTAINER_TAG, "config is not loaded yet !!");
424             }
425         }
426
427         void Configuration::getConfigDocument(std::string pathConfigFile)
428         {
429             std::basic_ifstream< char > xmlFile(pathConfigFile.c_str());
430
431             if (!xmlFile.fail())
432             {
433                 xmlFile.seekg(0, std::ios::end);
434                 unsigned int size = (unsigned int) xmlFile.tellg();
435                 xmlFile.seekg(0);
436
437                 std::vector< char > xmlData(size + 1);
438                 xmlData[size] = 0;
439
440                 xmlFile.read(&xmlData.front(), (std::streamsize) size);
441                 xmlFile.close();
442                 m_strConfigData = std::string(xmlData.data());
443
444                 try
445                 {
446                     m_xmlDoc.parse< 0 >((char *) m_strConfigData.c_str());
447                     m_loaded = true;
448                 }
449                 catch (rapidxml::parse_error &e)
450                 {
451                     OIC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
452                     OIC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
453                 }
454             }
455             else
456             {
457                 OIC_LOG(ERROR, CONTAINER_TAG, "Configuration File load failed !!");
458             }
459         }
460     }
461 }