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]);
126 env->ReleaseIntArrayElements(jValues, jIntArray, 0);
130 return integerProperty;
134 class JniDoubleProperty
137 static jobject toJava(JNIEnv *env, const std::shared_ptr<DoubleProperty> &property)
142 // Create Java DoubleProperty.Builder object
143 jobject jPropertyBuilder = nullptr;
144 static jmethodID builderCtor = env->GetMethodID(
145 gSimulatorClassRefs.doublePropertyBuilderCls, "<init>", "()V");
146 jPropertyBuilder = env->NewObject(gSimulatorClassRefs.doublePropertyBuilderCls, builderCtor);
149 static jmethodID setDefaultValueMID = env->GetMethodID(
150 gSimulatorClassRefs.doublePropertyBuilderCls, "setDefaultValue", "(D)V");
151 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
153 // Set Range or enum value set
154 if (property->hasRange())
158 property->getRange(min, max);
160 static jmethodID setRangeMID = env->GetMethodID(
161 gSimulatorClassRefs.doublePropertyBuilderCls, "setRange", "(DD)V");
162 env->CallVoidMethod(jPropertyBuilder, setRangeMID, min, max);
164 else if (property->hasValues())
166 std::vector<double> values;
167 property->getValues(values);
168 jdoubleArray jDoubleArray = env->NewDoubleArray(values.size());
169 env->SetDoubleArrayRegion(jDoubleArray, 0, values.size(),
170 reinterpret_cast<const jdouble *>(&values[0]));
172 static jmethodID setValuesMID = env->GetMethodID(
173 gSimulatorClassRefs.doublePropertyBuilderCls, "setValues", "([D)V");
174 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jDoubleArray);
177 // Create Java DoubleProperty object
178 static jmethodID buildMID = env->GetMethodID(
179 gSimulatorClassRefs.doublePropertyBuilderCls, "build", "()Lorg/oic/simulator/DoubleProperty;");
180 return env->CallObjectMethod(jPropertyBuilder, buildMID);
183 static std::shared_ptr<DoubleProperty> toCpp(JNIEnv *env, jobject &jProperty)
185 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
186 "mDefaultValue", "D");
187 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
190 jdouble defaultValue = env->GetIntField(jProperty, defaultValueFID);
191 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
193 std::shared_ptr<DoubleProperty> doubleProperty =
194 DoubleProperty::build(defaultValue);
198 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
200 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
203 jdouble min = env->GetDoubleField(jProperty, minFID);
204 jdouble max = env->GetDoubleField(jProperty, maxFID);
205 doubleProperty->setRange(min, max);
209 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.doublePropertyCls,
211 jdoubleArray jValues = (jdoubleArray) env->GetObjectField(jProperty, valuesFID);
214 std::vector<double> values;
215 jdouble *jDoubleArray = env->GetDoubleArrayElements(jValues, NULL);
216 size_t length = env->GetArrayLength(jValues);
217 for (size_t index = 0; index < length; index++)
219 values.push_back(jDoubleArray[index]);
222 env->ReleaseDoubleArrayElements(jValues, jDoubleArray, 0);
226 return doubleProperty;
230 class JniBooleanProperty
233 static jobject toJava(JNIEnv *env, const std::shared_ptr<BooleanProperty> &property)
238 // Create Java BooleanProperty.Builder object
239 jobject jPropertyBuilder = nullptr;
240 static jmethodID builderCtor = env->GetMethodID(
241 gSimulatorClassRefs.booleanPropertyBuilderCls, "<init>", "()V");
242 jPropertyBuilder = env->NewObject(gSimulatorClassRefs.booleanPropertyBuilderCls, builderCtor);
245 static jmethodID setDefaultValueMID = env->GetMethodID(
246 gSimulatorClassRefs.booleanPropertyBuilderCls, "setDefaultValue", "(Z)V");
247 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, property->getDefaultValue());
249 // Create Java BooleanProperty object
250 static jmethodID buildMID = env->GetMethodID(
251 gSimulatorClassRefs.booleanPropertyBuilderCls, "build", "()Lorg/oic/simulator/BooleanProperty;");
252 return env->CallObjectMethod(jPropertyBuilder, buildMID);
255 static std::shared_ptr<BooleanProperty> toCpp(JNIEnv *env, jobject &jProperty)
257 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.booleanPropertyCls,
258 "mDefaultValue", "Z");
260 jboolean defaultValue = env->GetBooleanField(jProperty, defaultValueFID);
261 return BooleanProperty::build(defaultValue);
265 class JniStringProperty
268 static jobject toJava(JNIEnv *env, const std::shared_ptr<StringProperty> &property)
273 // Create Java StringProperty.Builder object
274 jobject jPropertyBuilder = nullptr;
275 static jmethodID builderCtor = env->GetMethodID(
276 gSimulatorClassRefs.stringPropertyBuilderCls, "<init>", "()V");
277 jPropertyBuilder = env->NewObject(gSimulatorClassRefs.stringPropertyBuilderCls, builderCtor);
280 static jmethodID setDefaultValueMID = env->GetMethodID(
281 gSimulatorClassRefs.stringPropertyBuilderCls, "setDefaultValue", "(Ljava/lang/String;)V");
282 jstring jDefaultValue = env->NewStringUTF(property->getDefaultValue().c_str());
283 env->CallVoidMethod(jPropertyBuilder, setDefaultValueMID, jDefaultValue);
285 // Set Range or enum value set
286 if (property->hasRange())
290 property->getRange(min, max);
292 static jmethodID setRangeMID = env->GetMethodID(
293 gSimulatorClassRefs.stringPropertyBuilderCls, "setRange", "(II)V");
294 env->CallVoidMethod(jPropertyBuilder, setRangeMID, static_cast<jint>(min),
295 static_cast<jint>(max));
297 else if (property->hasValues())
299 std::vector<std::string> values;
300 property->getValues(values);
301 jobjectArray jStringArray = env->NewObjectArray(values.size(), gSimulatorClassRefs.stringCls,
304 for (size_t index = 0; index < values.size(); index++)
306 jstring element = env->NewStringUTF(values[index].c_str());
307 env->SetObjectArrayElement(jStringArray, index, element);
310 static jmethodID setValuesMID = env->GetMethodID(
311 gSimulatorClassRefs.stringPropertyBuilderCls, "setValues", "([Ljava/lang/String;)V");
312 env->CallVoidMethod(jPropertyBuilder, setValuesMID, jStringArray);
315 // Create Java StringProperty object
316 static jmethodID buildMID = env->GetMethodID(
317 gSimulatorClassRefs.stringPropertyBuilderCls, "build", "()Lorg/oic/simulator/StringProperty;");
318 return env->CallObjectMethod(jPropertyBuilder, buildMID);
321 static std::shared_ptr<StringProperty> toCpp(JNIEnv *env, jobject &jProperty)
323 static jfieldID defaultValueFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
324 "mDefaultValue", "Ljava/lang/String;");
325 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
328 jstring defaultValue = (jstring) env->GetObjectField(jProperty, defaultValueFID);
329 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
331 std::shared_ptr<StringProperty> stringProperty =
332 StringProperty::build(JniString(env, defaultValue).get());
336 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
338 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
341 jint min = env->GetIntField(jProperty, minFID);
342 jint max = env->GetIntField(jProperty, maxFID);
343 if (min >= 0 && max >= 0)
344 stringProperty->setRange(static_cast<size_t>(min), static_cast<size_t>(max));
348 static jfieldID valuesFID = env->GetFieldID(gSimulatorClassRefs.stringPropertyCls,
349 "mValues", "[Ljava/lang/String;");
350 jobjectArray jValues = (jobjectArray) env->GetObjectField(jProperty, valuesFID);
353 std::vector<std::string> values;
354 size_t length = env->GetArrayLength(jValues);
355 for (size_t index = 0; index < length; index++)
357 jstring jValue = (jstring) env->GetObjectArrayElement(jValues, index);
358 values.push_back(JniString(env, jValue).get());
363 return stringProperty;
367 class JniArrayProperty
370 static jobject toJava(JNIEnv *env, const std::shared_ptr<ArrayProperty> &property)
375 // Create Java ArrayProperty.Builder object
376 jobject jPropertyBuilder = nullptr;
377 static jmethodID builderCtor = env->GetMethodID(
378 gSimulatorClassRefs.arrayPropertyBuilderCls, "<init>", "()V");
379 jPropertyBuilder = env->NewObject(gSimulatorClassRefs.arrayPropertyBuilderCls, builderCtor);
381 // Set variable size propety
382 if (property->isVariable())
384 static jmethodID setVariableMID = env->GetMethodID(
385 gSimulatorClassRefs.arrayPropertyBuilderCls, "setVariableSize", "(Z)V");
386 env->CallVoidMethod(jPropertyBuilder, setVariableMID, property->isVariable());
389 // Set unique propety
390 if (property->isUnique())
392 static jmethodID setUniqueMID = env->GetMethodID(
393 gSimulatorClassRefs.arrayPropertyBuilderCls, "setUnique", "(Z)V");
394 env->CallVoidMethod(jPropertyBuilder, setUniqueMID, property->isUnique());
397 // Set range property
398 if (property->hasRange())
400 size_t min = property->getMinItems();
401 size_t max = property->getMaxItems();
403 static jmethodID setRangeMID = env->GetMethodID(
404 gSimulatorClassRefs.arrayPropertyBuilderCls, "setRange", "(II)V");
405 env->CallVoidMethod(jPropertyBuilder, setRangeMID, static_cast<jint>(min),
406 static_cast<jint>(max));
409 // Set element property
410 jobject jElementProperty = AttributePropertyToJava(env, property->getElementProperty());
411 static jmethodID setElementPropertyMID = env->GetMethodID(
412 gSimulatorClassRefs.arrayPropertyBuilderCls, "setElementProperty",
413 "(Lorg/oic/simulator/AttributeProperty;)V");
414 env->CallVoidMethod(jPropertyBuilder, setElementPropertyMID, jElementProperty);
416 // Create Java ArrayProperty object
417 static jmethodID buildMID = env->GetMethodID(
418 gSimulatorClassRefs.arrayPropertyBuilderCls, "build", "()Lorg/oic/simulator/ArrayProperty;");
419 return env->CallObjectMethod(jPropertyBuilder, buildMID);
422 static std::shared_ptr<ArrayProperty> toCpp(JNIEnv *env, jobject &jProperty)
424 static jfieldID hasRangeFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
426 static jfieldID variableFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
427 "mIsVariableSize", "Z");
428 static jfieldID uniqueFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
430 static jfieldID elementPropertyFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
431 "mElementProperty", "Lorg/oic/simulator/AttributeProperty;");
433 jboolean hasRange = env->GetBooleanField(jProperty, hasRangeFID);
434 jboolean isVariable = env->GetBooleanField(jProperty, variableFID);
435 jboolean isUnique = env->GetBooleanField(jProperty, uniqueFID);
436 jobject jElementProperty = env->GetObjectField(jProperty, elementPropertyFID);
438 std::shared_ptr<ArrayProperty> arrayProperty = ArrayProperty::build();
440 arrayProperty->setVariable(isVariable);
441 arrayProperty->setUnique(isUnique);
445 static jfieldID minFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
447 static jfieldID maxFID = env->GetFieldID(gSimulatorClassRefs.arrayPropertyCls,
450 jint min = env->GetIntField(jProperty, minFID);
451 jint max = env->GetIntField(jProperty, maxFID);
452 if (min >= 0 && max >= 0)
453 arrayProperty->setRange(static_cast<size_t>(min), static_cast<size_t>(max));
456 if (jElementProperty)
458 arrayProperty->setElementProperty(AttributePropertyToCpp(env, jElementProperty));
461 return arrayProperty;
465 class JniModelProperty
468 static jobject toJava(JNIEnv *env, const std::shared_ptr<ModelProperty> &property)
473 // Create Java ModelProperty object
474 jobject jModelProperty = nullptr;
475 static jmethodID modelPropertyCtor = env->GetMethodID(
476 gSimulatorClassRefs.modelPropertyCls, "<init>", "()V");
477 jModelProperty = env->NewObject(gSimulatorClassRefs.modelPropertyCls, modelPropertyCtor);
479 // Set child propeties
480 for (auto &propertyEntry : property->getChildProperties())
482 jstring jAttrName = env->NewStringUTF(propertyEntry.first.c_str());
483 jobject jProperty = AttributePropertyToJava(env, propertyEntry.second);
484 jboolean required = property->isRequired(propertyEntry.first);
486 static jmethodID addMID = env->GetMethodID(
487 gSimulatorClassRefs.modelPropertyCls, "add",
488 "(Ljava/lang/String;Lorg/oic/simulator/AttributeProperty;Z)Z");
489 env->CallBooleanMethod(jModelProperty, addMID, jAttrName, jProperty, required);
492 return jModelProperty;
495 static std::shared_ptr<ModelProperty> toCpp(JNIEnv *env, jobject &jProperty)
497 static jfieldID childPropertiesFID = env->GetFieldID(gSimulatorClassRefs.modelPropertyCls,
498 "mChildProperties", "Ljava/util/Map;");
499 static jmethodID isRequiredMID = env->GetMethodID(gSimulatorClassRefs.modelPropertyCls,
500 "isRequired", "()Z");
501 static jmethodID entrySetMID = env->GetMethodID(gSimulatorClassRefs.mapCls,
502 "entrySet", "()Ljava/util/Set;");
503 static jmethodID iteratorMID = env->GetMethodID(gSimulatorClassRefs.setCls,
504 "iterator", "()Ljava/util/Iterator;");
505 static jmethodID hasNextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls,
507 static jmethodID nextMID = env->GetMethodID(gSimulatorClassRefs.iteratorCls,
508 "next", "()Ljava/lang/Object;");
509 static jmethodID getKeyMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls,
510 "getKey", "()Ljava/lang/Object;");
511 static jmethodID getValueMID = env->GetMethodID(gSimulatorClassRefs.mapEntryCls,
512 "getValue", "()Ljava/lang/Object;");
514 std::shared_ptr<ModelProperty> modelProperty = ModelProperty::build();
515 jobject jChildProperties = env->GetObjectField(jProperty, childPropertiesFID);
516 if (jChildProperties)
518 jobject entrySet = env->CallObjectMethod(jChildProperties, entrySetMID);
519 jobject iterator = env->CallObjectMethod(entrySet, iteratorMID);
520 if (entrySet && iterator)
522 while (env->CallBooleanMethod(iterator, hasNextMID))
524 jobject entry = env->CallObjectMethod(iterator, nextMID);
525 jstring key = (jstring) env->CallObjectMethod(entry, getKeyMID);
526 jobject value = env->CallObjectMethod(entry, getValueMID);
527 jboolean isRequired = env->CallBooleanMethod(jProperty, isRequiredMID, key);
529 modelProperty->add(JniString(env, key).get(),
530 AttributePropertyToCpp(env, value), isRequired);
532 env->DeleteLocalRef(entry);
533 env->DeleteLocalRef(key);
534 env->DeleteLocalRef(value);
539 return modelProperty;
543 jobject AttributePropertyToJava(JNIEnv *env,
544 const std::shared_ptr<AttributeProperty> &property)
549 if (property->isInteger())
551 return JniIntegerProperty::toJava(env, property->asInteger());
553 else if (property->isDouble())
555 return JniDoubleProperty::toJava(env, property->asDouble());
557 else if (property->isBoolean())
559 return JniBooleanProperty::toJava(env, property->asBoolean());
561 else if (property->isString())
563 return JniStringProperty::toJava(env, property->asString());
565 else if (property->isArray())
567 return JniArrayProperty::toJava(env, property->asArray());
569 else if (property->isModel())
571 return JniModelProperty::toJava(env, property->asModel());
574 return nullptr; // Control should never reach here
577 std::shared_ptr<AttributeProperty> AttributePropertyToCpp(JNIEnv *env,
583 switch (getType(env, jProperty))
585 case AttributeProperty::Type::INTEGER:
586 return JniIntegerProperty::toCpp(env, jProperty);
588 case AttributeProperty::Type::DOUBLE:
589 return JniDoubleProperty::toCpp(env, jProperty);
591 case AttributeProperty::Type::BOOLEAN:
592 return JniBooleanProperty::toCpp(env, jProperty);
594 case AttributeProperty::Type::STRING:
595 return JniStringProperty::toCpp(env, jProperty);
597 case AttributeProperty::Type::ARRAY:
598 return JniArrayProperty::toCpp(env, jProperty);
600 case AttributeProperty::Type::MODEL:
601 return JniModelProperty::toCpp(env, jProperty);
604 return nullptr; // Control should never reach here