1 /******************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "simulator_resource_model_schema_jni.h"
22 #include "simulator_utils_jni.h"
23 #include "jni_string.h"
25 static AttributeProperty::Type getType(JNIEnv *env, jobject &jProperty)
27 static jmethodID getTypeMID = env->GetMethodID(
28 gSimulatorClassRefs.attributePropertyCls, "getType",
29 "()Lorg/oic/simulator/AttributeProperty$Type;");
31 static jmethodID ordinalMID = env->GetMethodID(
32 gSimulatorClassRefs.attributePropertyTypeCls, "ordinal", "()I");
34 jobject jType = env->CallObjectMethod(jProperty, getTypeMID);
35 int ordinal = env->CallIntMethod(jType, ordinalMID);
36 return AttributeProperty::Type(ordinal);
39 class JniIntegerProperty
42 static jobject toJava(JNIEnv *env, const std::shared_ptr<IntegerProperty> &property)
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);
54 static jmethodID setDefaultValueMID = env->GetMethodID(
55 gSimulatorClassRefs.integerPropertyBuilderCls, "setDefaultValue", "(I)V");
56 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
58 // Set Range or enum value set
59 if (property->hasRange())
63 property->getRange(min, max);
65 static jmethodID setRangeMID = env->GetMethodID(
66 gSimulatorClassRefs.integerPropertyBuilderCls, "setRange", "(II)V");
67 env->CallVoidMethod(jPropertyBuilder, setRangeMID, min, max);
69 else if (property->hasValues())
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]));
76 static jmethodID setValuesMID = env->GetMethodID(
77 gSimulatorClassRefs.integerPropertyBuilderCls, "setValues", "([I)V");
78 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jIntArray);
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);
87 static std::shared_ptr<IntegerProperty> toCpp(JNIEnv *env, jobject &jProperty)
89 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
90 "mDefaultValue", "I");
91 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
94 jint defaultValue = env->GetIntField(jProperty, defaultValueFID);
95 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
97 std::shared_ptr<IntegerProperty> integerProperty =
98 IntegerProperty::build(defaultValue);
102 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
104 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
107 jint min = env->GetIntField(jProperty, minFID);
108 jint max = env->GetIntField(jProperty, maxFID);
109 integerProperty->setRange(min, max);
113 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.integerPropertyCls,
115 jintArray jValues = (jintArray) env->GetObjectField(jProperty, valuesFID);
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++)
123 values.push_back(jIntArray[index]);
125 integerProperty->setValues(values);
127 env->ReleaseIntArrayElements(jValues, jIntArray, 0);
131 return integerProperty;
135 class JniDoubleProperty
138 static jobject toJava(JNIEnv *env, const std::shared_ptr<DoubleProperty> &property)
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);
150 static jmethodID setDefaultValueMID = env->GetMethodID(
151 gSimulatorClassRefs.doublePropertyBuilderCls, "setDefaultValue", "(D)V");
152 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
154 // Set Range or enum value set
155 if (property->hasRange())
159 property->getRange(min, max);
161 static jmethodID setRangeMID = env->GetMethodID(
162 gSimulatorClassRefs.doublePropertyBuilderCls, "setRange", "(DD)V");
163 env->CallVoidMethod(jPropertyBuilder, setRangeMID, min, max);
165 else if (property->hasValues())
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]));
173 static jmethodID setValuesMID = env->GetMethodID(
174 gSimulatorClassRefs.doublePropertyBuilderCls, "setValues", "([D)V");
175 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jDoubleArray);
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);
184 static std::shared_ptr<DoubleProperty> toCpp(JNIEnv *env, jobject &jProperty)
186 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
187 "mDefaultValue", "D");
188 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
191 jdouble defaultValue = env->GetDoubleField(jProperty, defaultValueFID);
192 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
194 std::shared_ptr<DoubleProperty> doubleProperty =
195 DoubleProperty::build(defaultValue);
199 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
201 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
204 jdouble min = env->GetDoubleField(jProperty, minFID);
205 jdouble max = env->GetDoubleField(jProperty, maxFID);
206 doubleProperty->setRange(min, max);
210 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
212 jdoubleArray jValues = (jdoubleArray) env->GetObjectField(jProperty, valuesFID);
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++)
220 values.push_back(jDoubleArray[index]);
222 doubleProperty->setValues(values);
224 env->ReleaseDoubleArrayElements(jValues, jDoubleArray, 0);
228 return doubleProperty;
232 class JniBooleanProperty
235 static jobject toJava(JNIEnv *env, const std::shared_ptr<BooleanProperty> &property)
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);
247 static jmethodID setDefaultValueMID = env->GetMethodID(
248 gSimulatorClassRefs.booleanPropertyBuilderCls, "setDefaultValue", "(Z)V");
249 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
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);
257 static std::shared_ptr<BooleanProperty> toCpp(JNIEnv *env, jobject &jProperty)
259 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.booleanPropertyCls,
260 "mDefaultValue", "Z");
262 jboolean defaultValue = env->GetBooleanField(jProperty, defaultValueFID);
263 return BooleanProperty::build(defaultValue);
267 class JniStringProperty
270 static jobject toJava(JNIEnv *env, const std::shared_ptr<StringProperty> &property)
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);
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);
287 // Set Range or enum value set
288 if (property->hasRange())
292 property->getRange(min, max);
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));
299 else if (property->hasValues())
301 std::vector<std::string> values;
302 property->getValues(values);
303 jobjectArray jStringArray = env->NewObjectArray(values.size(), gSimulatorClassRefs.stringCls,
306 for (size_t index = 0; index < values.size(); index++)
308 jstring element = env->NewStringUTF(values[index].c_str());
309 env->SetObjectArrayElement(jStringArray, index, element);
312 static jmethodID setValuesMID = env->GetMethodID(
313 gSimulatorClassRefs.stringPropertyBuilderCls, "setValues", "([Ljava/lang/String;)V");
314 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jStringArray);
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);
323 static std::shared_ptr<StringProperty> toCpp(JNIEnv *env, jobject &jProperty)
325 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
326 "mDefaultValue", "Ljava/lang/String;");
327 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
330 jstring defaultValue = (jstring) env->GetObjectField(jProperty, defaultValueFID);
331 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
333 std::shared_ptr<StringProperty> stringProperty =
334 StringProperty::build(JniString(env, defaultValue).get());
338 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
340 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
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));
350 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
351 "mValues", "[Ljava/lang/String;");
352 jobjectArray jValues = (jobjectArray) env->GetObjectField(jProperty, valuesFID);
355 std::vector<std::string> values;
356 size_t length = env->GetArrayLength(jValues);
357 for (size_t index = 0; index < length; index++)
359 jstring jValue = (jstring) env->GetObjectArrayElement(jValues, index);
360 values.push_back(JniString(env, jValue).get());
362 stringProperty->setValues(values);
366 return stringProperty;
370 class JniArrayProperty
373 static jobject toJava(JNIEnv *env, const std::shared_ptr<ArrayProperty> &property)
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);
384 // Set variable size propety
385 if (property->isVariable())
387 static jmethodID setVariableMID = env->GetMethodID(
388 gSimulatorClassRefs.arrayPropertyBuilderCls, "setVariableSize", "(Z)V");
389 env->CallVoidMethod(jPropertyBuilder, setVariableMID, property->isVariable());
392 // Set unique propety
393 if (property->isUnique())
395 static jmethodID setUniqueMID = env->GetMethodID(
396 gSimulatorClassRefs.arrayPropertyBuilderCls, "setUnique", "(Z)V");
397 env->CallVoidMethod(jPropertyBuilder, setUniqueMID, property->isUnique());
400 // Set range property
401 if (property->hasRange())
403 size_t min = property->getMinItems();
404 size_t max = property->getMaxItems();
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));
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);
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);
425 static std::shared_ptr<ArrayProperty> toCpp(JNIEnv *env, jobject &jProperty)
427 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
429 static jfieldID variableFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
430 "mIsVariableSize", "Z");
431 static jfieldID uniqueFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
433 static jfieldID elementPropertyFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
434 "mElementProperty", "Lorg/oic/simulator/AttributeProperty;");
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);
441 std::shared_ptr<ArrayProperty> arrayProperty = ArrayProperty::build();
443 arrayProperty->setVariable(isVariable);
444 arrayProperty->setUnique(isUnique);
448 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
450 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
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));
459 if (jElementProperty)
461 arrayProperty->setElementProperty(AttributePropertyToCpp(env, jElementProperty));
464 return arrayProperty;
468 class JniModelProperty
471 static jobject toJava(JNIEnv *env, const std::shared_ptr<ModelProperty> &property)
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);
482 // Set child propeties
483 for (auto &propertyEntry : property->getChildProperties())
485 jstring jAttrName = env->NewStringUTF(propertyEntry.first.c_str());
486 jobject jProperty = AttributePropertyToJava(env, propertyEntry.second);
487 jboolean required = property->isRequired(propertyEntry.first);
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);
495 return jModelProperty;
498 static std::shared_ptr<ModelProperty> toCpp(JNIEnv *env, jobject &jProperty)
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,
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;");
517 std::shared_ptr<ModelProperty> modelProperty = ModelProperty::build();
518 jobject jChildProperties = env->GetObjectField(jProperty, childPropertiesFID);
519 if (jChildProperties)
521 jobject entrySet = env->CallObjectMethod(jChildProperties, entrySetMID);
522 jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
523 if (entrySet && iterator)
525 while (env->CallBooleanMethod(iterator, hasNextMID))
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);
532 modelProperty->add(JniString(env, key).get(),
533 AttributePropertyToCpp(env, value), isRequired);
535 env->DeleteLocalRef(entry);
536 env->DeleteLocalRef(key);
537 env->DeleteLocalRef(value);
542 return modelProperty;
546 jobject AttributePropertyToJava(JNIEnv *env,
547 const std::shared_ptr<AttributeProperty> &property)
552 if (property->isInteger())
554 return JniIntegerProperty::toJava(env, property->asInteger());
556 else if (property->isDouble())
558 return JniDoubleProperty::toJava(env, property->asDouble());
560 else if (property->isBoolean())
562 return JniBooleanProperty::toJava(env, property->asBoolean());
564 else if (property->isString())
566 return JniStringProperty::toJava(env, property->asString());
568 else if (property->isArray())
570 return JniArrayProperty::toJava(env, property->asArray());
572 else if (property->isModel())
574 return JniModelProperty::toJava(env, property->asModel());
577 return nullptr; // Control should never reach here
580 std::shared_ptr<AttributeProperty> AttributePropertyToCpp(JNIEnv *env,
586 switch (getType(env, jProperty))
588 case AttributeProperty::Type::INTEGER:
589 return JniIntegerProperty::toCpp(env, jProperty);
591 case AttributeProperty::Type::DOUBLE:
592 return JniDoubleProperty::toCpp(env, jProperty);
594 case AttributeProperty::Type::BOOLEAN:
595 return JniBooleanProperty::toCpp(env, jProperty);
597 case AttributeProperty::Type::STRING:
598 return JniStringProperty::toCpp(env, jProperty);
600 case AttributeProperty::Type::ARRAY:
601 return JniArrayProperty::toCpp(env, jProperty);
603 case AttributeProperty::Type::MODEL:
604 return JniModelProperty::toCpp(env, jProperty);
607 return nullptr; // Control should never reach here