Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / simulator / src / common / resource_model_schema_builder.cpp
1 /******************************************************************
2  *
3  * Copyright 2016 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 "resource_model_schema_builder.h"
22 #include "simulator_resource_model_schema.h"
23 #include "Raml.h"
24 #include "Properties.h"
25 #include "logger.h"
26
27 #define TAG "RES_MODEL_BUILDER"
28
29 ResourceModelSchemaBuilder::ResourceModelSchemaBuilder(
30     const std::shared_ptr<RAML::RequestResponseBody> &ramlSchema)
31     :   m_ramlSchema (ramlSchema) {}
32
33 std::shared_ptr<SimulatorResourceModelSchema> ResourceModelSchemaBuilder::build()
34 {
35     if (!m_ramlSchema)
36     {
37         OIC_LOG(ERROR, TAG, "RAML schema pointer is null!");
38         return nullptr;
39     }
40
41     std::shared_ptr<SimulatorResourceModelSchema> modelSchema =
42         SimulatorResourceModelSchema::build();
43
44     auto jsonSchema = m_ramlSchema->getSchema()->getProperties();
45     for (auto &propertyElement : jsonSchema->getProperties())
46     {
47         auto property = propertyElement.second;
48         auto attributeProperty = buildAttribute(property);
49
50         if (!attributeProperty)
51             return nullptr;
52
53         modelSchema->add(property->getName(), attributeProperty);
54     }
55
56     return modelSchema;
57 }
58
59 std::shared_ptr<AttributeProperty> ResourceModelSchemaBuilder::buildAttribute(
60     const std::shared_ptr<RAML::Properties> &property)
61 {
62     switch (property->getType().type())
63     {
64         case RAML::VariantType::INTEGER:
65             return buildIntegerAttribute(property);
66
67         case RAML::VariantType::DOUBLE:
68             return buildDoubleAttribute(property);
69
70         case RAML::VariantType::BOOLEAN:
71             return buildBooleanAttribute(property);
72
73         case RAML::VariantType::STRING:
74             return buildStringAttribute(property);
75
76         case RAML::VariantType::PROPERTY:
77             return buildArrayAttribute(property);
78
79         case RAML::VariantType::ARRAY:
80             return buildModelArrayAttribute(property);
81
82         case RAML::VariantType::OBJECT:
83             return buildModelAttribute(property);
84
85         default:
86             OIC_LOG(ERROR, TAG, "Unknown type!");
87             return nullptr;
88     }
89
90     return nullptr;
91 }
92
93 std::shared_ptr<IntegerProperty> ResourceModelSchemaBuilder::buildIntegerAttribute(
94     const std::shared_ptr<RAML::Properties> &property)
95 {
96     std::shared_ptr<IntegerProperty> integerProperty = IntegerProperty::build();
97
98     // Set Default value
99     if (property->isDefaultValue())
100     {
101         integerProperty->setDefaultValue(property->getValue<int>());
102     }
103
104     // Set the Range/Enum property
105     for (auto &valueProperty : property->getValueProperties())
106     {
107         if (RAML::ValueProperty::Type::RANGE == valueProperty->type())
108         {
109             integerProperty->setRange(valueProperty->min(), valueProperty->max());
110             break;
111         }
112         else if (RAML::ValueProperty::Type::VALUE_SET == valueProperty->type())
113         {
114             std::vector<int> values;
115             for (auto &value : valueProperty->valueSet())
116                 values.push_back(boost::get<int>(value));
117             integerProperty->setValues(values);
118             break;
119         }
120     }
121
122     return integerProperty;
123 }
124
125 std::shared_ptr<DoubleProperty> ResourceModelSchemaBuilder::buildDoubleAttribute(
126     const std::shared_ptr<RAML::Properties> &property)
127 {
128     std::shared_ptr<DoubleProperty> doubleProperty = DoubleProperty::build();
129
130     // Set Default value
131     if (property->isDefaultValue())
132     {
133         doubleProperty->setDefaultValue(property->getValue<double>());
134     }
135
136     // Set the Range/Enum property
137     for (auto &valueProperty : property->getValueProperties())
138     {
139         if (RAML::ValueProperty::Type::RANGE == valueProperty->type())
140         {
141             doubleProperty->setRange(valueProperty->min(), valueProperty->max());
142             break;
143         }
144         else if (RAML::ValueProperty::Type::VALUE_SET == valueProperty->type())
145         {
146             std::vector<double> values;
147             for (auto &value : valueProperty->valueSet())
148                 values.push_back(boost::get<double>(value));
149             doubleProperty->setValues(values);
150             break;
151         }
152     }
153
154     return doubleProperty;
155 }
156
157 std::shared_ptr<BooleanProperty> ResourceModelSchemaBuilder::buildBooleanAttribute(
158     const std::shared_ptr<RAML::Properties> &property)
159 {
160     std::shared_ptr<BooleanProperty> boolProperty = BooleanProperty::build();
161
162     // Set Default value
163     if (property->isDefaultValue())
164     {
165         boolProperty->setDefaultValue(property->getValue<bool>());
166     }
167
168     return boolProperty;
169 }
170
171 std::shared_ptr<StringProperty> ResourceModelSchemaBuilder::buildStringAttribute(
172     const std::shared_ptr<RAML::Properties> &property)
173 {
174     std::shared_ptr<StringProperty> stringProperty = StringProperty::build();
175
176     // Set Default value
177     if (property->isDefaultValue())
178     {
179         stringProperty->setDefaultValue(property->getValue<std::string>());
180     }
181
182     // Set the Range/Enum property
183     for (auto &valueProperty : property->getValueProperties())
184     {
185         if (RAML::ValueProperty::Type::RANGE == valueProperty->type())
186         {
187             stringProperty->setRange(valueProperty->min(), valueProperty->max());
188             break;
189         }
190         else if (RAML::ValueProperty::Type::VALUE_SET == valueProperty->type())
191         {
192             std::vector<std::string> values;
193             for (auto &value : valueProperty->valueSet())
194                 values.push_back(boost::get<std::string>(value));
195             stringProperty->setValues(values);
196             break;
197         }
198     }
199
200     return stringProperty;
201 }
202
203 std::shared_ptr<ArrayProperty> ResourceModelSchemaBuilder::buildArrayAttribute(
204     const std::shared_ptr<RAML::Properties> &property)
205 {
206     std::shared_ptr<ArrayProperty> arrayProperty = ArrayProperty::build();
207
208     auto arrayAttribute = boost::get<RAML::Properties>(property->getValue());
209     switch (arrayAttribute.getType().type())
210     {
211         case RAML::VariantType::INTEGER:
212             {
213                 std::shared_ptr<RAML::Properties> elementAttribute =
214                     std::make_shared<RAML::Properties>(arrayAttribute);
215
216                 std::shared_ptr<IntegerProperty> elementProperty =
217                     buildIntegerAttribute(elementAttribute);
218
219                 setArrayProperties(property, arrayProperty);
220                 arrayProperty->setElementProperty(elementProperty);
221             }
222             break;
223
224         case RAML::VariantType::DOUBLE :
225             {
226                 std::shared_ptr<RAML::Properties> elementAttribute =
227                     std::make_shared<RAML::Properties>(arrayAttribute);
228
229                 std::shared_ptr<DoubleProperty> elementProperty =
230                     buildDoubleAttribute(elementAttribute);
231
232                 setArrayProperties(property, arrayProperty);
233                 arrayProperty->setElementProperty(elementProperty);
234             }
235             break;
236
237         case RAML::VariantType::BOOLEAN :
238             {
239                 std::shared_ptr<RAML::Properties> elementAttribute =
240                     std::make_shared<RAML::Properties>(arrayAttribute);
241
242                 std::shared_ptr<BooleanProperty> elementProperty =
243                     buildBooleanAttribute(elementAttribute);
244
245                 setArrayProperties(property, arrayProperty);
246                 arrayProperty->setElementProperty(elementProperty);
247             }
248             break;
249
250         case RAML::VariantType::STRING :
251             {
252                 std::shared_ptr<RAML::Properties> elementAttribute =
253                     std::make_shared<RAML::Properties>(arrayAttribute);
254
255                 std::shared_ptr<StringProperty> elementProperty =
256                     buildStringAttribute(elementAttribute);
257
258                 setArrayProperties(property, arrayProperty);
259                 arrayProperty->setElementProperty(elementProperty);
260             }
261             break;
262
263         default:
264             OIC_LOG(ERROR, TAG, "Unknown array element type!");
265             return nullptr;
266     }
267
268     return arrayProperty;
269 }
270
271 std::shared_ptr<ArrayProperty> ResourceModelSchemaBuilder::buildModelArrayAttribute(
272     const std::shared_ptr<RAML::Properties> &property)
273 {
274     std::vector<RAML::Properties> attributes =
275         boost::get<std::vector<RAML::Properties> >(property->getValue());
276
277     std::shared_ptr<ModelProperty> modelProperty = ModelProperty::build();
278
279     for (auto attributeProp : attributes)
280     {
281         auto elementProperty = std::make_shared<RAML::Properties>(attributeProp);
282         modelProperty->add(elementProperty->getName(), buildAttribute(elementProperty));
283     }
284
285     std::shared_ptr<ArrayProperty> arrayProperty = ArrayProperty::build();
286     setArrayProperties(property, arrayProperty);
287     arrayProperty->setElementProperty(modelProperty);
288
289     return arrayProperty;
290 }
291
292 std::shared_ptr<ModelProperty> ResourceModelSchemaBuilder::buildModelAttribute(
293     const std::shared_ptr<RAML::Properties> &property)
294 {
295     std::shared_ptr<ModelProperty> modelProperty = ModelProperty::build();
296
297     std::vector<RAML::Properties> attributes =
298         boost::get<std::vector<RAML::Properties> >(property->getValue());
299
300     for (auto attributeProp : attributes)
301     {
302         auto elementProperty = std::make_shared<RAML::Properties>(attributeProp);
303         modelProperty->add(elementProperty->getName(), buildAttribute(elementProperty));
304     }
305
306     return modelProperty;
307 }
308
309 void ResourceModelSchemaBuilder::setArrayProperties(
310     const std::shared_ptr<RAML::Properties> &property,
311     const std::shared_ptr<ArrayProperty> &arrayProperty)
312 {
313     for (auto &valueProperty : property->getValueProperties())
314     {
315         if (RAML::ValueProperty::Type::ARRAY == valueProperty->type())
316         {
317             int minItems = 0;
318             int maxItems = 0;
319             bool unique = false;
320             bool additionalItems = false;
321
322             valueProperty->valueArray(minItems, maxItems, unique, additionalItems);
323             arrayProperty->setRange(minItems, maxItems);
324             arrayProperty->setUnique(unique);
325             arrayProperty->setVariable(additionalItems);
326             break;
327         }
328     }
329 }