Displaying and editing the complex value types for attributes.
[platform/upstream/iotivity.git] / service / simulator / java / jni / simulator_resource_model_jni.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_jni.h"
22 #include "simulator_error_codes.h"
23 #include "simulator_exceptions_jni.h"
24 #include "simulator_utils_jni.h"
25 #include "jni_string.h"
26
27 class JniTypeInfo
28 {
29     public:
30         JniTypeInfo(JNIEnv *env) : m_env(env) {}
31
32         SimulatorResourceModel::TypeInfo toCpp(jobject jAttributeValue)
33         {
34             static jmethodID typeInfoMID = m_env->GetMethodID(gSimulatorClassRefs.attributeValueCls,
35                                            "typeInfo", "()Lorg/oic/simulator/AttributeValue$TypeInfo;");
36             static jfieldID typeFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
37                                       "mType", "Lorg/oic/simulator/AttributeValue$ValueType;");
38             static jfieldID baseTypeFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
39                                           "mBaseType", "Lorg/oic/simulator/AttributeValue$ValueType;");
40             static jfieldID depthFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
41                                        "mDepth", "I");
42
43             jobject jTypeInfo = m_env->CallObjectMethod(jAttributeValue, typeInfoMID);
44             jobject jType = m_env->GetObjectField(jTypeInfo, typeFID);
45             jobject jBaseType = m_env->GetObjectField(jTypeInfo, baseTypeFID);
46             jint jDepth = m_env->GetIntField(jTypeInfo, depthFID);
47
48             return SimulatorResourceModel::TypeInfo(getValueType(jType),
49                                                     getValueType(jBaseType), jDepth);
50         }
51
52     private:
53         SimulatorResourceModel::ValueType getValueType(jobject jValueType)
54         {
55             static jmethodID ordinalMID = m_env->GetMethodID(
56                                               gSimulatorClassRefs.attributeValueTypeCls, "ordinal", "()I");
57
58             int ordinal = m_env->CallIntMethod(jValueType, ordinalMID);
59             return SimulatorResourceModel::ValueType(ordinal);
60         }
61
62         JNIEnv *m_env;
63 };
64
65 class ValueConverterJava : public boost::static_visitor<jobject>
66 {
67     public:
68         ValueConverterJava(JNIEnv *env) : m_env(env) {}
69
70         jobject operator ()(const int &value)
71         {
72             static jmethodID integerCtor =
73                 m_env->GetMethodID(gSimulatorClassRefs.integerCls, "<init>", "(I)V");
74             return m_env->NewObject(gSimulatorClassRefs.integerCls,
75                                     integerCtor, value);
76         }
77
78         jobject operator ()(const double &value)
79         {
80             static jmethodID doubleCtor =
81                 m_env->GetMethodID(gSimulatorClassRefs.doubleCls, "<init>", "(D)V");
82             return m_env->NewObject(gSimulatorClassRefs.doubleCls,
83                                     doubleCtor, value);
84         }
85
86         jobject operator ()(const bool &value)
87         {
88             static jmethodID booleanCtor =
89                 m_env->GetMethodID(gSimulatorClassRefs.booleanCls, "<init>", "(Z)V");
90             return m_env->NewObject(gSimulatorClassRefs.booleanCls,
91                                     booleanCtor, value);
92         }
93
94         jobject operator ()(const std::string &value)
95         {
96             jstring stringValue = m_env->NewStringUTF(value.c_str());
97             return static_cast<jobject>(stringValue);
98         }
99
100         jobject operator ()(const SimulatorResourceModel &value)
101         {
102             return simulatorResourceModelToJava(m_env, const_cast<SimulatorResourceModel &>(value));
103         }
104
105         template <typename T>
106         jobject operator ()(const std::vector<T> &values)
107         {
108             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
109             if (!jArray)
110                 return nullptr;
111
112             for (size_t index = 0; index < values.size(); index++)
113             {
114                 jobject element = operator()(values[index]);
115                 m_env->SetObjectArrayElement(jArray, index, element);
116             }
117
118             return jArray;
119         }
120
121         template <typename T>
122         jobject operator ()(const std::vector<std::vector<T>> &values)
123         {
124             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
125             if (!jArray)
126                 return nullptr;
127
128             for (size_t index = 0; index < values.size(); index++)
129             {
130                 jobject element = operator()(values[index]);
131                 m_env->SetObjectArrayElement(jArray, index, element);
132             }
133
134             return jArray;
135         }
136
137         template <typename T>
138         jobject operator ()(const std::vector<std::vector<std::vector<T>>> &values)
139         {
140             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
141             if (!jArray)
142                 return nullptr;
143
144             for (size_t index = 0; index < values.size(); index++)
145             {
146                 jobject element = operator()(values[index]);
147                 m_env->SetObjectArrayElement(jArray, index, element);
148             }
149
150             return jArray;
151         }
152
153     private:
154         jclass getClass(const std::vector<int> &)
155         {
156             return gSimulatorClassRefs.integerCls;
157         }
158
159         jclass getClass(const std::vector<std::vector<int>> &)
160         {
161             return gSimulatorClassRefs.integer1DArrayCls;
162         }
163
164         jclass getClass(const std::vector<std::vector<std::vector<int>>> &)
165         {
166             return gSimulatorClassRefs.integer2DArrayCls;
167         }
168
169         jclass getClass(const std::vector<double> &)
170         {
171             return gSimulatorClassRefs.doubleCls;
172         }
173
174         jclass getClass(const std::vector<std::vector<double>> &)
175         {
176             return gSimulatorClassRefs.double1DArrayCls;
177         }
178
179         jclass getClass(const std::vector<std::vector<std::vector<double>>> &)
180         {
181             return gSimulatorClassRefs.double2DArrayCls;
182         }
183
184         jclass getClass(const std::vector<bool> &)
185         {
186             return gSimulatorClassRefs.booleanCls;
187         }
188
189         jclass getClass(const std::vector<std::vector<bool>> &)
190         {
191             return gSimulatorClassRefs.boolean1DArrayCls;
192         }
193
194         jclass getClass(const std::vector<std::vector<std::vector<bool>>> &)
195         {
196             return gSimulatorClassRefs.boolean2DArrayCls;
197         }
198
199         jclass getClass(const std::vector<std::string> &)
200         {
201             return gSimulatorClassRefs.stringCls;
202         }
203
204         jclass getClass(const std::vector<std::vector<std::string>> &)
205         {
206             return gSimulatorClassRefs.string1DArrayCls;
207         }
208
209         jclass getClass(const std::vector<std::vector<std::vector<std::string>>> &)
210         {
211             return gSimulatorClassRefs.string2DArrayCls;
212         }
213
214         jclass getClass(const std::vector<SimulatorResourceModel> &)
215         {
216             return gSimulatorClassRefs.simulatorResourceModelCls;
217         }
218
219         jclass getClass(const std::vector<std::vector<SimulatorResourceModel>> &)
220         {
221             return gSimulatorClassRefs.simulatorResModel1DArrayCls;
222         }
223
224         jclass getClass(const std::vector<std::vector<std::vector<SimulatorResourceModel>>> &)
225         {
226             return gSimulatorClassRefs.simulatorResModel2DArrayCls;
227         }
228
229         JNIEnv *m_env;
230 };
231
232 class ValueConverterCpp
233 {
234     public:
235         ValueConverterCpp(JNIEnv *env, SimulatorResourceModel::TypeInfo &typeInfo,
236                           jobject &value) : m_env(env), m_typeInfo(typeInfo), m_value(value) {}
237
238         void convert()
239         {
240             switch (m_typeInfo.baseType())
241             {
242                 case SimulatorResourceModel::ValueType::INTEGER:
243                     return handleByDepth<int>();
244                 case SimulatorResourceModel::ValueType::DOUBLE:
245                     return handleByDepth<double>();
246                 case SimulatorResourceModel::ValueType::BOOLEAN:
247                     return handleByDepth<bool>();
248                 case SimulatorResourceModel::ValueType::STRING:
249                     return handleByDepth<std::string>();
250                 case SimulatorResourceModel::ValueType::RESOURCE_MODEL:
251                     return handleByDepth<SimulatorResourceModel>();
252                 case SimulatorResourceModel::ValueType::VECTOR:
253                 case SimulatorResourceModel::ValueType::UNKNOWN:
254                     break;
255             }
256         }
257
258         SimulatorResourceModel::ValueVariant get()
259         {
260             return std::move(m_result);
261         }
262
263     private:
264         template <typename T>
265         void handleByDepth()
266         {
267             if (0 == m_typeInfo.depth())
268             {
269                 T value;
270                 getValue(m_value, value);
271                 m_result = value;
272             }
273             else if (1 == m_typeInfo.depth())
274             {
275                 std::vector<T> value;
276                 getValue(m_value, value);
277                 m_result = value;
278             }
279             else if (2 == m_typeInfo.depth())
280             {
281                 std::vector<std::vector<T>> value;
282                 getValue(m_value, value);
283                 m_result = value;
284             }
285             else if (3 == m_typeInfo.depth())
286             {
287                 std::vector<std::vector<std::vector<T>>> value;
288                 getValue(m_value, value);
289                 m_result = value;
290             }
291         }
292
293         void getValue(jobject &jValue, int &value)
294         {
295             static jmethodID intValueMID = m_env->GetMethodID(
296                                                gSimulatorClassRefs.integerCls, "intValue", "()I");
297
298             jint temp = m_env->CallIntMethod(jValue, intValueMID);
299             value = temp;
300         }
301
302         void getValue(jobject &jValue, std::vector<int> &value)
303         {
304             jobjectArray array = (jobjectArray) jValue;
305             size_t length = m_env->GetArrayLength(array);
306             for (size_t i = 0; i < length; i++)
307             {
308                 jobject jElement = m_env->GetObjectArrayElement(array, i);
309
310                 int element;
311                 getValue(jElement, element);
312                 value.push_back(element);
313             }
314         }
315
316         void getValue(jobject &jValue, std::vector<std::vector<int>> &value)
317         {
318             jobjectArray array = (jobjectArray) jValue;
319             size_t length = m_env->GetArrayLength(array);
320             for (size_t i = 0; i < length; i++)
321             {
322                 jobject jElement = m_env->GetObjectArrayElement(array, i);
323
324                 std::vector<int> element;
325                 getValue(jElement, element);
326                 value.push_back(element);
327             }
328         }
329
330         void getValue(jobject &jValue, std::vector<std::vector<std::vector<int>>> &value)
331         {
332             jobjectArray array = (jobjectArray) jValue;
333             size_t length = m_env->GetArrayLength(array);
334             for (size_t i = 0; i < length; i++)
335             {
336                 jobject jElement = m_env->GetObjectArrayElement(array, i);
337
338                 std::vector<std::vector<int>> element;
339                 getValue(jElement, element);
340                 value.push_back(element);
341             }
342         }
343
344         void getValue(jobject &jValue, double &value)
345         {
346             static jmethodID doubleValueMID = m_env->GetMethodID(
347                                                   gSimulatorClassRefs.doubleCls, "doubleValue", "()D");
348
349             value = m_env->CallDoubleMethod(jValue, doubleValueMID);
350         }
351
352         void getValue(jobject &jValue, std::vector<double> &value)
353         {
354             jobjectArray array = (jobjectArray) jValue;
355             size_t length = m_env->GetArrayLength(array);
356             for (size_t i = 0; i < length; i++)
357             {
358                 jobject jElement = m_env->GetObjectArrayElement(array, i);
359
360                 double element;
361                 getValue(jElement, element);
362                 value.push_back(element);
363             }
364         }
365
366         void getValue(jobject &jValue, std::vector<std::vector<double>> &value)
367         {
368             jobjectArray array = (jobjectArray) jValue;
369             size_t length = m_env->GetArrayLength(array);
370             for (size_t i = 0; i < length; i++)
371             {
372                 jobject jElement = m_env->GetObjectArrayElement(array, i);
373
374                 std::vector<double> element;
375                 getValue(jElement, element);
376                 value.push_back(element);
377             }
378         }
379
380         void getValue(jobject &jValue, std::vector<std::vector<std::vector<double>>> &value)
381         {
382             jobjectArray array = (jobjectArray) jValue;
383             size_t length = m_env->GetArrayLength(array);
384             for (size_t i = 0; i < length; i++)
385             {
386                 jobject jElement = m_env->GetObjectArrayElement(array, i);
387
388                 std::vector<std::vector<double>> element;
389                 getValue(jElement, element);
390                 value.push_back(element);
391             }
392         }
393
394         void getValue(jobject &jValue, bool &value)
395         {
396             static jmethodID boolValueMID = m_env->GetMethodID(
397                                                 gSimulatorClassRefs.booleanCls, "booleanValue", "()Z");
398
399             value = m_env->CallBooleanMethod(jValue, boolValueMID);
400         }
401
402         void getValue(jobject &jValue, std::vector<bool> &value)
403         {
404             jobjectArray array = (jobjectArray) jValue;
405             size_t length = m_env->GetArrayLength(array);
406             for (size_t i = 0; i < length; i++)
407             {
408                 jobject jElement = m_env->GetObjectArrayElement(array, i);
409
410                 bool element;
411                 getValue(jElement, element);
412                 value.push_back(element);
413             }
414         }
415
416         void getValue(jobject &jValue, std::vector<std::vector<bool>> &value)
417         {
418             jobjectArray array = (jobjectArray) jValue;
419             size_t length = m_env->GetArrayLength(array);
420             for (size_t i = 0; i < length; i++)
421             {
422                 jobject jElement = m_env->GetObjectArrayElement(array, i);
423
424                 std::vector<bool> element;
425                 getValue(jElement, element);
426                 value.push_back(element);
427             }
428         }
429
430         void getValue(jobject &jValue, std::vector<std::vector<std::vector<bool>>> &value)
431         {
432             jobjectArray array = (jobjectArray) jValue;
433             size_t length = m_env->GetArrayLength(array);
434             for (size_t i = 0; i < length; i++)
435             {
436                 jobject jElement = m_env->GetObjectArrayElement(array, i);
437
438                 std::vector<std::vector<bool>> element;
439                 getValue(jElement, element);
440                 value.push_back(element);
441             }
442         }
443
444         void getValue(jobject &jValue, std::string &value)
445         {
446             jstring stringValue = (jstring) jValue;
447             JniString jniValue(m_env, stringValue);
448             value = jniValue.get();
449         }
450
451         void getValue(jobject jValue, std::vector<std::string> &value)
452         {
453             jobjectArray array = (jobjectArray) jValue;
454             size_t length = m_env->GetArrayLength(array);
455             for (size_t i = 0; i < length; i++)
456             {
457                 jobject jElement = m_env->GetObjectArrayElement(array, i);
458
459                 std::string element;
460                 getValue(jElement, element);
461                 value.push_back(element);
462             }
463         }
464
465         void getValue(jobject &jValue, std::vector<std::vector<std::string>> &value)
466         {
467             jobjectArray array = (jobjectArray) jValue;
468             size_t length = m_env->GetArrayLength(array);
469             for (size_t i = 0; i < length; i++)
470             {
471                 jobject jElement = m_env->GetObjectArrayElement(array, i);
472
473                 std::vector<std::string> element;
474                 getValue(jElement, element);
475                 value.push_back(element);
476             }
477         }
478
479         void getValue(jobject &jValue, std::vector<std::vector<std::vector<std::string>>> &value)
480         {
481             jobjectArray array = (jobjectArray) jValue;
482             size_t length = m_env->GetArrayLength(array);
483             for (size_t i = 0; i < length; i++)
484             {
485                 jobject jElement = m_env->GetObjectArrayElement(array, i);
486
487                 std::vector<std::vector<std::string>> element;
488                 getValue(jElement, element);
489                 value.push_back(element);
490             }
491         }
492
493         void getValue(jobject &jValue, SimulatorResourceModel &value)
494         {
495             simulatorResourceModelToCpp(m_env, jValue, value);
496         }
497
498         void getValue(jobject &jValue, std::vector<SimulatorResourceModel> &value)
499         {
500             jobjectArray array = (jobjectArray) jValue;
501             size_t length = m_env->GetArrayLength(array);
502             std::vector<SimulatorResourceModel> result(length);
503             for (size_t i = 0; i < length; i++)
504             {
505                 jobject jElement = m_env->GetObjectArrayElement(array, i);
506
507                 SimulatorResourceModel element;
508                 getValue(jElement, element);
509                 result[i] = element;
510             }
511
512             value = result;
513         }
514
515         void getValue(jobject &jValue, std::vector<std::vector<SimulatorResourceModel>> &value)
516         {
517             jobjectArray array = (jobjectArray) jValue;
518             size_t length = m_env->GetArrayLength(array);
519             std::vector<std::vector<SimulatorResourceModel>> result(length);
520             for (size_t i = 0; i < length; i++)
521             {
522                 jobject jElement = m_env->GetObjectArrayElement(array, i);
523
524                 std::vector<SimulatorResourceModel> childArray;
525                 getValue(jElement, childArray);
526                 value[i] = childArray;
527             }
528
529             value = result;
530         }
531
532         void getValue(jobject &jValue, std::vector<std::vector<std::vector<SimulatorResourceModel>>> &value)
533         {
534             jobjectArray array = (jobjectArray) jValue;
535             size_t length = m_env->GetArrayLength(array);
536             std::vector<std::vector<std::vector<SimulatorResourceModel>>> result(length);
537             for (size_t i = 0; i < length; i++)
538             {
539                 jobject jElement = m_env->GetObjectArrayElement(array, i);
540
541                 std::vector<std::vector<SimulatorResourceModel>> childArray;
542                 getValue(jElement, childArray);
543                 value[i] = childArray;
544             }
545
546             value = result;
547         }
548
549         JNIEnv *m_env;
550         SimulatorResourceModel::TypeInfo &m_typeInfo;
551         jobject &m_value;
552         SimulatorResourceModel::ValueVariant m_result;
553 };
554
555 class JniAttributeValue
556 {
557     public:
558         static jobject toJava(JNIEnv *env, SimulatorResourceModel::Attribute &attribute)
559         {
560             auto value = attribute.getValue();
561             return toJava(env, value);
562         }
563
564         static jobject toJava(JNIEnv *env, SimulatorResourceModel::ValueVariant &value)
565         {
566             ValueConverterJava converter(env);
567             jobject jValue =  boost::apply_visitor(converter, value);
568
569             static jmethodID attrValueCtor = env->GetMethodID(
570                                                  gSimulatorClassRefs.attributeValueCls, "<init>", "(Ljava/lang/Object;)V");
571
572             return env->NewObject(gSimulatorClassRefs.attributeValueCls, attrValueCtor, jValue);
573         }
574
575         static SimulatorResourceModel::ValueVariant toCpp(JNIEnv *env, jobject &jAttributeValue)
576         {
577             static jmethodID getMID = env->GetMethodID(gSimulatorClassRefs.attributeValueCls,
578                                       "get", "()Ljava/lang/Object;");
579
580             SimulatorResourceModel::TypeInfo typeInfo = JniTypeInfo(env).toCpp(jAttributeValue);
581             jobject jValue = env->CallObjectMethod(jAttributeValue, getMID);
582
583             ValueConverterCpp converter(env, typeInfo, jValue);
584             converter.convert();
585             return converter.get();
586         }
587 };
588
589 class JniAttributeProperty
590 {
591     public:
592         static jobject toJava(JNIEnv *env,
593                               SimulatorResourceModel::AttributeProperty &property)
594         {
595             jobject jAttributeProperty = nullptr;
596             if (SimulatorResourceModel::AttributeProperty::Type::RANGE == property.type())
597             {
598                 static jmethodID propertyCtor = env->GetMethodID(
599                                                     gSimulatorClassRefs.attributePropertyCls, "<init>", "(DD)V");
600
601                 jAttributeProperty = env->NewObject(gSimulatorClassRefs.attributePropertyCls, propertyCtor,
602                                                     property.min(), property.max());
603             }
604             else if (SimulatorResourceModel::AttributeProperty::Type::VALUE_SET == property.type())
605             {
606                 static jmethodID propertyCtor = env->GetMethodID(
607                                                     gSimulatorClassRefs.attributePropertyCls, "<init>", "([Lorg/oic/simulator/AttributeValue;)V");
608
609                 jobjectArray jValueSet = env->NewObjectArray(property.valueSetSize(),
610                                          gSimulatorClassRefs.attributeValueCls, nullptr);
611                 int index = 0;
612                 for (auto &value : property.valueSet())
613                 {
614                     jobject jValue = JniAttributeValue::toJava(env, value);
615                     env->SetObjectArrayElement(jValueSet, index++, jValue);
616                 }
617
618                 jAttributeProperty = env->NewObject(gSimulatorClassRefs.attributePropertyCls, propertyCtor,
619                                                     jValueSet);
620             }
621             else
622             {
623                 return jAttributeProperty;
624             }
625
626             // Add child property
627             if (jAttributeProperty && property.getChildProperty())
628             {
629                 SimulatorResourceModel::AttributeProperty childProperty = *(property.getChildProperty());
630                 jobject jChildProperty = JniAttributeProperty::toJava(env,  property);
631                 if (jChildProperty)
632                 {
633                     static jfieldID childPropFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
634                                                    "mChildProperty", "Lorg/oic/simulator/AttributeProperty;");
635                     env->SetObjectField(jAttributeProperty, childPropFID, jChildProperty);
636                 }
637             }
638
639             return jAttributeProperty;
640         }
641
642         static SimulatorResourceModel::AttributeProperty toCpp(JNIEnv *env, jobject jAttributeProperty)
643         {
644             static jfieldID typeFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
645                                       "mType", "Lorg/oic/simulator/AttributeProperty$Type;");
646             static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
647                                      "mMin", "D");
648             static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
649                                      "mMax", "D");
650             static jfieldID valueSetFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
651                                           "mValueSet", "[Lorg/oic/simulator/AttributeValue;");
652             static jfieldID childPropFID = env->GetFieldID(gSimulatorClassRefs.attributePropertyCls,
653                                            "mChildProperty", "Lorg/oic/simulator/AttributeProperty;");
654             static jmethodID ordinalMID = env->GetMethodID(
655                                               gSimulatorClassRefs.attributePropertyTypeCls, "ordinal", "()I");
656
657             SimulatorResourceModel::AttributeProperty attributeProperty;
658             jobject jType = env->GetObjectField(jAttributeProperty, typeFID);
659             jdouble jMin = env->GetDoubleField(jAttributeProperty, minFID);
660             jdouble jMax = env->GetDoubleField(jAttributeProperty, maxFID);
661             jobjectArray jValueSet = (jobjectArray) env->GetObjectField(jAttributeProperty, valueSetFID);
662             jobject jChildProperty = env->GetObjectField(jAttributeProperty, childPropFID);
663
664             int ordinal = env->CallIntMethod(jType, ordinalMID);
665             switch (SimulatorResourceModel::AttributeProperty::Type(ordinal))
666             {
667                 case SimulatorResourceModel::AttributeProperty::Type::RANGE:
668                     {
669                         attributeProperty = SimulatorResourceModel::AttributeProperty(jMin, jMax);
670                     }
671                     break;
672
673                 case SimulatorResourceModel::AttributeProperty::Type::VALUE_SET:
674                     {
675                         std::vector<SimulatorResourceModel::ValueVariant> valueSet;
676                         size_t length = env->GetArrayLength(jValueSet);
677                         for (size_t i = 0; i < length; i++)
678                         {
679                             jobject jAttributeValue = env->GetObjectArrayElement(jValueSet, i);
680                             valueSet.push_back(JniAttributeValue::toCpp(env, jAttributeValue));
681                         }
682
683                         attributeProperty = SimulatorResourceModel::AttributeProperty(valueSet);
684                     }
685                     break;
686             }
687
688             // Set child property
689             if (jChildProperty)
690             {
691                 SimulatorResourceModel::AttributeProperty childProperty =
692                     JniAttributeProperty::toCpp(env, jAttributeProperty);
693                 attributeProperty.setChildProperty(childProperty);
694             }
695
696             return attributeProperty;
697         }
698 };
699
700 static jobject createHashMap(JNIEnv *env)
701 {
702     static jmethodID hashMapCtor = env->GetMethodID(
703                                        gSimulatorClassRefs.hashMapCls, "<init>", "()V");
704     return env->NewObject(gSimulatorClassRefs.hashMapCls, hashMapCtor);
705 }
706
707 static void addEntryToHashMap(JNIEnv *env, jobject mapobj, jobject key, jobject value)
708 {
709     if (!mapobj || !key || !value)
710         return;
711
712     static jmethodID hashMapPutMethod = env->GetMethodID(gSimulatorClassRefs.hashMapCls,
713                                         "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
714     env->CallObjectMethod(mapobj, hashMapPutMethod, key, value);
715 }
716
717 jobject simulatorResourceModelToJava(JNIEnv *env, SimulatorResourceModel &resModel)
718 {
719     jobject attributesMap = createHashMap(env);
720     jobject propertiesMap = createHashMap(env);
721     if (!attributesMap || !propertiesMap)
722         return nullptr;
723
724     for (auto &attributeEntry : resModel.getAttributes())
725     {
726         jstring jAttrName = env->NewStringUTF((attributeEntry.first).c_str());
727         jobject jAttributeValue = JniAttributeValue::toJava(env, attributeEntry.second);
728         addEntryToHashMap(env, attributesMap, jAttrName, jAttributeValue);
729
730         jobject jAttributeProperty = JniAttributeProperty::toJava(env, attributeEntry.second.getProperty());
731         if (jAttributeProperty)
732             addEntryToHashMap(env, propertiesMap, jAttrName, jAttributeProperty);
733     }
734
735     static jmethodID simulatorResourceModelCtor = env->GetMethodID(
736                 gSimulatorClassRefs.simulatorResourceModelCls, "<init>", "(Ljava/util/Map;Ljava/util/Map;)V");
737
738     return env->NewObject(gSimulatorClassRefs.simulatorResourceModelCls,
739                           simulatorResourceModelCtor, attributesMap, propertiesMap);
740 }
741
742 jobject simulatorResourceAttributeToJava(JNIEnv *env, SimulatorResourceModel::Attribute &attribute)
743 {
744     static jmethodID simulatorResAttributeCtor = env->GetMethodID(
745                 gSimulatorClassRefs.simulatorResourceAttributeCls, "<init>",
746                 "(Ljava/lang/String;Lorg/oic/simulator/AttributeValue;Lorg/oic/simulator/AttributeProperty;)V");
747
748     jstring jAttrName = env->NewStringUTF(attribute.getName().c_str());
749     jobject jAttributeValue = JniAttributeValue::toJava(env, attribute);
750     jobject jAttributeProperty = JniAttributeProperty::toJava(env, attribute.getProperty());
751
752     return env->NewObject(gSimulatorClassRefs.simulatorResourceAttributeCls,
753                           simulatorResAttributeCtor, jAttrName, jAttributeValue, jAttributeProperty);
754 }
755
756 bool simulatorResourceModelToCpp(JNIEnv *env, jobject jResModel, SimulatorResourceModel &resModel)
757 {
758     if (!jResModel)
759         return false;
760
761     static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceModelCls,
762                                 "mValues", "Ljava/util/Map;");
763     static jfieldID propertiesFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceModelCls,
764                                     "mProperties", "Ljava/util/Map;");
765     static jmethodID entrySetMID = env->GetMethodID(gSimulatorClassRefs.mapCls, "entrySet",
766                                    "()Ljava/util/Set;");
767     static jmethodID iteratorMID = env->GetMethodID(gSimulatorClassRefs.setCls, "iterator",
768                                    "()Ljava/util/Iterator;");
769     static jmethodID hasNextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls, "hasNext",
770                                   "()Z");
771     static jmethodID nextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls, "next",
772                                "()Ljava/lang/Object;");
773     static jmethodID getKeyMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls, "getKey",
774                                  "()Ljava/lang/Object;");
775     static jmethodID getValueMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls, "getValue",
776                                    "()Ljava/lang/Object;");
777
778     jobject jValues = env->GetObjectField(jResModel, valuesFID);
779     jobject jProperties = env->GetObjectField(jResModel, propertiesFID);
780
781     if (jValues)
782     {
783         jobject entrySet = env->CallObjectMethod(jValues, entrySetMID);
784         jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
785         if (entrySet && iterator)
786         {
787             while (env->CallBooleanMethod(iterator, hasNextMID))
788             {
789                 jobject entry = env->CallObjectMethod(iterator, nextMID);
790                 jstring key = (jstring) env->CallObjectMethod(entry, getKeyMID);
791                 jobject value = env->CallObjectMethod(entry, getValueMID);
792                 resModel.add(JniString(env, key).get(), JniAttributeValue::toCpp(env, value));
793
794                 env->DeleteLocalRef(entry);
795                 env->DeleteLocalRef(key);
796                 env->DeleteLocalRef(value);
797             }
798         }
799     }
800
801     if (jProperties)
802     {
803         jobject entrySet = env->CallObjectMethod(jProperties, entrySetMID);
804         jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
805         if (entrySet && iterator)
806         {
807             while (env->CallBooleanMethod(iterator, hasNextMID))
808             {
809                 jobject entry = env->CallObjectMethod(iterator, nextMID);
810                 jstring key = (jstring) env->CallObjectMethod(entry, getKeyMID);
811                 jobject value = env->CallObjectMethod(entry, getValueMID);
812                 resModel.setAttributeProperty(JniString(env, key).get(),
813                                               JniAttributeProperty::toCpp(env, value));
814
815                 env->DeleteLocalRef(entry);
816                 env->DeleteLocalRef(key);
817                 env->DeleteLocalRef(value);
818             }
819         }
820     }
821
822     return true;
823 }
824
825 bool simulatorResourceAttributeToCpp(JNIEnv *env, jobject jAttribute,
826                                      SimulatorResourceModel::Attribute &attribute)
827 {
828     if (!jAttribute)
829         return false;
830
831     static jfieldID nameFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceAttributeCls,
832                               "mName", "Ljava/lang/String;");
833     static jfieldID valueFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceAttributeCls,
834                                "mValue", "Lorg/oic/simulator/AttributeValue;");
835     static jfieldID propertyFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceAttributeCls,
836                                   "mProperty", "Lorg/oic/simulator/AttributeProperty;");
837
838     jstring jAttributeName = (jstring) env->GetObjectField(jAttribute, nameFID);
839     jobject jAttributeValue = env->GetObjectField(jAttribute, valueFID);
840     jobject jAttributeProperty = env->GetObjectField(jAttribute, propertyFID);
841
842     if (!jAttributeName || !jAttributeValue)
843         return false;
844
845     JniString attrName(env, jAttributeName);
846     SimulatorResourceModel::ValueVariant value = JniAttributeValue::toCpp(env, jAttributeValue);
847
848     attribute.setName(attrName.get());
849     attribute.setValue(value);
850     if (jAttributeProperty)
851     {
852         SimulatorResourceModel::AttributeProperty property = JniAttributeProperty::toCpp(env,
853                 jAttributeProperty);
854         attribute.setProperty(property);
855     }
856
857     return true;
858 }
859
860 bool AttributeValueToCpp(JNIEnv *env, jobject jAttributeValue,
861                          SimulatorResourceModel::ValueVariant &value)
862 {
863     if (!jAttributeValue)
864         return false;
865
866     value = JniAttributeValue::toCpp(env, jAttributeValue);
867     return true;
868 }
869