Various fixes for the Android resource container extension
[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
29 namespace OIC
30 {
31     namespace Service
32     {
33         static inline std::string trim_both(const std::string &str)
34         {
35             size_t npos = str.find_first_not_of(" \t\v\n\r");
36
37             if (npos == std::string::npos)
38             {
39                 return "";
40             }
41
42             std::string tempString = str.substr(npos, str.length());
43             npos = tempString.find_last_not_of(" \t\v\n\r");
44
45             return npos == std::string::npos ? tempString : tempString.substr(0, npos + 1);
46         }
47
48         Configuration::Configuration()
49         {
50             m_loaded = false;
51         }
52
53         Configuration::Configuration(string configFile)
54         {
55             m_loaded = false;
56
57             m_pathConfigFile.append(configFile);
58
59             getConfigDocument(m_pathConfigFile);
60         }
61
62         Configuration::~Configuration()
63         {
64         }
65
66         bool Configuration::isLoaded() const
67         {
68             return m_loaded;
69         }
70
71         bool Configuration::isHasInput(std::string &bundleId) const
72         {
73
74             try
75             {
76                 OC_LOG_V(INFO, CONTAINER_TAG, "isHasInput: (%d) %s",m_mapisHasInput.at(bundleId), bundleId.c_str() );
77                 return m_mapisHasInput.at(bundleId);
78             }
79             catch (std::out_of_range &e)
80             {
81                 OC_LOG_V(INFO, CONTAINER_TAG, "isHasInput out of range %s.", bundleId.c_str());
82                 return false;
83             }
84         }
85
86         void Configuration::getConfiguredBundles(configInfo *configOutput)
87         {
88             rapidxml::xml_node< char > *bundle;
89             rapidxml::xml_node< char > *subItem;
90
91             string strKey, strValue;
92
93             if (m_loaded)
94             {
95                 try
96                 {
97                     for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
98                              bundle->next_sibling())
99                     {
100                         std::map< std::string, std::string > bundleMap;
101                         for (subItem = bundle->first_node(); subItem;
102                              subItem = subItem->next_sibling())
103                         {
104                             strKey = subItem->name();
105                             strValue = subItem->value();
106
107                             if (strlen(subItem->value()) > 0)
108                             {
109                                 bundleMap.insert(
110                                     std::make_pair(trim_both(strKey), trim_both(strValue)));
111                             }
112                         }
113                         configOutput->push_back(bundleMap);
114                     }
115
116                 }
117                 catch (rapidxml::parse_error &e)
118                 {
119                     OC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
120                     OC_LOG_V(ERROR, CONTAINER_TAG, "Exception : (%s)", e.what());
121                 }
122             }
123         }
124
125         void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
126         {
127             rapidxml::xml_node< char > *bundle;
128
129             string strBundleId, strPath, strVersion;
130
131             if (m_loaded)
132             {
133                 try
134                 {
135                     std::map< std::string, std::string > bundleConfigMap;
136
137                     // <bundle>
138                     for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
139                              bundle->next_sibling())
140                     {
141                         // <id>
142                         strBundleId = bundle->first_node(BUNDLE_ID)->value();
143
144                         if (!strBundleId.compare(bundleId))
145                         {
146                             bundleConfigMap.insert(std::make_pair(BUNDLE_ID, trim_both(strBundleId)));
147
148                             // <path>
149                             strPath = bundle->first_node(BUNDLE_PATH)->value();
150                             bundleConfigMap.insert(std::make_pair(BUNDLE_PATH, trim_both(strPath)));
151
152                             // <version>
153                             strVersion = bundle->first_node(BUNDLE_VERSION)->value();
154                             bundleConfigMap.insert(
155                                 std::make_pair(BUNDLE_VERSION, trim_both(strVersion)));
156
157                             configOutput->push_back(bundleConfigMap);
158
159                             break;
160                         }
161                     }
162                 }
163                 catch (rapidxml::parse_error &e)
164                 {
165                     OC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
166                     OC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
167                 }
168             }
169         }
170
171         void Configuration::getResourceConfiguration(std::string bundleId,
172                 std::vector< resourceInfo > *configOutput)
173         {
174             rapidxml::xml_node< char > *bundle;
175             rapidxml::xml_node< char > *resource;
176             rapidxml::xml_node< char > *item, *subItem, *subItem2;
177
178             string strBundleId;
179             string strKey, strValue;
180             OC_LOG(INFO, CONTAINER_TAG, "Loading resource configuration!");
181
182             if (m_loaded)
183             {
184                 try
185                 {
186                     // <bundle>
187                     for (bundle = m_xmlDoc.first_node()->first_node(BUNDLE_TAG); bundle; bundle =
188                              bundle->next_sibling())
189                     {
190                         // <id>
191                         strBundleId = bundle->first_node(BUNDLE_ID)->value();
192
193                         OC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle ids %s - %s !", strBundleId.c_str(), bundleId.c_str());
194
195                         if (!strBundleId.compare(bundleId))
196                         {
197                             OC_LOG_V(INFO, CONTAINER_TAG, "Inspecting");
198                             // <resourceInfo>
199                             for (resource = bundle->first_node(OUTPUT_RESOURCES_TAG)->first_node(OUTPUT_RESOURCE_INFO);
200                                  resource; resource = resource->next_sibling())
201                             {
202                                 resourceInfo tempResourceInfo;
203
204                                 for (item = resource->first_node(); item; item =
205                                          item->next_sibling())
206                                 {
207                                     strKey = item->name();
208                                     strValue = item->value();
209
210                                     if (!strKey.compare(OUTPUT_RESOURCE_NAME))
211                                         tempResourceInfo.name = trim_both(strValue);
212
213                                     else if (!strKey.compare(OUTPUT_RESOURCE_URI))
214                                         tempResourceInfo.uri = trim_both(strValue);
215
216                                     else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
217                                         tempResourceInfo.address = trim_both(strValue);
218
219                                     else if (!strKey.compare(OUTPUT_RESOURCE_TYPE))
220                                         tempResourceInfo.resourceType = trim_both(strValue);
221
222                                     else
223                                     {
224                                         for (subItem = item->first_node(); subItem; subItem =
225                                                  subItem->next_sibling())
226                                         {
227                                             map< string, string > propertyMap;
228
229                                             strKey = subItem->name();
230
231                                             if (strKey.compare(INPUT_RESOURCE))
232                                             {
233                                                 m_mapisHasInput[strBundleId] = true;
234                                                 OC_LOG_V(INFO, CONTAINER_TAG, "Bundle has input (%s)", strBundleId.c_str());
235                                             }
236
237                                             for (subItem2 = subItem->first_node(); subItem2;
238                                                  subItem2 = subItem2->next_sibling())
239                                             {
240                                                 string newStrKey = subItem2->name();
241                                                 string newStrValue = subItem2->value();
242
243                                                 propertyMap[trim_both(newStrKey)] = trim_both(
244                                                                                         newStrValue);
245                                             }
246
247                                             tempResourceInfo.resourceProperty[trim_both(strKey)].push_back(
248                                                 propertyMap);
249                                         }
250                                     }
251                                 }
252                                 configOutput->push_back(tempResourceInfo);
253                             }
254                         }
255                     }
256                 }
257                 catch (rapidxml::parse_error &e)
258                 {
259                     OC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
260                     OC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
261                 }
262             }
263             else{
264                 OC_LOG(INFO, CONTAINER_TAG, "config is not loaded yet !!");
265             }
266         }
267
268         void Configuration::getConfigDocument(std::string pathConfigFile)
269         {
270             std::basic_ifstream< char > xmlFile(pathConfigFile.c_str());
271
272             if (!xmlFile.fail())
273             {
274                 xmlFile.seekg(0, std::ios::end);
275                 unsigned int size = (unsigned int) xmlFile.tellg();
276                 xmlFile.seekg(0);
277
278                 std::vector< char > xmlData(size + 1);
279                 xmlData[size] = 0;
280
281                 xmlFile.read(&xmlData.front(), (std::streamsize) size);
282                 xmlFile.close();
283                 m_strConfigData = std::string(xmlData.data());
284
285                 try
286                 {
287                     m_xmlDoc.parse< 0 >((char *) m_strConfigData.c_str());
288                     m_loaded = true;
289                 }
290                 catch (rapidxml::parse_error &e)
291                 {
292                     OC_LOG(ERROR, CONTAINER_TAG, "xml parsing failed !!");
293                     OC_LOG_V(ERROR, CONTAINER_TAG, "Exception (%s)", e.what());
294                 }
295             }
296             else
297             {
298                 OC_LOG(ERROR, CONTAINER_TAG, "Configuration File load failed !!");
299             }
300         }
301     }
302 }