Imported Upstream version 1.1.0
[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_utils_jni.h"
23 #include "jni_string.h"
24 #include "jni_map.h"
25
26 class JniTypeInfo
27 {
28     public:
29         JniTypeInfo(JNIEnv *env) : m_env(env) {}
30
31         SimulatorResourceModel::TypeInfo toCpp(jobject jAttributeValue)
32         {
33             static jmethodID typeInfoMID = m_env->GetMethodID(gSimulatorClassRefs.attributeValueCls,
34                                            "typeInfo", "()Lorg/oic/simulator/AttributeValue$TypeInfo;");
35             static jfieldID typeFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
36                                       "mType", "Lorg/oic/simulator/AttributeValue$ValueType;");
37             static jfieldID baseTypeFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
38                                           "mBaseType", "Lorg/oic/simulator/AttributeValue$ValueType;");
39             static jfieldID depthFID = m_env->GetFieldID(gSimulatorClassRefs.attributeTypeInfoCls,
40                                        "mDepth", "I");
41
42             jobject jTypeInfo = m_env->CallObjectMethod(jAttributeValue, typeInfoMID);
43             jobject jType = m_env->GetObjectField(jTypeInfo, typeFID);
44             jobject jBaseType = m_env->GetObjectField(jTypeInfo, baseTypeFID);
45             jint jDepth = m_env->GetIntField(jTypeInfo, depthFID);
46
47             return SimulatorResourceModel::TypeInfo(getValueType(jType),
48                                                     getValueType(jBaseType), jDepth);
49         }
50
51     private:
52         AttributeValueType getValueType(jobject jValueType)
53         {
54             static jmethodID ordinalMID = m_env->GetMethodID(
55                                               gSimulatorClassRefs.attributeValueTypeCls, "ordinal", "()I");
56
57             int ordinal = m_env->CallIntMethod(jValueType, ordinalMID);
58             return AttributeValueType(ordinal);
59         }
60
61         JNIEnv *m_env;
62 };
63
64 class ValueConverterJava : public boost::static_visitor<jobject>
65 {
66     public:
67         ValueConverterJava(JNIEnv *env) : m_env(env) {}
68
69         jobject operator ()(const int &value)
70         {
71             static jmethodID integerCtor =
72                 m_env->GetMethodID(gSimulatorClassRefs.integerCls, "<init>", "(I)V");
73             return m_env->NewObject(gSimulatorClassRefs.integerCls,
74                                     integerCtor, value);
75         }
76
77         jobject operator ()(const double &value)
78         {
79             static jmethodID doubleCtor =
80                 m_env->GetMethodID(gSimulatorClassRefs.doubleCls, "<init>", "(D)V");
81             return m_env->NewObject(gSimulatorClassRefs.doubleCls,
82                                     doubleCtor, value);
83         }
84
85         jobject operator ()(const bool &value)
86         {
87             static jmethodID booleanCtor =
88                 m_env->GetMethodID(gSimulatorClassRefs.booleanCls, "<init>", "(Z)V");
89             return m_env->NewObject(gSimulatorClassRefs.booleanCls,
90                                     booleanCtor, value);
91         }
92
93         jobject operator ()(const std::string &value)
94         {
95             jstring stringValue = m_env->NewStringUTF(value.c_str());
96             return static_cast<jobject>(stringValue);
97         }
98
99         jobject operator ()(const SimulatorResourceModel &value)
100         {
101             return SimulatorResourceModelToJava(m_env, const_cast<SimulatorResourceModel &>(value));
102         }
103
104         template <typename T>
105         jobject operator ()(const std::vector<T> &values)
106         {
107             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
108             if (!jArray)
109                 return nullptr;
110
111             for (size_t index = 0; index < values.size(); index++)
112             {
113                 jobject element = operator()(values[index]);
114                 m_env->SetObjectArrayElement(jArray, index, element);
115             }
116
117             return jArray;
118         }
119
120         template <typename T>
121         jobject operator ()(const std::vector<std::vector<T>> &values)
122         {
123             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
124             if (!jArray)
125                 return nullptr;
126
127             for (size_t index = 0; index < values.size(); index++)
128             {
129                 jobject element = operator()(values[index]);
130                 m_env->SetObjectArrayElement(jArray, index, element);
131             }
132
133             return jArray;
134         }
135
136         template <typename T>
137         jobject operator ()(const std::vector<std::vector<std::vector<T>>> &values)
138         {
139             jobjectArray jArray = m_env->NewObjectArray(values.size(), getClass(values), nullptr);
140             if (!jArray)
141                 return nullptr;
142
143             for (size_t index = 0; index < values.size(); index++)
144             {
145                 jobject element = operator()(values[index]);
146                 m_env->SetObjectArrayElement(jArray, index, element);
147             }
148
149             return jArray;
150         }
151
152     private:
153         jclass getClass(const std::vector<int> &)
154         {
155             return gSimulatorClassRefs.integerCls;
156         }
157
158         jclass getClass(const std::vector<std::vector<int>> &)
159         {
160             return gSimulatorClassRefs.integer1DArrayCls;
161         }
162
163         jclass getClass(const std::vector<std::vector<std::vector<int>>> &)
164         {
165             return gSimulatorClassRefs.integer2DArrayCls;
166         }
167
168         jclass getClass(const std::vector<double> &)
169         {
170             return gSimulatorClassRefs.doubleCls;
171         }
172
173         jclass getClass(const std::vector<std::vector<double>> &)
174         {
175             return gSimulatorClassRefs.double1DArrayCls;
176         }
177
178         jclass getClass(const std::vector<std::vector<std::vector<double>>> &)
179         {
180             return gSimulatorClassRefs.double2DArrayCls;
181         }
182
183         jclass getClass(const std::vector<bool> &)
184         {
185             return gSimulatorClassRefs.booleanCls;
186         }
187
188         jclass getClass(const std::vector<std::vector<bool>> &)
189         {
190             return gSimulatorClassRefs.boolean1DArrayCls;
191         }
192
193         jclass getClass(const std::vector<std::vector<std::vector<bool>>> &)
194         {
195             return gSimulatorClassRefs.boolean2DArrayCls;
196         }
197
198         jclass getClass(const std::vector<std::string> &)
199         {
200             return gSimulatorClassRefs.stringCls;
201         }
202
203         jclass getClass(const std::vector<std::vector<std::string>> &)
204         {
205             return gSimulatorClassRefs.string1DArrayCls;
206         }
207
208         jclass getClass(const std::vector<std::vector<std::vector<std::string>>> &)
209         {
210             return gSimulatorClassRefs.string2DArrayCls;
211         }
212
213         jclass getClass(const std::vector<SimulatorResourceModel> &)
214         {
215             return gSimulatorClassRefs.simulatorResourceModelCls;
216         }
217
218         jclass getClass(const std::vector<std::vector<SimulatorResourceModel>> &)
219         {
220             return gSimulatorClassRefs.simulatorResModel1DArrayCls;
221         }
222
223         jclass getClass(const std::vector<std::vector<std::vector<SimulatorResourceModel>>> &)
224         {
225             return gSimulatorClassRefs.simulatorResModel2DArrayCls;
226         }
227
228         JNIEnv *m_env;
229 };
230
231 class ValueConverterCpp
232 {
233     public:
234         ValueConverterCpp(JNIEnv *env, SimulatorResourceModel::TypeInfo &typeInfo,
235                           jobject &value) : m_env(env), m_typeInfo(typeInfo), m_value(value) {}
236
237         void convert()
238         {
239             switch (m_typeInfo.baseType())
240             {
241                 case AttributeValueType::INTEGER:
242                     return handleByDepth<int>();
243                 case AttributeValueType::DOUBLE:
244                     return handleByDepth<double>();
245                 case AttributeValueType::BOOLEAN:
246                     return handleByDepth<bool>();
247                 case AttributeValueType::STRING:
248                     return handleByDepth<std::string>();
249                 case AttributeValueType::RESOURCE_MODEL:
250                     return handleByDepth<SimulatorResourceModel>();
251                 case AttributeValueType::VECTOR:
252                 case AttributeValueType::UNKNOWN:
253                     break;
254             }
255         }
256
257         AttributeValueVariant get()
258         {
259             return std::move(m_result);
260         }
261
262     private:
263         template <typename T>
264         void handleByDepth()
265         {
266             if (0 == m_typeInfo.depth())
267             {
268                 T value;
269                 getValue(m_value, value);
270                 m_result = value;
271             }
272             else if (1 == m_typeInfo.depth())
273             {
274                 std::vector<T> value;
275                 getValue(m_value, value);
276                 m_result = value;
277             }
278             else if (2 == m_typeInfo.depth())
279             {
280                 std::vector<std::vector<T>> value;
281                 getValue(m_value, value);
282                 m_result = value;
283             }
284             else if (3 == m_typeInfo.depth())
285             {
286                 std::vector<std::vector<std::vector<T>>> value;
287                 getValue(m_value, value);
288                 m_result = value;
289             }
290         }
291
292         void getValue(jobject &jValue, int &value)
293         {
294             static jmethodID intValueMID = m_env->GetMethodID(
295                                                gSimulatorClassRefs.integerCls, "intValue", "()I");
296
297             jint temp = m_env->CallIntMethod(jValue, intValueMID);
298             value = temp;
299         }
300
301         void getValue(jobject &jValue, std::vector<int> &value)
302         {
303             jobjectArray array = (jobjectArray) jValue;
304             size_t length = m_env->GetArrayLength(array);
305             for (size_t i = 0; i < length; i++)
306             {
307                 jobject jElement = m_env->GetObjectArrayElement(array, i);
308
309                 int element;
310                 getValue(jElement, element);
311                 value.push_back(element);
312             }
313         }
314
315         void getValue(jobject &jValue, std::vector<std::vector<int>> &value)
316         {
317             jobjectArray array = (jobjectArray) jValue;
318             size_t length = m_env->GetArrayLength(array);
319             for (size_t i = 0; i < length; i++)
320             {
321                 jobject jElement = m_env->GetObjectArrayElement(array, i);
322
323                 std::vector<int> element;
324                 getValue(jElement, element);
325                 value.push_back(element);
326             }
327         }
328
329         void getValue(jobject &jValue, std::vector<std::vector<std::vector<int>>> &value)
330         {
331             jobjectArray array = (jobjectArray) jValue;
332             size_t length = m_env->GetArrayLength(array);
333             for (size_t i = 0; i < length; i++)
334             {
335                 jobject jElement = m_env->GetObjectArrayElement(array, i);
336
337                 std::vector<std::vector<int>> element;
338                 getValue(jElement, element);
339                 value.push_back(element);
340             }
341         }
342
343         void getValue(jobject &jValue, double &value)
344         {
345             static jmethodID doubleValueMID = m_env->GetMethodID(
346                                                   gSimulatorClassRefs.doubleCls, "doubleValue", "()D");
347
348             value = m_env->CallDoubleMethod(jValue, doubleValueMID);
349         }
350
351         void getValue(jobject &jValue, std::vector<double> &value)
352         {
353             jobjectArray array = (jobjectArray) jValue;
354             size_t length = m_env->GetArrayLength(array);
355             for (size_t i = 0; i < length; i++)
356             {
357                 jobject jElement = m_env->GetObjectArrayElement(array, i);
358
359                 double element;
360                 getValue(jElement, element);
361                 value.push_back(element);
362             }
363         }
364
365         void getValue(jobject &jValue, std::vector<std::vector<double>> &value)
366         {
367             jobjectArray array = (jobjectArray) jValue;
368             size_t length = m_env->GetArrayLength(array);
369             for (size_t i = 0; i < length; i++)
370             {
371                 jobject jElement = m_env->GetObjectArrayElement(array, i);
372
373                 std::vector<double> element;
374                 getValue(jElement, element);
375                 value.push_back(element);
376             }
377         }
378
379         void getValue(jobject &jValue, std::vector<std::vector<std::vector<double>>> &value)
380         {
381             jobjectArray array = (jobjectArray) jValue;
382             size_t length = m_env->GetArrayLength(array);
383             for (size_t i = 0; i < length; i++)
384             {
385                 jobject jElement = m_env->GetObjectArrayElement(array, i);
386
387                 std::vector<std::vector<double>> element;
388                 getValue(jElement, element);
389                 value.push_back(element);
390             }
391         }
392
393         void getValue(jobject &jValue, bool &value)
394         {
395             static jmethodID boolValueMID = m_env->GetMethodID(
396                                                 gSimulatorClassRefs.booleanCls, "booleanValue", "()Z");
397
398             value = m_env->CallBooleanMethod(jValue, boolValueMID);
399         }
400
401         void getValue(jobject &jValue, std::vector<bool> &value)
402         {
403             jobjectArray array = (jobjectArray) jValue;
404             size_t length = m_env->GetArrayLength(array);
405             for (size_t i = 0; i < length; i++)
406             {
407                 jobject jElement = m_env->GetObjectArrayElement(array, i);
408
409                 bool element;
410                 getValue(jElement, element);
411                 value.push_back(element);
412             }
413         }
414
415         void getValue(jobject &jValue, std::vector<std::vector<bool>> &value)
416         {
417             jobjectArray array = (jobjectArray) jValue;
418             size_t length = m_env->GetArrayLength(array);
419             for (size_t i = 0; i < length; i++)
420             {
421                 jobject jElement = m_env->GetObjectArrayElement(array, i);
422
423                 std::vector<bool> element;
424                 getValue(jElement, element);
425                 value.push_back(element);
426             }
427         }
428
429         void getValue(jobject &jValue, std::vector<std::vector<std::vector<bool>>> &value)
430         {
431             jobjectArray array = (jobjectArray) jValue;
432             size_t length = m_env->GetArrayLength(array);
433             for (size_t i = 0; i < length; i++)
434             {
435                 jobject jElement = m_env->GetObjectArrayElement(array, i);
436
437                 std::vector<std::vector<bool>> element;
438                 getValue(jElement, element);
439                 value.push_back(element);
440             }
441         }
442
443         void getValue(jobject &jValue, std::string &value)
444         {
445             jstring stringValue = (jstring) jValue;
446             JniString jniValue(m_env, stringValue);
447             value = jniValue.get();
448         }
449
450         void getValue(jobject jValue, std::vector<std::string> &value)
451         {
452             jobjectArray array = (jobjectArray) jValue;
453             size_t length = m_env->GetArrayLength(array);
454             for (size_t i = 0; i < length; i++)
455             {
456                 jobject jElement = m_env->GetObjectArrayElement(array, i);
457
458                 std::string element;
459                 getValue(jElement, element);
460                 value.push_back(element);
461             }
462         }
463
464         void getValue(jobject &jValue, std::vector<std::vector<std::string>> &value)
465         {
466             jobjectArray array = (jobjectArray) jValue;
467             size_t length = m_env->GetArrayLength(array);
468             for (size_t i = 0; i < length; i++)
469             {
470                 jobject jElement = m_env->GetObjectArrayElement(array, i);
471
472                 std::vector<std::string> element;
473                 getValue(jElement, element);
474                 value.push_back(element);
475             }
476         }
477
478         void getValue(jobject &jValue, std::vector<std::vector<std::vector<std::string>>> &value)
479         {
480             jobjectArray array = (jobjectArray) jValue;
481             size_t length = m_env->GetArrayLength(array);
482             for (size_t i = 0; i < length; i++)
483             {
484                 jobject jElement = m_env->GetObjectArrayElement(array, i);
485
486                 std::vector<std::vector<std::string>> element;
487                 getValue(jElement, element);
488                 value.push_back(element);
489             }
490         }
491
492         void getValue(jobject &jValue, SimulatorResourceModel &value)
493         {
494             SimulatorResourceModelToCpp(m_env, jValue, value);
495         }
496
497         void getValue(jobject &jValue, std::vector<SimulatorResourceModel> &value)
498         {
499             jobjectArray array = (jobjectArray) jValue;
500             size_t length = m_env->GetArrayLength(array);
501             std::vector<SimulatorResourceModel> result(length);
502             for (size_t i = 0; i < length; i++)
503             {
504                 jobject jElement = m_env->GetObjectArrayElement(array, i);
505
506                 SimulatorResourceModel element;
507                 getValue(jElement, element);
508                 result[i] = element;
509             }
510
511             value = result;
512         }
513
514         void getValue(jobject &jValue, std::vector<std::vector<SimulatorResourceModel>> &value)
515         {
516             jobjectArray array = (jobjectArray) jValue;
517             size_t length = m_env->GetArrayLength(array);
518             std::vector<std::vector<SimulatorResourceModel>> result(length);
519             for (size_t i = 0; i < length; i++)
520             {
521                 jobject jElement = m_env->GetObjectArrayElement(array, i);
522
523                 std::vector<SimulatorResourceModel> childArray;
524                 getValue(jElement, childArray);
525                 value[i] = childArray;
526             }
527
528             value = result;
529         }
530
531         void getValue(jobject &jValue, std::vector<std::vector<std::vector<SimulatorResourceModel>>> &value)
532         {
533             jobjectArray array = (jobjectArray) jValue;
534             size_t length = m_env->GetArrayLength(array);
535             std::vector<std::vector<std::vector<SimulatorResourceModel>>> result(length);
536             for (size_t i = 0; i < length; i++)
537             {
538                 jobject jElement = m_env->GetObjectArrayElement(array, i);
539
540                 std::vector<std::vector<SimulatorResourceModel>> childArray;
541                 getValue(jElement, childArray);
542                 value[i] = childArray;
543             }
544
545             value = result;
546         }
547
548         JNIEnv *m_env;
549         SimulatorResourceModel::TypeInfo &m_typeInfo;
550         jobject &m_value;
551         AttributeValueVariant m_result;
552 };
553
554 class JniAttributeValue
555 {
556     public:
557         static jobject toJava(JNIEnv *env, const SimulatorResourceAttribute &attribute)
558         {
559             return toJava(env, attribute.getValue());
560         }
561
562         static jobject toJava(JNIEnv *env, const AttributeValueVariant &value)
563         {
564             ValueConverterJava converter(env);
565             jobject jValue =  boost::apply_visitor(converter, value);
566
567             static jmethodID attrValueCtor = env->GetMethodID(
568                                                  gSimulatorClassRefs.attributeValueCls, "<init>", "(Ljava/lang/Object;)V");
569
570             return env->NewObject(gSimulatorClassRefs.attributeValueCls, attrValueCtor, jValue);
571         }
572
573         static AttributeValueVariant toCpp(JNIEnv *env, jobject &jAttributeValue)
574         {
575             static jmethodID getMID = env->GetMethodID(gSimulatorClassRefs.attributeValueCls,
576                                       "get", "()Ljava/lang/Object;");
577
578             SimulatorResourceModel::TypeInfo typeInfo = JniTypeInfo(env).toCpp(jAttributeValue);
579             jobject jValue = env->CallObjectMethod(jAttributeValue, getMID);
580
581             ValueConverterCpp converter(env, typeInfo, jValue);
582             converter.convert();
583             return converter.get();
584         }
585 };
586
587 jobject SimulatorResourceModelToJava(JNIEnv *env, const SimulatorResourceModel &resModel)
588 {
589     JniMap jAttributesMap(env);
590
591     // Add attribute values for HashMap
592     for (auto &attributeEntry : resModel.getAttributeValues())
593     {
594         jstring jAttrName = env->NewStringUTF((attributeEntry.first).c_str());
595         jobject jAttributeValue = JniAttributeValue::toJava(env, attributeEntry.second);
596
597         jAttributesMap.put(jAttrName, jAttributeValue);
598     }
599
600     // Create Java SimulatorResourceModel object
601     static jmethodID simulatorResourceModelCtor = env->GetMethodID(
602                 gSimulatorClassRefs.simulatorResourceModelCls, "<init>", "(Ljava/util/Map;)V");
603
604     return env->NewObject(gSimulatorClassRefs.simulatorResourceModelCls,
605                           simulatorResourceModelCtor, jAttributesMap.get());
606 }
607
608 bool SimulatorResourceModelToCpp(JNIEnv *env, jobject jResModel, SimulatorResourceModel &resModel)
609 {
610     if (!jResModel)
611         return false;
612
613     static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.simulatorResourceModelCls,
614                                 "mValues", "Ljava/util/Map;");
615     static jmethodID entrySetMID = env->GetMethodID(gSimulatorClassRefs.mapCls, "entrySet",
616                                    "()Ljava/util/Set;");
617     static jmethodID iteratorMID = env->GetMethodID(gSimulatorClassRefs.setCls, "iterator",
618                                    "()Ljava/util/Iterator;");
619     static jmethodID hasNextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls, "hasNext",
620                                   "()Z");
621     static jmethodID nextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls, "next",
622                                "()Ljava/lang/Object;");
623     static jmethodID getKeyMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls, "getKey",
624                                  "()Ljava/lang/Object;");
625     static jmethodID getValueMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls, "getValue",
626                                    "()Ljava/lang/Object;");
627
628     jobject jValues = env->GetObjectField(jResModel, valuesFID);
629     if (jValues)
630     {
631         jobject entrySet = env->CallObjectMethod(jValues, entrySetMID);
632         jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
633         if (entrySet && iterator)
634         {
635             while (env->CallBooleanMethod(iterator, hasNextMID))
636             {
637                 jobject entry = env->CallObjectMethod(iterator, nextMID);
638                 jstring key = (jstring) env->CallObjectMethod(entry, getKeyMID);
639                 jobject value = env->CallObjectMethod(entry, getValueMID);
640                 resModel.add(JniString(env, key).get(), JniAttributeValue::toCpp(env, value));
641
642                 env->DeleteLocalRef(entry);
643                 env->DeleteLocalRef(key);
644                 env->DeleteLocalRef(value);
645             }
646         }
647     }
648
649     return true;
650 }
651
652 jobject AttributeValueToJava(JNIEnv *env,
653                              const AttributeValueVariant &value)
654 {
655     return JniAttributeValue::toJava(env, value);
656 }
657
658 bool AttributeValueToCpp(JNIEnv *env, jobject jAttributeValue,
659                          AttributeValueVariant &jValue)
660 {
661     if (!jAttributeValue)
662         return false;
663
664     jValue = JniAttributeValue::toCpp(env, jAttributeValue);
665     return true;
666 }
667