9425b0be18e4e7edc81417961e7f8ccdfb419162
[platform/upstream/iotivity.git] / service / simulator / ramlparser / raml / jsonSchemaParser / JsonSchema.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 #include "JsonSchema.h"\r
22 using namespace std;\r
23 \r
24 namespace RAML\r
25 {\r
26 \r
27     void JsonSchema::readJson()\r
28     {\r
29         if (! m_cjson)\r
30             return;\r
31 \r
32         cJSON *jsonId = cJSON_GetObjectItem(m_cjson, "id");\r
33         if (jsonId)\r
34         {\r
35             m_id = jsonId->valuestring;\r
36         }\r
37         cJSON *jsonSchema = cJSON_GetObjectItem(m_cjson, "$schema");\r
38         if (jsonSchema)\r
39         {\r
40             m_schema = jsonSchema->valuestring;\r
41         }\r
42         cJSON *jsonTitle = cJSON_GetObjectItem(m_cjson, "title");\r
43         if (jsonTitle)\r
44         {\r
45             m_title = jsonTitle->valuestring;\r
46         }\r
47         cJSON *jsonType = cJSON_GetObjectItem(m_cjson, "type");\r
48         if (jsonType)\r
49         {\r
50             m_type = jsonType->valuestring;\r
51         }\r
52         cJSON *jsonDescription = cJSON_GetObjectItem(m_cjson, "description");\r
53         if (jsonDescription)\r
54         {\r
55             m_description = jsonDescription->valuestring;\r
56         }\r
57         cJSON *jsonDefinitions = cJSON_GetObjectItem(m_cjson, "definitions");\r
58         if (jsonDefinitions)\r
59         {\r
60             cJSON *childDefinitions = jsonDefinitions->child;\r
61             while (childDefinitions)\r
62             {\r
63                 std::string defName = childDefinitions->string;\r
64                 addDefinition(defName, readDef(childDefinitions, defName));\r
65                 childDefinitions = childDefinitions->next;\r
66             }\r
67         }\r
68         cJSON *jsonProperties = cJSON_GetObjectItem(m_cjson, "properties");\r
69         if (jsonProperties)\r
70         {\r
71             cJSON *childProperties = jsonProperties->child;\r
72             while (childProperties)\r
73             {\r
74                 std::string attName = childProperties->string;\r
75                 addProperty(attName, readProp(childProperties, attName));\r
76                 childProperties = childProperties->next;\r
77             }\r
78         }\r
79         if (m_type == "array")\r
80         {\r
81             cJSON *jsonItems = cJSON_GetObjectItem(m_cjson, "items");\r
82             if (jsonItems)\r
83             {\r
84                 if (jsonItems->type == 5)\r
85                 {\r
86                     int item_size = cJSON_GetArraySize(jsonItems);\r
87                     int item_index = 0;\r
88                     do\r
89                     {\r
90                         cJSON *item = cJSON_GetArrayItem(jsonItems, item_index);\r
91                         setItem(readItems(item));\r
92                     }\r
93                     while ( ++item_index < item_size);\r
94                 }\r
95                 else\r
96                 {\r
97                     setItem(readItems(jsonItems));\r
98                 }\r
99             }\r
100         }\r
101         cJSON *jsonAdditionalProperties = cJSON_GetObjectItem(m_cjson, "additionalProperties");\r
102         if (jsonAdditionalProperties)\r
103             m_additionalProperties = jsonAdditionalProperties->type;\r
104         else\r
105             m_additionalProperties = cJSON_True;\r
106 \r
107         cJSON *jsonReference = cJSON_GetObjectItem(m_cjson, "$ref");\r
108         if (jsonReference)\r
109         {\r
110             readJsonRef(jsonReference);\r
111         }\r
112         cJSON *jsonAllOf = cJSON_GetObjectItem(m_cjson, "allOf");\r
113         if (jsonAllOf)\r
114         {\r
115             readAllOf(jsonAllOf);\r
116         }\r
117         cJSON *jsonRequiredValues = cJSON_GetObjectItem(m_cjson, "required");\r
118         if (jsonRequiredValues)\r
119         {\r
120             int size = cJSON_GetArraySize(jsonRequiredValues);\r
121             int index = 0;\r
122             do\r
123             {\r
124                 setRequiredValue(cJSON_GetArrayItem(jsonRequiredValues, index)->valuestring);\r
125             }\r
126             while ( ++index < size);\r
127         }\r
128     }\r
129 \r
130     DefinitionsPtr JsonSchema::readDef(cJSON *childDefinitions, const std::string &defName)\r
131     {\r
132         DefinitionsPtr definition = std::make_shared<Definitions>(defName);\r
133 \r
134         cJSON *defType = cJSON_GetObjectItem(childDefinitions, "type");\r
135         if (defType)\r
136         {\r
137             std::string type = defType->valuestring;\r
138             definition->setType(type);\r
139         }\r
140         cJSON *defProperties = cJSON_GetObjectItem(childDefinitions, "properties");\r
141         if (defProperties)\r
142         {\r
143             cJSON *childProperties = defProperties->child;\r
144             while (childProperties)\r
145             {\r
146                 std::string attName = childProperties->string;\r
147                 definition->addProperty(attName, readProp(childProperties, attName));\r
148                 childProperties = childProperties->next;\r
149             }\r
150         }\r
151         cJSON *defRequiredValues = cJSON_GetObjectItem(childDefinitions, "required");\r
152         if (defRequiredValues)\r
153         {\r
154             int size = cJSON_GetArraySize(defRequiredValues);\r
155             int index = 0;\r
156             do\r
157             {\r
158                 definition->setRequiredValue(cJSON_GetArrayItem(defRequiredValues, index)->valuestring);\r
159             }\r
160             while ( ++index < size);\r
161         }\r
162         cJSON *defReference = cJSON_GetObjectItem(childDefinitions, "$ref");\r
163         if (defReference)\r
164         {\r
165             readDefRef(defReference, definition);\r
166         }\r
167         cJSON *defAllOf = cJSON_GetObjectItem(childDefinitions, "allOf");\r
168         if (defAllOf)\r
169         {\r
170             readDefAllOf(defAllOf, definition);\r
171         }\r
172         return definition;\r
173     }\r
174 \r
175     PropertiesPtr JsonSchema::readProp(cJSON *childProperties, const std::string &attName )\r
176     {\r
177         PropertiesPtr property = std::make_shared<Properties>(attName);\r
178 \r
179         cJSON *propertyUpdateFrequency = cJSON_GetObjectItem(childProperties, "update_frequency");\r
180         if (propertyUpdateFrequency)\r
181         {\r
182             property->setUpdateFrequencyTime(propertyUpdateFrequency->valueint);\r
183         }\r
184         cJSON *propertyDescription = cJSON_GetObjectItem(childProperties, "description");\r
185         if (propertyDescription)\r
186         {\r
187             property->setDescription(propertyDescription->valuestring);\r
188         }\r
189         cJSON *propertyType = cJSON_GetObjectItem(childProperties, "type");\r
190         if (propertyType)\r
191         {\r
192             std::string attType;\r
193             if (propertyType->type == 4)\r
194             {\r
195                 attType = propertyType->valuestring;\r
196                 property->setType(attType);\r
197             }\r
198             else if (propertyType->type == 5)\r
199             {\r
200                 attType = cJSON_GetArrayItem(propertyType, 0)->valuestring;\r
201                 property->setType(attType);\r
202             }\r
203             readValues(childProperties, property, attType);\r
204         }\r
205         cJSON *defaultValue = cJSON_GetObjectItem(childProperties, "default");\r
206         if (defaultValue)\r
207         {\r
208             if (defaultValue->type == 4)\r
209             {\r
210                 property->setValue((std::string)defaultValue->valuestring);\r
211             }\r
212             else if (defaultValue->type == 3)\r
213             {\r
214                 if (property->getType() == "number")\r
215                     property->setValue((double)defaultValue->valuedouble);\r
216                 else\r
217                     property->setValue((int)defaultValue->valueint );\r
218             }\r
219             else if (defaultValue->type == 1)\r
220             {\r
221                 property->setValue((bool)true);\r
222             }\r
223             else if (defaultValue->type == 0)\r
224             {\r
225                 property->setValue((bool)false);\r
226             }\r
227 \r
228         }\r
229         cJSON *allowedvalues = cJSON_GetObjectItem(childProperties, "enum");\r
230         if (allowedvalues)\r
231         {\r
232             if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 4)\r
233             {\r
234                 int size = cJSON_GetArraySize(allowedvalues);\r
235                 int idx = 0;\r
236                 std::vector<std::string> allwdValues;\r
237                 do\r
238                 {\r
239                     allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valuestring);\r
240                 }\r
241                 while ( ++idx < size);\r
242                 property->setAllowedValues(allwdValues);\r
243             }\r
244             else if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 3)\r
245             {\r
246                 int size = cJSON_GetArraySize(allowedvalues);\r
247                 int idx = 0;\r
248                 if (property->getType() == "number")\r
249                 {\r
250                     std::vector<double> allwdValues;\r
251                     do\r
252                     {\r
253                         allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valuedouble);\r
254                     }\r
255                     while ( ++idx < size);\r
256                     property->setAllowedValues(allwdValues);\r
257                 }\r
258                 else\r
259                 {\r
260                     std::vector<int> allwdValues;\r
261                     do\r
262                     {\r
263                         allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valueint);\r
264                     }\r
265                     while ( ++idx < size);\r
266                     property->setAllowedValues(allwdValues);\r
267                 }\r
268             }\r
269             else if (((cJSON_GetArrayItem(allowedvalues, 0)->type) == 1)\r
270                      || ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 0))\r
271             {\r
272                 int size = cJSON_GetArraySize(allowedvalues);\r
273                 int idx = 0;\r
274                 std::vector<bool> allwdValues;\r
275                 do\r
276                 {\r
277                     if (cJSON_GetArrayItem(allowedvalues, idx)->type)\r
278                         allwdValues.push_back(true);\r
279                     else\r
280                         allwdValues.push_back(false);\r
281                 }\r
282                 while ( ++idx < size);\r
283                 property->setAllowedValues(allwdValues);\r
284             }\r
285         }\r
286         return property;\r
287     }\r
288 \r
289     void JsonSchema::readValues(cJSON *childProperties,  PropertiesPtr property ,\r
290                                 const std::string &attType)\r
291     {\r
292         if (attType == "string")\r
293         {\r
294             readString(childProperties, property);\r
295         }\r
296         else if (attType == "integer")\r
297         {\r
298             readNumber(childProperties, property);\r
299         }\r
300         else if (attType == "array")\r
301         {\r
302             readArray(childProperties, property);\r
303         }\r
304         else if (attType == "number")\r
305         {\r
306             readNumber(childProperties, property);\r
307         }\r
308     }\r
309 \r
310     void JsonSchema::readString(cJSON *childProperties, PropertiesPtr property)\r
311     {\r
312         cJSON *stringMax = cJSON_GetObjectItem(childProperties, "maxLength");\r
313         if (stringMax)\r
314         {\r
315             cJSON *exclusiveMax = cJSON_GetObjectItem(childProperties, "exclusiveMaximum");\r
316             if (exclusiveMax)\r
317             {\r
318                 if (exclusiveMax->type == cJSON_True)\r
319                     property->setMax (--(stringMax->valueint));\r
320                 else\r
321                     property->setMax(stringMax->valueint);\r
322             }\r
323             else\r
324                 property->setMax(stringMax->valueint);\r
325         }\r
326         cJSON *stringMin = cJSON_GetObjectItem(childProperties, "minLength");\r
327         if (stringMin)\r
328         {\r
329             cJSON *exclusiveMin = cJSON_GetObjectItem(childProperties, "exclusiveMinimum");\r
330             if (exclusiveMin)\r
331             {\r
332                 if (exclusiveMin->type == cJSON_True)\r
333                     property->setMin( ++(stringMin->valueint));\r
334                 else\r
335                     property->setMin(stringMin->valueint);\r
336             }\r
337             else\r
338                 property->setMin(stringMin->valueint);\r
339         }\r
340         cJSON *stringFormat = cJSON_GetObjectItem(childProperties, "format");\r
341         if (stringFormat)\r
342         {\r
343             property->setFormat(stringFormat->valuestring);\r
344         }\r
345         cJSON *stringPattern = cJSON_GetObjectItem(childProperties, "pattern");\r
346         if (stringPattern)\r
347         {\r
348             property->setPattern(stringPattern->valuestring);\r
349         }\r
350     }\r
351 \r
352     void JsonSchema::readArray(cJSON *childProperties,  PropertiesPtr property)\r
353     {\r
354         cJSON *itemValues = cJSON_GetObjectItem(childProperties, "items");\r
355         if (itemValues)\r
356         {\r
357             if (itemValues->type == 5)\r
358             {\r
359                 int item_size = cJSON_GetArraySize(itemValues);\r
360                 int item_index = 0;\r
361                 do\r
362                 {\r
363                     cJSON *item = cJSON_GetArrayItem(itemValues, item_index);\r
364                     property->setItem(readItems(item));\r
365                 }\r
366                 while ( ++item_index < item_size);\r
367             }\r
368             else\r
369             {\r
370                 property->setItem(readItems(itemValues));\r
371             }\r
372         }\r
373         cJSON *itemsMax = cJSON_GetObjectItem(childProperties, "maxItems");\r
374         if (itemsMax)\r
375         {\r
376             cJSON *exclusiveMax = cJSON_GetObjectItem(childProperties, "exclusiveMaximum");\r
377             if (exclusiveMax)\r
378             {\r
379                 if (exclusiveMax->type == cJSON_True)\r
380                     property->setMax( --(itemsMax->valueint));\r
381                 else\r
382                     property->setMax(itemsMax->valueint);\r
383             }\r
384             else\r
385                 property->setMax(itemsMax->valueint);\r
386         }\r
387         cJSON *itemsMin = cJSON_GetObjectItem(childProperties, "minLength");\r
388         if (itemsMin)\r
389         {\r
390             cJSON *exclusiveMin = cJSON_GetObjectItem(childProperties, "exclusiveMinimum");\r
391             if (exclusiveMin)\r
392             {\r
393                 if (exclusiveMin->type == cJSON_True)\r
394                     property->setMin( ++(itemsMin->valueint));\r
395                 else\r
396                     property->setMin(itemsMin->valueint);\r
397             }\r
398             else\r
399                 property->setMin(itemsMin->valueint);\r
400         }\r
401         cJSON *uniqueItems = cJSON_GetObjectItem(childProperties, "uniqueItems");\r
402         if (uniqueItems)\r
403         {\r
404             property->setUnique(uniqueItems->type);\r
405         }\r
406         else\r
407         {\r
408             property->setUnique(cJSON_True);\r
409         }\r
410         cJSON *additionalItems = cJSON_GetObjectItem(childProperties, "additionalItems");\r
411         if (additionalItems)\r
412         {\r
413             property->setAdditionalItems(additionalItems->type);\r
414         }\r
415         else\r
416         {\r
417             property->setAdditionalItems(cJSON_True);\r
418         }\r
419     }\r
420 \r
421     void JsonSchema::readNumber(cJSON *childProperties,  PropertiesPtr property)\r
422     {\r
423         cJSON *Max = cJSON_GetObjectItem(childProperties, "maximum");\r
424         if (Max)\r
425         {\r
426             cJSON *exclusiveMax = cJSON_GetObjectItem(childProperties, "exclusiveMaximum");\r
427             if (exclusiveMax)\r
428             {\r
429                 if (exclusiveMax->type == cJSON_True)\r
430                     property->setMax( --(Max->valueint));\r
431                 else\r
432                     property->setMax(Max->valueint);\r
433             }\r
434             else\r
435                 property->setMax(Max->valueint);\r
436         }\r
437         cJSON *Min = cJSON_GetObjectItem(childProperties, "minimum");\r
438         if (Min)\r
439         {\r
440             cJSON *exclusiveMin = cJSON_GetObjectItem(childProperties, "exclusiveMinimum");\r
441             if (exclusiveMin)\r
442             {\r
443                 if (exclusiveMin->type == cJSON_True)\r
444                     property->setMin( ++(Min->valueint));\r
445                 else\r
446                     property->setMin(Min->valueint);\r
447             }\r
448             else\r
449                 property->setMin(Min->valueint);\r
450         }\r
451         cJSON *multipleOf = cJSON_GetObjectItem(childProperties, "multipleOf");\r
452         if (multipleOf)\r
453         {\r
454             property->setMultipleOf(multipleOf->valueint);\r
455         }\r
456 \r
457     }\r
458     DefinitionsPtr JsonSchema::readRef(std::string m_ref)\r
459     {\r
460         std::string delimiter1 = "#";\r
461         std::string delimiter2 = "/";\r
462         std::string fileName;\r
463         if (! m_ref.empty())\r
464         {\r
465             std::size_t pos = m_ref.find(delimiter1);\r
466             if ( (pos = m_ref.find(delimiter1)) != std::string::npos)\r
467             {\r
468                 fileName = m_ref.substr(0, pos);\r
469                 m_ref.erase(0, pos);\r
470             }\r
471             m_ref.erase(0, delimiter1 .length());\r
472             std::string defName;\r
473 \r
474             if (! m_ref.empty())\r
475             {\r
476                 m_ref.erase(0, delimiter2 .length());\r
477                 std::string keyName;\r
478                 if ( (pos = m_ref.find(delimiter2)) != std::string::npos)\r
479                 {\r
480                     keyName = m_ref.substr(0, pos);\r
481                     m_ref.erase(0, pos + delimiter2.length());\r
482                     if (keyName == "definitions")\r
483                     {\r
484                         if ( (pos = m_ref.find(delimiter2)) != std::string::npos)\r
485                         {\r
486                             defName = m_ref.substr(0, pos);\r
487                         }\r
488                         else if (! m_ref.empty())\r
489                         {\r
490                             defName = m_ref;\r
491                         }\r
492                     }\r
493                 }\r
494             }\r
495             if (!fileName.empty())\r
496             {\r
497                 if (!(defName.empty()))\r
498                 {\r
499                     cJSON *m_json = m_includeResolver->readToJson(fileName);\r
500                     JsonSchemaPtr Refparser = std::make_shared<JsonSchema>(m_json, m_includeResolver);\r
501                     DefinitionsPtr definition = Refparser->getDefinition(defName);\r
502                     if (definition == nullptr)\r
503                         throw JsonException("Definition Name Incorrect");\r
504                     return definition;\r
505                 }\r
506             }\r
507             else\r
508             {\r
509                 if (!(defName.empty()))\r
510                 {\r
511                     if (getDefinition(defName) == nullptr)\r
512                         throw JsonException("Definition Name Incorrect");\r
513                     return getDefinition(defName);\r
514                 }\r
515             }\r
516         }\r
517         throw JsonException("Definition Name Empty");\r
518         return nullptr;\r
519     }\r
520     void JsonSchema::readAllOf(cJSON *allofValues)\r
521     {\r
522         int size = cJSON_GetArraySize(allofValues);\r
523         int index = 0;\r
524         do\r
525         {\r
526             cJSON *childAllOf = cJSON_GetArrayItem(allofValues, index);\r
527             cJSON *jsonReference = cJSON_GetObjectItem(childAllOf, "$ref");\r
528             if (jsonReference)\r
529             {\r
530                 readJsonRef(jsonReference );\r
531             }\r
532             cJSON *jsonRequiredValues = cJSON_GetObjectItem(childAllOf, "required");\r
533             if (jsonRequiredValues)\r
534             {\r
535                 int len = cJSON_GetArraySize(jsonRequiredValues);\r
536                 int idx = 0;\r
537                 do\r
538                 {\r
539                     setRequiredValue(cJSON_GetArrayItem(jsonRequiredValues, idx)->valuestring);\r
540                 }\r
541                 while ( ++idx < len);\r
542             }\r
543         }\r
544         while ( ++index < size);\r
545     }\r
546     void JsonSchema::readJsonRef(cJSON *jsonReference)\r
547     {\r
548         std::string m_ref = jsonReference->valuestring;\r
549         std::map<std::string, PropertiesPtr > properties;\r
550         std::vector<std::string> required;\r
551 \r
552         std::string web = "http://";\r
553         std::string delimiter = "#";\r
554         std::size_t pos = m_ref.find(web);\r
555 \r
556         if (pos == std::string::npos)   // If Web Link Is GIVEN TO READ\r
557         {\r
558             pos = m_ref.find(delimiter);\r
559             if ( pos ==  (m_ref.length() - 1) )\r
560             {\r
561                 std::string fileName = m_ref.substr(0, pos);\r
562                 cJSON *m_json = m_includeResolver->readToJson(fileName);\r
563                 JsonSchemaPtr Refparser = std::make_shared<JsonSchema>(m_json, m_includeResolver);\r
564 \r
565                 properties = Refparser->getProperties();\r
566                 required = Refparser->getRequiredValues();\r
567             }\r
568             else\r
569             {\r
570                 DefinitionsPtr definition = readRef(m_ref);\r
571                 properties = definition->getProperties();\r
572                 required = definition->getRequiredValues();\r
573             }\r
574             for ( auto it : properties)\r
575             {\r
576                 std:: string name = it.first;\r
577                 addProperty(name, it.second);\r
578             }\r
579             for (auto it : required )\r
580             {\r
581                 setRequiredValue(it);\r
582             }\r
583 \r
584         }\r
585     }\r
586     void JsonSchema::readDefAllOf(cJSON *allofValues, DefinitionsPtr definition)\r
587     {\r
588         int size = cJSON_GetArraySize(allofValues);\r
589         int index = 0;\r
590         do\r
591         {\r
592             cJSON *childAllOf = cJSON_GetArrayItem(allofValues, index);\r
593             cJSON *defReference = cJSON_GetObjectItem(childAllOf, "$ref");\r
594             if (defReference)\r
595             {\r
596                 readDefRef(defReference , definition);\r
597             }\r
598             cJSON *defRequiredValues = cJSON_GetObjectItem(allofValues, "required");\r
599             if (defRequiredValues)\r
600             {\r
601                 int len = cJSON_GetArraySize(defRequiredValues);\r
602                 int idx = 0;\r
603                 do\r
604                 {\r
605                     definition->setRequiredValue(cJSON_GetArrayItem(defRequiredValues, idx)->valuestring);\r
606                 }\r
607                 while ( ++idx < len);\r
608             }\r
609         }\r
610         while ( ++index < size);\r
611     }\r
612     void JsonSchema::readDefRef(cJSON *defReference, DefinitionsPtr definition)\r
613     {\r
614         std::string m_ref = defReference->valuestring;\r
615         std::map<std::string, PropertiesPtr > properties;\r
616         std::vector<std::string> required;\r
617         std::string type;\r
618 \r
619         std::string web = "http://";\r
620         std::string delimiter = "#";\r
621         std::size_t pos = m_ref.find(web);\r
622 \r
623         if (pos == std::string::npos)   // If Web Link Is GIVEN TO READ\r
624         {\r
625             pos = m_ref.find(delimiter);\r
626             if ( pos ==  (m_ref.length() - 1) )\r
627             {\r
628                 std::string fileName = m_ref.substr(0, pos);\r
629                 cJSON *m_json = m_includeResolver->readToJson(fileName);\r
630                 JsonSchemaPtr Refparser = std::make_shared<JsonSchema>(m_json, m_includeResolver);\r
631 \r
632                 properties = Refparser->getProperties();\r
633                 required = Refparser->getRequiredValues();\r
634                 type =    Refparser->getType();\r
635             }\r
636             else\r
637             {\r
638                 DefinitionsPtr definitionRef = readRef(m_ref);\r
639                 properties = definitionRef->getProperties();\r
640                 required = definitionRef->getRequiredValues();\r
641                 type =    definitionRef->getType();\r
642             }\r
643             for (auto it : properties)\r
644             {\r
645                 definition->addProperty(it.first, it.second);\r
646             }\r
647             for ( auto it : required)\r
648             {\r
649                 definition->setRequiredValue(it);\r
650             }\r
651             definition->setType(type);\r
652         }\r
653     }\r
654     ItemsPtr JsonSchema::readItems(cJSON *item)\r
655     {\r
656         ItemsPtr newItem = std::make_shared<Items>();\r
657         cJSON *itemType = cJSON_GetObjectItem(item, "type");\r
658         if (itemType)\r
659         {\r
660             std::string type = itemType->valuestring;\r
661             newItem->setType(type);\r
662         }\r
663 \r
664         cJSON *itemProperties = cJSON_GetObjectItem(item, "properties");\r
665         if (itemProperties)\r
666         {\r
667             cJSON *childProperties = itemProperties->child;\r
668             while (childProperties)\r
669             {\r
670                 std::string attName = childProperties->string;\r
671 \r
672                 newItem->addProperty(attName, readProp(childProperties, attName));\r
673                 childProperties = childProperties->next;\r
674             }\r
675         }\r
676 \r
677         cJSON *allowedvalues = cJSON_GetObjectItem(item, "enum");\r
678         if (allowedvalues)\r
679         {\r
680             if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 4)\r
681             {\r
682                 int size = cJSON_GetArraySize(allowedvalues);\r
683                 int idx = 0;\r
684                 std::vector<std::string> allwdValues;\r
685                 do\r
686                 {\r
687                     allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valuestring);\r
688                 }\r
689                 while ( ++idx < size);\r
690                 newItem->setAllowedValues(allwdValues);\r
691             }\r
692             else if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 3)\r
693             {\r
694                 int size = cJSON_GetArraySize(allowedvalues);\r
695                 int idx = 0;\r
696                 if (newItem->getType() == "number")\r
697                 {\r
698                     std::vector<double> allwdValues;\r
699                     do\r
700                     {\r
701                         allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valuedouble);\r
702                     }\r
703                     while ( ++idx < size);\r
704                     newItem->setAllowedValues(allwdValues);\r
705                 }\r
706                 else\r
707                 {\r
708                     std::vector<int> allwdValues;\r
709                     do\r
710                     {\r
711                         allwdValues.push_back(cJSON_GetArrayItem(allowedvalues, idx)->valueint);\r
712                     }\r
713                     while ( ++idx < size);\r
714                     newItem->setAllowedValues(allwdValues);\r
715                 }\r
716             }\r
717             else if (((cJSON_GetArrayItem(allowedvalues, 0)->type) == 1)\r
718                      || ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 0))\r
719             {\r
720                 int size = cJSON_GetArraySize(allowedvalues);\r
721                 int idx = 0;\r
722                 std::vector<bool> allwdValues;\r
723                 do\r
724                 {\r
725                     if (cJSON_GetArrayItem(allowedvalues, idx)->type)\r
726                         allwdValues.push_back(true);\r
727                     else\r
728                         allwdValues.push_back(false);\r
729                 }\r
730                 while ( ++idx < size);\r
731                 newItem->setAllowedValues(allwdValues);\r
732             }\r
733         }\r
734         cJSON *itemRequiredValues = cJSON_GetObjectItem(item, "required");\r
735         if (itemRequiredValues)\r
736         {\r
737             int size = cJSON_GetArraySize(itemRequiredValues);\r
738             int index = 0;\r
739             do\r
740             {\r
741                 newItem->setRequiredValue(cJSON_GetArrayItem(itemRequiredValues, index)->valuestring);\r
742             }\r
743             while ( ++index < size);\r
744         }\r
745         cJSON *itemReference = cJSON_GetObjectItem(item, "$ref");\r
746         if (itemReference)\r
747         {\r
748             readItemRef(itemReference , newItem);\r
749         }\r
750         cJSON *itemAllOf = cJSON_GetObjectItem(item, "allOf");\r
751         if (itemAllOf)\r
752         {\r
753             readItemAllOf(itemAllOf , newItem);\r
754         }\r
755         return newItem;\r
756     }\r
757 \r
758     void JsonSchema::readItemRef(cJSON *itemReference, ItemsPtr item)\r
759     {\r
760         std::string m_ref = itemReference->valuestring;\r
761         std::map<std::string, PropertiesPtr > properties;\r
762         std::vector<std::string> required;\r
763         std::string type;\r
764 \r
765         std::string web = "http://";\r
766         std::string delimiter = "#";\r
767         std::size_t pos = m_ref.find(web);\r
768 \r
769         if (pos == std::string::npos)   // If Web Link Is GIVEN TO READ\r
770         {\r
771             pos = m_ref.find(delimiter);\r
772             if ( pos ==  (m_ref.length() - 1 ) )\r
773             {\r
774                 std::string fileName = m_ref.substr(0, pos);\r
775                 cJSON *m_json = m_includeResolver->readToJson(fileName);\r
776                 JsonSchemaPtr Refparser = std::make_shared<JsonSchema>(m_json, m_includeResolver);\r
777 \r
778                 properties = Refparser->getProperties();\r
779                 required = Refparser->getRequiredValues();\r
780                 type =    Refparser->getType();\r
781             }\r
782             else\r
783             {\r
784                 DefinitionsPtr definitionRef = readRef(m_ref);\r
785                 properties = definitionRef->getProperties();\r
786                 required = definitionRef->getRequiredValues();\r
787                 type =    definitionRef->getType();\r
788             }\r
789             for ( auto it : properties)\r
790             {\r
791                 std:: string name = it.first;\r
792                 item->addProperty(name, it.second);\r
793             }\r
794             for ( auto it : required)\r
795             {\r
796                 item->setRequiredValue(it);\r
797             }\r
798             item->setType(type);\r
799         }\r
800     }\r
801 \r
802     void JsonSchema::readItemAllOf(cJSON *allofValues, ItemsPtr item)\r
803     {\r
804         int size = cJSON_GetArraySize(allofValues);\r
805         int index = 0;\r
806         do\r
807         {\r
808             cJSON *childAllOf = cJSON_GetArrayItem(allofValues, index);\r
809             cJSON *itemReference = cJSON_GetObjectItem(childAllOf, "$ref");\r
810             if (itemReference)\r
811             {\r
812                 readItemRef(itemReference, item);\r
813             }\r
814             cJSON *itemRequiredValues = cJSON_GetObjectItem(allofValues, "required");\r
815             if (itemRequiredValues)\r
816             {\r
817                 int len = cJSON_GetArraySize(itemRequiredValues);\r
818                 int idx = 0;\r
819                 do\r
820                 {\r
821                     item->setRequiredValue(cJSON_GetArrayItem(itemRequiredValues, idx)->valuestring);\r
822                 }\r
823                 while ( ++idx < len);\r
824             }\r
825         }\r
826         while ( ++index < size);\r
827     }\r
828 }\r
829 \r