Fix for SVACE and Klocwork issues in RAML parser module.
[platform/upstream/iotivity.git] / service / simulator / ramlparser / raml / jsonSchemaParser / Properties.cpp
1 /******************************************************************\r
2  *\r
3  * Copyright 2015 Samsung Electronics All Rights Reserved.\r
4  *\r
5  *\r
6  *\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  *\r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  *\r
19  ******************************************************************/\r
20 \r
21 /**\r
22  * @file   Properties.cpp\r
23  *\r
24  * @brief   This file provides data Model for Json Schema Properties.\r
25  */\r
26 \r
27 #include "Properties.h"\r
28 #include <boost/lexical_cast.hpp>\r
29 #include <boost/variant/static_visitor.hpp>\r
30 #include "RamlExceptions.h"\r
31 \r
32 namespace RAML\r
33 {\r
34     template <typename T>\r
35     struct TypeConverter {};\r
36 \r
37     template <>\r
38     struct TypeConverter<int>\r
39     {\r
40         constexpr static VariantType type =\r
41             VariantType::INTEGER;\r
42     };\r
43 \r
44     template <>\r
45     struct TypeConverter<double>\r
46     {\r
47         constexpr static VariantType type =\r
48             VariantType::DOUBLE;\r
49     };\r
50 \r
51     template <>\r
52     struct TypeConverter<bool>\r
53     {\r
54         constexpr static VariantType type =\r
55             VariantType::BOOLEAN;\r
56     };\r
57 \r
58     template <>\r
59     struct TypeConverter<std::string>\r
60     {\r
61         constexpr static VariantType type =\r
62             VariantType::STRING;\r
63     };\r
64 \r
65     template <>\r
66     struct TypeConverter<Properties>\r
67     {\r
68         constexpr static VariantType type =\r
69             VariantType::PROPERTY;\r
70     };\r
71 \r
72     template <typename T>\r
73     struct TypeDetails\r
74     {\r
75         constexpr static VariantType type =\r
76             TypeConverter<T>::type;\r
77         constexpr static VariantType baseType =\r
78             TypeConverter<T>::type;\r
79         constexpr static int depth = 0;\r
80     };\r
81 \r
82     template <typename T>\r
83     struct TypeDetails<std::vector<T>>\r
84     {\r
85         constexpr static VariantType type =\r
86             VariantType::ARRAY;\r
87         constexpr static VariantType baseType =\r
88             TypeDetails<T>::baseType;\r
89         constexpr static int depth = 1 + TypeDetails<T>::depth;\r
90     };\r
91 \r
92     class PropertyTypeVisitor : public boost::static_visitor<>\r
93     {\r
94         public:\r
95             PropertyTypeVisitor() : m_type(VariantType::UNKNOWN),\r
96                 m_baseType(VariantType::UNKNOWN), m_depth(0) {}\r
97 \r
98             template <typename T>\r
99             void operator ()(const T &)\r
100             {\r
101                 m_type = TypeDetails<T>::type;\r
102                 m_baseType = TypeDetails<T>::baseType;\r
103                 m_depth = TypeDetails<T>::depth;\r
104             }\r
105 \r
106             VariantType m_type;\r
107             VariantType m_baseType;\r
108             int m_depth;\r
109     };\r
110 \r
111     Properties::TypeInfo Properties::getType() const\r
112     {\r
113         if (m_value)\r
114         {\r
115             RAML::PropertyTypeVisitor typeVisitor;\r
116             boost::apply_visitor(typeVisitor, *(m_value.get()));\r
117             Properties::TypeInfo typeInfo(typeVisitor.m_type, typeVisitor.m_baseType,\r
118                                           typeVisitor.m_depth);\r
119             return typeInfo;\r
120         }\r
121         else if (!m_typeString.empty()) //to read properties even if default value is not present\r
122         {\r
123             if (m_typeString == "string")\r
124                 return Properties::TypeInfo(VariantType::STRING, VariantType::STRING, 0);\r
125             else if (m_typeString == "integer")\r
126                 return Properties::TypeInfo(VariantType::INTEGER, VariantType::INTEGER, 0);\r
127             else if (m_typeString == "number")\r
128                 return Properties::TypeInfo(VariantType::DOUBLE, VariantType::DOUBLE, 0);\r
129             else if (m_typeString == "boolean")\r
130                 return Properties::TypeInfo(VariantType::BOOLEAN, VariantType::BOOLEAN, 0);\r
131         }\r
132         return Properties::TypeInfo();\r
133     }\r
134 \r
135     void Properties::setTypeString(const std::string &type)\r
136     {\r
137         m_typeString = type;\r
138     }\r
139 \r
140     Properties::TypeInfo::TypeInfo(VariantType type,\r
141                                    VariantType baseType, int depth)\r
142         :   m_type (type), m_baseType(baseType), m_depth(depth) {}\r
143 \r
144     VariantType Properties::TypeInfo::type() const\r
145     {\r
146         return m_type;\r
147     }\r
148 \r
149     VariantType Properties::TypeInfo::baseType() const\r
150     {\r
151         return m_baseType;\r
152     }\r
153 \r
154     int Properties::TypeInfo::depth() const\r
155     {\r
156         return m_depth;\r
157     }\r
158 \r
159     bool Properties::TypeInfo::operator==(\r
160         const Properties::TypeInfo &rhs ) const\r
161     {\r
162         if (m_type == rhs.type() && m_baseType == rhs.baseType()\r
163             && m_depth == rhs.depth())\r
164             return true;\r
165         return false;\r
166     }\r
167 \r
168     bool Properties::TypeInfo::operator!=(\r
169         const Properties::TypeInfo &rhs ) const\r
170     {\r
171         if (m_type != rhs.type() || m_baseType != rhs.baseType()\r
172             || m_depth != rhs.depth())\r
173             return true;\r
174         return false;\r
175     }\r
176 \r
177     ValueVariant Properties::getValue() const\r
178     {\r
179         if (!isDefaultValue())\r
180             throw JsonException("Reading Empty Property Value");\r
181         return *m_value;\r
182     }\r
183 \r
184     std::string Properties::getName() const\r
185     {\r
186         return m_name;\r
187     }\r
188 \r
189     void Properties::setName(const std::string &name)\r
190     {\r
191         m_name = name;\r
192     }\r
193     std::string Properties::getDescription() const\r
194     {\r
195         return m_description;\r
196     }\r
197 \r
198     void Properties::setDescription(const std::string &description)\r
199     {\r
200         m_description = description;\r
201     }\r
202     std::vector<std::shared_ptr<ValueProperty> > const &Properties::getValueProperties()\r
203     const\r
204     {\r
205         return m_valueProperty;\r
206     }\r
207     void Properties::setValueProperty(const std::shared_ptr<ValueProperty> &value)\r
208     {\r
209         m_valueProperty.push_back(value);\r
210     }\r
211     std::vector<std::string> const &Properties::getRequiredValues() const\r
212     {\r
213         return m_required;\r
214     }\r
215     void Properties::setRequiredValue(const std::string &reqValue)\r
216     {\r
217         auto it = m_required.begin();\r
218         for (; it != m_required.end(); ++it)\r
219         {\r
220             if (*it == reqValue)\r
221                 break;\r
222         }\r
223         if (m_required.end() == it)\r
224         {\r
225             m_required.push_back(reqValue);\r
226         }\r
227     }\r
228     ValueProperty::ValueProperty()\r
229         :   m_type(ValueProperty::Type::UNKNOWN),\r
230             m_min(INT_MIN),\r
231             m_max(INT_MAX),\r
232             m_multipleOf(INT_MAX),\r
233             m_minItems(INT_MIN),\r
234             m_maxItems(INT_MAX),\r
235             m_unique(false),\r
236             m_additionalItems(false) {}\r
237 \r
238     ValueProperty::ValueProperty(double min, double max, int multipleOf)\r
239         :   m_type(ValueProperty::Type::RANGE),\r
240             m_min(min),\r
241             m_max(max),\r
242             m_multipleOf(multipleOf),\r
243             m_minItems(INT_MIN),\r
244             m_maxItems(INT_MAX),\r
245             m_unique(false),\r
246             m_additionalItems(false) {}\r
247 \r
248     ValueProperty::ValueProperty(\r
249         const std::vector<int> &valueSet)\r
250         :   m_type(ValueProperty::Type::VALUE_SET),\r
251             m_min(INT_MIN),\r
252             m_max(INT_MAX),\r
253             m_multipleOf(INT_MAX),\r
254             m_valueSet(valueSet.begin(), valueSet.end()),\r
255             m_minItems(INT_MIN),\r
256             m_maxItems(INT_MAX),\r
257             m_unique(false),\r
258             m_additionalItems(false)  {}\r
259 \r
260     ValueProperty::ValueProperty(\r
261         const std::vector<double> &valueSet)\r
262         :   m_type(ValueProperty::Type::VALUE_SET),\r
263             m_min(INT_MIN),\r
264             m_max(INT_MAX),\r
265             m_multipleOf(INT_MAX),\r
266             m_valueSet(valueSet.begin(), valueSet.end()),\r
267             m_minItems(INT_MIN),\r
268             m_maxItems(INT_MAX),\r
269             m_unique(false),\r
270             m_additionalItems(false)  {}\r
271 \r
272     ValueProperty::ValueProperty(\r
273         const std::vector<bool> &valueSet)\r
274         :   m_type(ValueProperty::Type::VALUE_SET),\r
275             m_min(INT_MIN),\r
276             m_max(INT_MAX),\r
277             m_multipleOf(INT_MAX),\r
278             m_valueSet(valueSet.begin(), valueSet.end()),\r
279             m_minItems(INT_MIN),\r
280             m_maxItems(INT_MAX),\r
281             m_unique(false),\r
282             m_additionalItems(false)  {}\r
283 \r
284     ValueProperty::ValueProperty(\r
285         const std::vector<std::string> &valueSet)\r
286         :   m_type(ValueProperty::Type::VALUE_SET),\r
287             m_min(INT_MIN),\r
288             m_max(INT_MAX),\r
289             m_multipleOf(INT_MAX),\r
290             m_valueSet(valueSet.begin(), valueSet.end()),\r
291             m_minItems(INT_MIN),\r
292             m_maxItems(INT_MAX),\r
293             m_unique(false),\r
294             m_additionalItems(false)  {}\r
295 \r
296     ValueProperty::ValueProperty(\r
297         const std::vector<ValueVariant> &valueSet)\r
298         :   m_type(ValueProperty::Type::VALUE_SET),\r
299             m_min(INT_MIN),\r
300             m_max(INT_MAX),\r
301             m_multipleOf(INT_MAX),\r
302             m_valueSet(valueSet.begin(), valueSet.end()),\r
303             m_minItems(INT_MIN),\r
304             m_maxItems(INT_MAX),\r
305             m_unique(false),\r
306             m_additionalItems(false)  {}\r
307 \r
308     ValueProperty::ValueProperty(Type type, std::string value)\r
309         :   m_min(INT_MIN),\r
310             m_max(INT_MAX),\r
311             m_multipleOf(INT_MAX),\r
312             m_minItems(INT_MIN),\r
313             m_maxItems(INT_MAX),\r
314             m_unique(false),\r
315             m_additionalItems(false)\r
316     {\r
317         if (type == ValueProperty::Type::PATTERN)\r
318         {\r
319             m_type = ValueProperty::Type::PATTERN;\r
320             m_pattern = value;\r
321         }\r
322         else if (type == ValueProperty::Type::FORMAT)\r
323         {\r
324             m_type = ValueProperty::Type::FORMAT;\r
325             m_format = value;\r
326         }\r
327         else\r
328         {\r
329             m_type = ValueProperty::Type::UNKNOWN;\r
330         }\r
331     }\r
332 \r
333     ValueProperty::ValueProperty(Type type, int minItems, int maxItems, bool unique,\r
334                                  bool additionalItems)\r
335         :   m_type(ValueProperty::Type::UNKNOWN),\r
336             m_min(INT_MIN),\r
337             m_max(INT_MAX),\r
338             m_multipleOf(INT_MAX),\r
339             m_minItems(1),\r
340             m_maxItems(20),\r
341             m_unique(false),\r
342             m_additionalItems(false)\r
343     {\r
344         if (type == ValueProperty::Type::ARRAY)\r
345         {\r
346             m_type = ValueProperty::Type::ARRAY;\r
347 \r
348             if (minItems > 0)\r
349                 m_minItems = minItems;\r
350 \r
351             if (maxItems != INT_MAX && maxItems > m_minItems)\r
352                 m_maxItems = maxItems;\r
353 \r
354             m_unique = unique;\r
355             m_additionalItems = additionalItems;\r
356         }\r
357     }\r
358 \r
359     ValueProperty::Type ValueProperty::type() const\r
360     {\r
361         return m_type;\r
362     }\r
363 \r
364     double ValueProperty::min() const\r
365     {\r
366         return m_min;\r
367     }\r
368 \r
369     double ValueProperty::max() const\r
370     {\r
371         return m_max;\r
372     }\r
373 \r
374     int ValueProperty::multipleOf() const\r
375     {\r
376         return m_multipleOf;\r
377     }\r
378 \r
379     std::string ValueProperty::pattern() const\r
380     {\r
381         return m_pattern;\r
382     }\r
383 \r
384     std::string ValueProperty::format() const\r
385     {\r
386         return m_format;\r
387     }\r
388 \r
389     int ValueProperty::valueSetSize() const\r
390     {\r
391         return m_valueSet.size();\r
392     }\r
393 \r
394     std::vector<ValueVariant> ValueProperty::valueSet() const\r
395     {\r
396         return m_valueSet;\r
397     }\r
398 \r
399     void ValueProperty::valueArray(int &minItems, int &maxItems, bool &unique,\r
400                                    bool &additionalItems) const\r
401     {\r
402         minItems = m_minItems;\r
403         maxItems = m_maxItems;\r
404         unique = m_unique;\r
405         additionalItems = m_additionalItems;\r
406     }\r
407 \r
408 \r
409 }\r