Merge branch 'upstream' into tizen
[platform/upstream/iotivity.git] / service / simulator / java / jni / simulator_resource_model_schema_jni.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 "simulator_resource_model_schema_jni.h"
22 #include "simulator_utils_jni.h"
23 #include "jni_string.h"
24
25 static AttributeProperty::Type getType(JNIEnv *env, jobject &jProperty)
26 {
27     static jmethodID getTypeMID = env->GetMethodID(
28                                       gSimulatorClassRefs.attributePropertyCls, "getType",
29                                       "()Lorg/oic/simulator/AttributeProperty$Type;");
30
31     static jmethodID ordinalMID = env->GetMethodID(
32                                       gSimulatorClassRefs.attributePropertyTypeCls, "ordinal", "()I");
33
34     jobject jType = env->CallObjectMethod(jProperty, getTypeMID);
35     int ordinal = env->CallIntMethod(jType, ordinalMID);
36     return AttributeProperty::Type(ordinal);
37 }
38
39 class JniIntegerProperty
40 {
41     public:
42         static jobject toJava(JNIEnv *env, const std::shared_ptr<IntegerProperty> &property)
43         {
44             if (!property)
45                 return nullptr;
46
47             // Create Java IntegerProperty.Builder object
48             jobject jPropertyBuilder = nullptr;
49             static jmethodID builderCtor = env->GetMethodID(
50                                                gSimulatorClassRefs.integerPropertyBuilderCls, "<init>", "()V");
51             jPropertyBuilder = env->NewObject(gSimulatorClassRefs.integerPropertyBuilderCls, builderCtor);
52
53             // Set default value
54             static jmethodID setDefaultValueMID = env->GetMethodID(
55                     gSimulatorClassRefs.integerPropertyBuilderCls, "setDefaultValue", "(I)V");
56             env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
57
58             // Set Range or enum value set
59             if (property->hasRange())
60             {
61                 int min = 0;
62                 int max = 0;
63                 property->getRange(min, max);
64
65                 static jmethodID setRangeMID = env->GetMethodID(
66                                                    gSimulatorClassRefs.integerPropertyBuilderCls, "setRange", "(II)V");
67                 env->CallVoidMethod(jPropertyBuilder, setRangeMID, min, max);
68             }
69             else if (property->hasValues())
70             {
71                 std::vector<int> values;
72                 property->getValues(values);
73                 jintArray jIntArray = env->NewIntArray(values.size());
74                 env->SetIntArrayRegion(jIntArray, 0, values.size(), reinterpret_cast<const jint *>(&values[0]));
75
76                 static jmethodID setValuesMID = env->GetMethodID(
77                                                     gSimulatorClassRefs.integerPropertyBuilderCls, "setValues", "([I)V");
78                 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jIntArray);
79             }
80
81             // Create Java IntegerProperty object
82             static jmethodID buildMID = env->GetMethodID(
83                                             gSimulatorClassRefs.integerPropertyBuilderCls, "build", "()Lorg/oic/simulator/IntegerProperty;");
84             return env->CallObjectMethod(jPropertyBuilder, buildMID);
85         }
86
87         static std::shared_ptr<IntegerProperty> toCpp(JNIEnv *env, jobject &jProperty)
88         {
89             static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
90                                               "mDefaultValue", "I");
91             static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
92                                           "mHasRange", "Z");
93
94             jint defaultValue = env->GetIntField(jProperty, defaultValueFID);
95             jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
96
97             std::shared_ptr<IntegerProperty> integerProperty =
98                 IntegerProperty::build(defaultValue);
99
100             if (hasRange)
101             {
102                 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
103                                          "mMin", "I");
104                 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
105                                          "mMax", "I");
106
107                 jint min = env->GetIntField(jProperty, minFID);
108                 jint max = env->GetIntField(jProperty, maxFID);
109                 integerProperty->setRange(min, max);
110             }
111             else
112             {
113                 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
114                                             "mValues", "[I");
115                 jintArray jValues = (jintArray) env->GetObjectField(jProperty, valuesFID);
116                 if (jValues)
117                 {
118                     std::vector<int> values;
119                     jint *jIntArray = env->GetIntArrayElements(jValues, NULL);
120                     size_t length = env->GetArrayLength(jValues);
121                     for (size_t index = 0; index < length; index++)
122                     {
123                         values.push_back(jIntArray[index]);
124                     }
125                     integerProperty->setValues(values);
126
127                     env->ReleaseIntArrayElements(jValues, jIntArray, 0);
128                 }
129             }
130
131             return integerProperty;
132         }
133 };
134
135 class JniDoubleProperty
136 {
137     public:
138         static jobject toJava(JNIEnv *env, const std::shared_ptr<DoubleProperty> &property)
139         {
140             if (!property)
141                 return nullptr;
142
143             // Create Java DoubleProperty.Builder object
144             jobject jPropertyBuilder = nullptr;
145             static jmethodID builderCtor = env->GetMethodID(
146                                                gSimulatorClassRefs.doublePropertyBuilderCls, "<init>", "()V");
147             jPropertyBuilder = env->NewObject(gSimulatorClassRefs.doublePropertyBuilderCls, builderCtor);
148
149             // Set default value
150             static jmethodID setDefaultValueMID = env->GetMethodID(
151                     gSimulatorClassRefs.doublePropertyBuilderCls, "setDefaultValue", "(D)V");
152             env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
153
154             // Set Range or enum value set
155             if (property->hasRange())
156             {
157                 double min = 0.0;
158                 double max = 0.0;
159                 property->getRange(min, max);
160
161                 static jmethodID setRangeMID = env->GetMethodID(
162                                                    gSimulatorClassRefs.doublePropertyBuilderCls, "setRange", "(DD)V");
163                 env->CallVoidMethod(jPropertyBuilder, setRangeMID, min, max);
164             }
165             else if (property->hasValues())
166             {
167                 std::vector<double> values;
168                 property->getValues(values);
169                 jdoubleArray jDoubleArray = env->NewDoubleArray(values.size());
170                 env->SetDoubleArrayRegion(jDoubleArray, 0, values.size(),
171                                           reinterpret_cast<const jdouble *>(&values[0]));
172
173                 static jmethodID setValuesMID = env->GetMethodID(
174                                                     gSimulatorClassRefs.doublePropertyBuilderCls, "setValues", "([D)V");
175                 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jDoubleArray);
176             }
177
178             // Create Java DoubleProperty object
179             static jmethodID buildMID = env->GetMethodID(
180                                             gSimulatorClassRefs.doublePropertyBuilderCls, "build", "()Lorg/oic/simulator/DoubleProperty;");
181             return env->CallObjectMethod(jPropertyBuilder, buildMID);
182         }
183
184         static std::shared_ptr<DoubleProperty> toCpp(JNIEnv *env, jobject &jProperty)
185         {
186             static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
187                                               "mDefaultValue", "D");
188             static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
189                                           "mHasRange", "Z");
190
191             jdouble defaultValue = env->GetDoubleField(jProperty, defaultValueFID);
192             jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
193
194             std::shared_ptr<DoubleProperty> doubleProperty =
195                 DoubleProperty::build(defaultValue);
196
197             if (hasRange)
198             {
199                 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
200                                          "mMin", "D");
201                 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
202                                          "mMax", "D");
203
204                 jdouble min = env->GetDoubleField(jProperty, minFID);
205                 jdouble max = env->GetDoubleField(jProperty, maxFID);
206                 doubleProperty->setRange(min, max);
207             }
208             else
209             {
210                 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
211                                             "mValues", "[D");
212                 jdoubleArray jValues = (jdoubleArray) env->GetObjectField(jProperty, valuesFID);
213                 if (jValues)
214                 {
215                     std::vector<double> values;
216                     jdouble *jDoubleArray = env->GetDoubleArrayElements(jValues, NULL);
217                     size_t length = env->GetArrayLength(jValues);
218                     for (size_t index = 0; index < length; index++)
219                     {
220                         values.push_back(jDoubleArray[index]);
221                     }
222                     doubleProperty->setValues(values);
223
224                     env->ReleaseDoubleArrayElements(jValues, jDoubleArray, 0);
225                 }
226             }
227
228             return doubleProperty;
229         }
230 };
231
232 class JniBooleanProperty
233 {
234     public:
235         static jobject toJava(JNIEnv *env, const std::shared_ptr<BooleanProperty> &property)
236         {
237             if (!property)
238                 return nullptr;
239
240             // Create Java BooleanProperty.Builder object
241             jobject jPropertyBuilder = nullptr;
242             static jmethodID builderCtor = env->GetMethodID(
243                                                gSimulatorClassRefs.booleanPropertyBuilderCls, "<init>", "()V");
244             jPropertyBuilder = env->NewObject(gSimulatorClassRefs.booleanPropertyBuilderCls, builderCtor);
245
246             // Set default value
247             static jmethodID setDefaultValueMID = env->GetMethodID(
248                     gSimulatorClassRefs.booleanPropertyBuilderCls, "setDefaultValue", "(Z)V");
249             env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
250
251             // Create Java BooleanProperty object
252             static jmethodID buildMID = env->GetMethodID(
253                                             gSimulatorClassRefs.booleanPropertyBuilderCls, "build", "()Lorg/oic/simulator/BooleanProperty;");
254             return env->CallObjectMethod(jPropertyBuilder, buildMID);
255         }
256
257         static std::shared_ptr<BooleanProperty> toCpp(JNIEnv *env, jobject &jProperty)
258         {
259             static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.booleanPropertyCls,
260                                               "mDefaultValue", "Z");
261
262             jboolean defaultValue = env->GetBooleanField(jProperty, defaultValueFID);
263             return BooleanProperty::build(defaultValue);
264         }
265 };
266
267 class JniStringProperty
268 {
269     public:
270         static jobject toJava(JNIEnv *env, const std::shared_ptr<StringProperty> &property)
271         {
272             if (!property)
273                 return nullptr;
274
275             // Create Java StringProperty.Builder object
276             jobject jPropertyBuilder = nullptr;
277             static jmethodID builderCtor = env->GetMethodID(
278                                                gSimulatorClassRefs.stringPropertyBuilderCls, "<init>", "()V");
279             jPropertyBuilder = env->NewObject(gSimulatorClassRefs.stringPropertyBuilderCls, builderCtor);
280
281             // Set default value
282             static jmethodID setDefaultValueMID = env->GetMethodID(
283                     gSimulatorClassRefs.stringPropertyBuilderCls, "setDefaultValue", "(Ljava/lang/String;)V");
284             jstring jDefaultValue = env->NewStringUTF(property->getDefaultValue().c_str());
285             env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, jDefaultValue);
286
287             // Set Range or enum value set
288             if (property->hasRange())
289             {
290                 size_t min = 0;
291                 size_t max = 0;
292                 property->getRange(min, max);
293
294                 static jmethodID setRangeMID = env->GetMethodID(
295                                                    gSimulatorClassRefs.stringPropertyBuilderCls, "setRange", "(II)V");
296                 env->CallVoidMethod(jPropertyBuilder, setRangeMID, static_cast<jint>(min),
297                                     static_cast<jint>(max));
298             }
299             else if (property->hasValues())
300             {
301                 std::vector<std::string> values;
302                 property->getValues(values);
303                 jobjectArray jStringArray = env->NewObjectArray(values.size(), gSimulatorClassRefs.stringCls,
304                                             nullptr);
305
306                 for (size_t index = 0; index < values.size(); index++)
307                 {
308                     jstring element = env->NewStringUTF(values[index].c_str());
309                     env->SetObjectArrayElement(jStringArray, index, element);
310                 }
311
312                 static jmethodID setValuesMID = env->GetMethodID(
313                                                     gSimulatorClassRefs.stringPropertyBuilderCls, "setValues", "([Ljava/lang/String;)V");
314                 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jStringArray);
315             }
316
317             // Create Java StringProperty object
318             static jmethodID buildMID = env->GetMethodID(
319                                             gSimulatorClassRefs.stringPropertyBuilderCls, "build", "()Lorg/oic/simulator/StringProperty;");
320             return env->CallObjectMethod(jPropertyBuilder, buildMID);
321         }
322
323         static std::shared_ptr<StringProperty> toCpp(JNIEnv *env, jobject &jProperty)
324         {
325             static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
326                                               "mDefaultValue", "Ljava/lang/String;");
327             static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
328                                           "mHasRange", "Z");
329
330             jstring defaultValue = (jstring) env->GetObjectField(jProperty, defaultValueFID);
331             jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
332
333             std::shared_ptr<StringProperty> stringProperty =
334                 StringProperty::build(JniString(env, defaultValue).get());
335
336             if (hasRange)
337             {
338                 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
339                                          "mMin", "I");
340                 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
341                                          "mMax", "I");
342
343                 jint min = env->GetIntField(jProperty, minFID);
344                 jint max = env->GetIntField(jProperty, maxFID);
345                 if (min >= 0 && max >= 0)
346                     stringProperty->setRange(static_cast<size_t>(min), static_cast<size_t>(max));
347             }
348             else
349             {
350                 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
351                                             "mValues", "[Ljava/lang/String;");
352                 jobjectArray jValues = (jobjectArray) env->GetObjectField(jProperty, valuesFID);
353                 if (jValues)
354                 {
355                     std::vector<std::string> values;
356                     size_t length = env->GetArrayLength(jValues);
357                     for (size_t index = 0; index < length; index++)
358                     {
359                         jstring jValue = (jstring) env->GetObjectArrayElement(jValues, index);
360                         values.push_back(JniString(env, jValue).get());
361                     }
362                     stringProperty->setValues(values);
363                 }
364             }
365
366             return stringProperty;
367         }
368 };
369
370 class JniArrayProperty
371 {
372     public:
373         static jobject toJava(JNIEnv *env, const std::shared_ptr<ArrayProperty> &property)
374         {
375             if (!property)
376                 return nullptr;
377
378             // Create Java ArrayProperty.Builder object
379             jobject jPropertyBuilder = nullptr;
380             static jmethodID builderCtor = env->GetMethodID(
381                                                gSimulatorClassRefs.arrayPropertyBuilderCls, "<init>", "()V");
382             jPropertyBuilder = env->NewObject(gSimulatorClassRefs.arrayPropertyBuilderCls, builderCtor);
383
384             // Set variable size propety
385             if (property->isVariable())
386             {
387                 static jmethodID setVariableMID = env->GetMethodID(
388                                                       gSimulatorClassRefs.arrayPropertyBuilderCls, "setVariableSize", "(Z)V");
389                 env->CallVoidMethod(jPropertyBuilder, setVariableMID, property->isVariable());
390             }
391
392             // Set unique propety
393             if (property->isUnique())
394             {
395                 static jmethodID setUniqueMID = env->GetMethodID(
396                                                     gSimulatorClassRefs.arrayPropertyBuilderCls, "setUnique", "(Z)V");
397                 env->CallVoidMethod(jPropertyBuilder, setUniqueMID, property->isUnique());
398             }
399
400             // Set range property
401             if (property->hasRange())
402             {
403                 size_t min = property->getMinItems();
404                 size_t max = property->getMaxItems();
405
406                 static jmethodID setRangeMID = env->GetMethodID(
407                                                    gSimulatorClassRefs.arrayPropertyBuilderCls, "setRange", "(II)V");
408                 env->CallVoidMethod(jPropertyBuilder, setRangeMID, static_cast<jint>(min),
409                                     static_cast<jint>(max));
410             }
411
412             // Set element property
413             jobject jElementProperty = AttributePropertyToJava(env, property->getElementProperty());
414             static jmethodID setElementPropertyMID = env->GetMethodID(
415                         gSimulatorClassRefs.arrayPropertyBuilderCls, "setElementProperty",
416                         "(Lorg/oic/simulator/AttributeProperty;)V");
417             env->CallVoidMethod(jPropertyBuilder, setElementPropertyMID, jElementProperty);
418
419             // Create Java ArrayProperty object
420             static jmethodID buildMID = env->GetMethodID(
421                                             gSimulatorClassRefs.arrayPropertyBuilderCls, "build", "()Lorg/oic/simulator/ArrayProperty;");
422             return env->CallObjectMethod(jPropertyBuilder, buildMID);
423         }
424
425         static std::shared_ptr<ArrayProperty> toCpp(JNIEnv *env, jobject &jProperty)
426         {
427             static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
428                                           "mHasRange", "Z");
429             static jfieldID variableFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
430                                           "mIsVariableSize", "Z");
431             static jfieldID uniqueFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
432                                         "mIsUnique", "Z");
433             static jfieldID elementPropertyFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
434                                                  "mElementProperty", "Lorg/oic/simulator/AttributeProperty;");
435
436             jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
437             jboolean isVariable = env->GetBooleanField(jProperty, variableFID);
438             jboolean isUnique = env->GetBooleanField(jProperty, uniqueFID);
439             jobject jElementProperty = env->GetObjectField(jProperty, elementPropertyFID);
440
441             std::shared_ptr<ArrayProperty> arrayProperty = ArrayProperty::build();
442
443             arrayProperty->setVariable(isVariable);
444             arrayProperty->setUnique(isUnique);
445
446             if (hasRange)
447             {
448                 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
449                                          "mMin", "I");
450                 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
451                                          "mMax", "I");
452
453                 jint min = env->GetIntField(jProperty, minFID);
454                 jint max = env->GetIntField(jProperty, maxFID);
455                 if (min >= 0 && max >= 0)
456                     arrayProperty->setRange(static_cast<size_t>(min), static_cast<size_t>(max));
457             }
458
459             if (jElementProperty)
460             {
461                 arrayProperty->setElementProperty(AttributePropertyToCpp(env, jElementProperty));
462             }
463
464             return arrayProperty;
465         }
466 };
467
468 class JniModelProperty
469 {
470     public:
471         static jobject toJava(JNIEnv *env, const std::shared_ptr<ModelProperty> &property)
472         {
473             if (!property)
474                 return nullptr;
475
476             // Create Java ModelProperty object
477             jobject jModelProperty = nullptr;
478             static jmethodID modelPropertyCtor = env->GetMethodID(
479                     gSimulatorClassRefs.modelPropertyCls, "<init>", "()V");
480             jModelProperty = env->NewObject(gSimulatorClassRefs.modelPropertyCls, modelPropertyCtor);
481
482             // Set child propeties
483             for (auto &propertyEntry : property->getChildProperties())
484             {
485                 jstring jAttrName = env->NewStringUTF(propertyEntry.first.c_str());
486                 jobject jProperty = AttributePropertyToJava(env, propertyEntry.second);
487                 jboolean required = property->isRequired(propertyEntry.first);
488
489                 static jmethodID addMID = env->GetMethodID(
490                                               gSimulatorClassRefs.modelPropertyCls, "add",
491                                               "(Ljava/lang/String;Lorg/oic/simulator/AttributeProperty;Z)Z");
492                 env->CallBooleanMethod(jModelProperty, addMID, jAttrName, jProperty, required);
493             }
494
495             return jModelProperty;
496         }
497
498         static std::shared_ptr<ModelProperty> toCpp(JNIEnv *env, jobject &jProperty)
499         {
500             static jfieldID childPropertiesFID = env->GetFieldID(gSimulatorClassRefs.modelPropertyCls,
501                                                  "mChildProperties", "Ljava/util/Map;");
502             static jmethodID isRequiredMID = env->GetMethodID(gSimulatorClassRefs.modelPropertyCls,
503                                              "isRequired", "()Z");
504             static jmethodID entrySetMID = env->GetMethodID(gSimulatorClassRefs.mapCls,
505                                            "entrySet", "()Ljava/util/Set;");
506             static jmethodID iteratorMID = env->GetMethodID(gSimulatorClassRefs.setCls,
507                                            "iterator", "()Ljava/util/Iterator;");
508             static jmethodID hasNextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls,
509                                           "hasNext", "()Z");
510             static jmethodID nextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls,
511                                        "next", "()Ljava/lang/Object;");
512             static jmethodID getKeyMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls,
513                                          "getKey", "()Ljava/lang/Object;");
514             static jmethodID getValueMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls,
515                                            "getValue", "()Ljava/lang/Object;");
516
517             std::shared_ptr<ModelProperty> modelProperty = ModelProperty::build();
518             jobject jChildProperties = env->GetObjectField(jProperty, childPropertiesFID);
519             if (jChildProperties)
520             {
521                 jobject entrySet = env->CallObjectMethod(jChildProperties, entrySetMID);
522                 jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
523                 if (entrySet && iterator)
524                 {
525                     while (env->CallBooleanMethod(iterator, hasNextMID))
526                     {
527                         jobject entry = env->CallObjectMethod(iterator, nextMID);
528                         jstring key = (jstring) env->CallObjectMethod(entry, getKeyMID);
529                         jobject value = env->CallObjectMethod(entry, getValueMID);
530                         jboolean isRequired = env->CallBooleanMethod(jProperty, isRequiredMID, key);
531
532                         modelProperty->add(JniString(env, key).get(),
533                                            AttributePropertyToCpp(env, value), isRequired);
534
535                         env->DeleteLocalRef(entry);
536                         env->DeleteLocalRef(key);
537                         env->DeleteLocalRef(value);
538                     }
539                 }
540             }
541
542             return modelProperty;
543         }
544 };
545
546 jobject AttributePropertyToJava(JNIEnv *env,
547                                 const std::shared_ptr<AttributeProperty> &property)
548 {
549     if (!property)
550         return nullptr;
551
552     if (property->isInteger())
553     {
554         return JniIntegerProperty::toJava(env, property->asInteger());
555     }
556     else if (property->isDouble())
557     {
558         return JniDoubleProperty::toJava(env, property->asDouble());
559     }
560     else if (property->isBoolean())
561     {
562         return JniBooleanProperty::toJava(env, property->asBoolean());
563     }
564     else if (property->isString())
565     {
566         return JniStringProperty::toJava(env, property->asString());
567     }
568     else if (property->isArray())
569     {
570         return JniArrayProperty::toJava(env, property->asArray());
571     }
572     else if (property->isModel())
573     {
574         return JniModelProperty::toJava(env, property->asModel());
575     }
576
577     return nullptr; // Control should never reach here
578 }
579
580 std::shared_ptr<AttributeProperty> AttributePropertyToCpp(JNIEnv *env,
581         jobject &jProperty)
582 {
583     if (!jProperty)
584         return nullptr;
585
586     switch (getType(env, jProperty))
587     {
588         case AttributeProperty::Type::INTEGER:
589             return JniIntegerProperty::toCpp(env, jProperty);
590
591         case AttributeProperty::Type::DOUBLE:
592             return JniDoubleProperty::toCpp(env, jProperty);
593
594         case AttributeProperty::Type::BOOLEAN:
595             return JniBooleanProperty::toCpp(env, jProperty);
596
597         case AttributeProperty::Type::STRING:
598             return JniStringProperty::toCpp(env, jProperty);
599
600         case AttributeProperty::Type::ARRAY:
601             return JniArrayProperty::toCpp(env, jProperty);
602
603         case AttributeProperty::Type::MODEL:
604             return JniModelProperty::toCpp(env, jProperty);
605     }
606
607     return nullptr; // Control should never reach here
608 }
609