Imported Upstream version 1.0.1
[platform/upstream/iotivity.git] / service / simulator / src / common / simulator_resource_model.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 "simulator_resource_model.h"
22 #include "simulator_exceptions.h"
23 #include "logger.h"
24 #include "OCPlatform.h"
25 #include <sstream>
26 #include <boost/lexical_cast.hpp>
27
28 template <typename T>
29 struct TypeConverter
30 {
31     constexpr static SimulatorResourceModel::Attribute::ValueType type =
32             SimulatorResourceModel::Attribute::ValueType::UNKNOWN;
33 };
34
35 template <>
36 struct TypeConverter<int>
37 {
38     constexpr static SimulatorResourceModel::Attribute::ValueType type =
39             SimulatorResourceModel::Attribute::ValueType::INTEGER;
40 };
41
42 template <>
43 struct TypeConverter<double>
44 {
45     constexpr static SimulatorResourceModel::Attribute::ValueType type =
46             SimulatorResourceModel::Attribute::ValueType::DOUBLE;
47 };
48
49 template <>
50 struct TypeConverter<bool>
51 {
52     constexpr static SimulatorResourceModel::Attribute::ValueType type =
53             SimulatorResourceModel::Attribute::ValueType::BOOLEAN;
54 };
55
56 template <>
57 struct TypeConverter<std::string>
58 {
59     constexpr static SimulatorResourceModel::Attribute::ValueType type =
60             SimulatorResourceModel::Attribute::ValueType::STRING;
61 };
62
63 class attribute_type_visitor : public boost::static_visitor<
64         SimulatorResourceModel::Attribute::ValueType>
65 {
66     public:
67         template <typename T>
68         result_type operator ()(const T &)
69         {
70             return TypeConverter<T>::type;
71         }
72 };
73
74 class to_string_visitor : public boost::static_visitor<std::string>
75 {
76     public:
77         template <typename T>
78         result_type operator ()(const T &value)
79         {
80             try
81             {
82                 return boost::lexical_cast<std::string>(value);
83             }
84             catch (const boost::bad_lexical_cast &e)
85             {
86                 return "";
87             }
88         }
89 };
90
91 class add_to_representation : public boost::static_visitor<>
92 {
93     public:
94         add_to_representation(OC::OCRepresentation &rep, const std::string &key)
95             : m_rep(rep), m_key(key) {}
96
97         template <typename T>
98         void operator ()(const T &value)
99         {
100             m_rep.setValue(m_key, value);
101         }
102
103         OC::OCRepresentation &&getRep()
104         {
105             return std::move(m_rep);
106         }
107
108     private:
109         OC::OCRepresentation m_rep;
110         std::string m_key;
111 };
112
113 class range_validation : public boost::static_visitor<bool>
114 {
115     public:
116         range_validation (SimulatorResourceModel::Attribute &attrItem)
117             : m_attrItem(attrItem) {}
118
119         bool operator ()(int &value)
120         {
121             int min, max;
122             m_attrItem.getRange(min, max);
123             if (value >= min && value <= max)
124                 return true;
125             return false;
126         }
127
128         bool operator ()(double &value)
129         {
130             std::vector<SimulatorResourceModel::Attribute::ValueVariant> values
131                 = m_attrItem.getAllowedValues();
132             if(0 == values.size())
133                 return true;
134             for (SimulatorResourceModel::Attribute::ValueVariant & val : values)
135             {
136                 SimulatorResourceModel::Attribute::ValueVariant vVal = value;
137                 if (val == vVal)
138                     return true;
139             }
140             return false;
141         }
142
143         bool operator ()(bool &value)
144         {
145             return true;
146         }
147
148         bool operator ()(std::string &value)
149         {
150             std::vector<SimulatorResourceModel::Attribute::ValueVariant> values
151                 = m_attrItem.getAllowedValues();
152             if(0 == values.size())
153                 return true;
154             for (SimulatorResourceModel::Attribute::ValueVariant & vVal : values)
155             {
156                 std::string val = boost::get<std::string>(vVal);
157                 if (val == value)
158                     return true;
159             }
160
161             return false;
162         }
163
164     private:
165         SimulatorResourceModel::Attribute &m_attrItem;
166 };
167
168 SimulatorResourceModel::Attribute::ValueVariant
169 &SimulatorResourceModel::Attribute::AllowedValues::at(unsigned int index)
170 {
171     return m_values.at(index);
172 }
173
174 int SimulatorResourceModel::Attribute::AllowedValues::size() const
175 {
176     return m_values.size();
177 }
178
179 std::vector<std::string> SimulatorResourceModel::Attribute::AllowedValues::toString() const
180 {
181     std::vector<std::string> values;
182
183     for (auto & value : m_values)
184     {
185         to_string_visitor visitor;
186         values.push_back(boost::apply_visitor(visitor, value));
187     }
188     return values;
189 }
190
191 std::vector<SimulatorResourceModel::Attribute::ValueVariant>
192 SimulatorResourceModel::Attribute::AllowedValues::getValues() const
193 {
194     return m_values;
195 }
196
197 std::string SimulatorResourceModel::Attribute::getName(void) const
198 {
199     return m_name;
200 }
201
202 void SimulatorResourceModel::Attribute::setName(const std::string &name)
203 {
204     m_name = name;
205 }
206
207 void SimulatorResourceModel::Attribute::getRange(int &min, int &max) const
208 {
209     min = m_min;
210     max = m_max;
211 }
212
213 void SimulatorResourceModel::Attribute::setRange(const int &min, const int &max)
214 {
215     m_min = min;
216     m_max = max;
217 }
218
219 int SimulatorResourceModel::Attribute::getAllowedValuesSize() const
220 {
221     return m_allowedValues.size();
222 }
223
224 void SimulatorResourceModel::Attribute::setFromAllowedValue(unsigned int index)
225 {
226     m_value = m_allowedValues.at(index);
227 }
228
229 SimulatorResourceModel::Attribute::ValueType SimulatorResourceModel::Attribute::getValueType() const
230 {
231     attribute_type_visitor typeVisitor;
232     return boost::apply_visitor(typeVisitor, m_value);
233 }
234
235 std::string SimulatorResourceModel::Attribute::valueToString() const
236 {
237     to_string_visitor visitor;
238     return boost::apply_visitor(visitor, m_value);
239 }
240
241 std::vector<std::string> SimulatorResourceModel::Attribute::allowedValuesToString() const
242 {
243     return m_allowedValues.toString();
244 }
245
246 void SimulatorResourceModel::Attribute::addValuetoRepresentation(OC::OCRepresentation &rep,
247         const std::string &key) const
248 {
249     add_to_representation visitor(rep, key);
250     boost::apply_visitor(visitor, m_value);
251     rep = visitor.getRep();
252 }
253
254 bool SimulatorResourceModel::Attribute::compare(SimulatorResourceModel::Attribute &attribute)
255 {
256     // Check the value types
257     if (m_value.which() != attribute.getValue().which())
258     {
259         return false;
260     }
261
262     // Check the value in allowed range
263     range_validation visitor(*this);
264     return boost::apply_visitor(visitor, attribute.getValue());
265 }
266
267 std::vector<SimulatorResourceModel::Attribute::ValueVariant>
268 SimulatorResourceModel::Attribute::getAllowedValues() const
269 {
270     return m_allowedValues.getValues();
271 }
272
273 bool SimulatorResourceModel::getAttribute(const std::string &attrName, Attribute &value)
274 {
275     if (m_attributes.end() != m_attributes.find(attrName))
276     {
277         value = m_attributes[attrName];
278         return true;
279     }
280
281     return false;
282 }
283
284 std::map<std::string, SimulatorResourceModel::Attribute> SimulatorResourceModel::getAttributes()
285 const
286 {
287     return m_attributes;
288 }
289
290 void SimulatorResourceModel::addAttribute(const SimulatorResourceModel::Attribute &attribute, bool overwrite)
291 {
292     if (!attribute.getName().empty() &&
293         (m_attributes.end() == m_attributes.find(attribute.getName()) || overwrite))
294     {
295         m_attributes[attribute.getName()] = attribute;
296     }
297 }
298
299 void SimulatorResourceModel::setRange(const std::string &attrName, const int min, const int max)
300 {
301     if (m_attributes.end() != m_attributes.find(attrName))
302         m_attributes[attrName].setRange(min, max);
303 }
304
305 void SimulatorResourceModel::setUpdateInterval(const std::string &attrName, int interval)
306 {
307     if (m_attributes.end() != m_attributes.find(attrName))
308         m_attributes[attrName].setUpdateFrequencyTime(interval);
309 }
310
311 void SimulatorResourceModel::updateAttributeFromAllowedValues(const std::string &attrName,
312         unsigned int index)
313 {
314     if (m_attributes.end() != m_attributes.find(attrName))
315         m_attributes[attrName].setFromAllowedValue(index);
316 }
317
318 void SimulatorResourceModel::removeAttribute(const std::string &attrName)
319 {
320    if (attrName.empty() || m_attributes.end() == m_attributes.find(attrName))
321    {
322        OC_LOG(ERROR, TAG, "Attribute name is empty or not found in model!");
323        throw InvalidArgsException(SIMULATOR_INVALID_PARAM, "Attribute not found in model!");
324    }
325
326     m_attributes.erase(attrName);
327     return;
328 }
329
330 OC::OCRepresentation SimulatorResourceModel::getOCRepresentation() const
331 {
332     OC::OCRepresentation rep;
333     for (auto & attribute : m_attributes)
334     {
335         (attribute.second).addValuetoRepresentation(rep, attribute.first);
336     }
337
338     return rep;
339 }
340
341 bool SimulatorResourceModel::update(OC::OCRepresentation &ocRep)
342 {
343     if (0 == ocRep.size())
344         return true;
345
346     // Convert OCRepresentation to SimulatorResourceModel
347     SimulatorResourceModelSP resModel = create(ocRep);
348
349     return update(resModel);
350 }
351
352 bool SimulatorResourceModel::update(SimulatorResourceModelSP &repModel)
353 {
354     std::map<std::string, SimulatorResourceModel::Attribute> attributes = repModel->getAttributes();
355     for (auto & attributeItem : attributes)
356     {
357         // Check the attribute presence
358         SimulatorResourceModel::Attribute attribute;
359         if (false == getAttribute((attributeItem.second).getName(), attribute))
360         {
361             return false;
362         }
363
364         // Check the validity of the value to be set
365         if (false == attribute.compare(attributeItem.second))
366         {
367             return false;
368         }
369         m_attributes[(attributeItem.second).getName()].setValue((attributeItem.second).getValue());
370     }
371
372     return true;
373 }
374
375 SimulatorResourceModelSP SimulatorResourceModel::create(const OC::OCRepresentation &ocRep)
376 {
377     SimulatorResourceModelSP resModel(new SimulatorResourceModel);
378     for (auto & attributeItem : ocRep)
379     {
380         SimulatorResourceModel::Attribute attribute;
381         if (attributeItem.type() == OC::AttributeType::Integer)
382             attribute.setValue(attributeItem.getValue<int>());
383         if (attributeItem.type() == OC::AttributeType::Double)
384             attribute.setValue(attributeItem.getValue<double>());
385         if (attributeItem.type() == OC::AttributeType::String)
386             attribute.setValue(attributeItem.getValue<std::string>());
387         if (attributeItem.type() == OC::AttributeType::Boolean)
388             attribute.setValue(attributeItem.getValue<bool>());
389
390         attribute.setName(attributeItem.attrname());
391         resModel->m_attributes[attributeItem.attrname()] = attribute;
392     }
393     return resModel;
394 }
395