Imported Upstream version 1.1.0
[platform/upstream/iotivity.git] / service / simulator / java / jni / simulator_remote_resource_jni.cpp
index 63215b6..f033f2c 100644 (file)
  *
  ******************************************************************/
 
-#include "simulator_remote_resource_jni.h"
-#include "simulator_common_jni.h"
-#include "simulator_error_codes.h"
-#include "simulator_resource_jni_util.h"
 #include "simulator_resource_model_jni.h"
-#include "simulator_client_types.h"
-#include "simulator_exceptions.h"
-#include "simulator_jni_utils.h"
-
-extern SimulatorClassRefs gSimulatorClassRefs;
-
-SimulatorRemoteResourceSP JniSimulatorRemoteResource::getResourceHandle
-(JNIEnv *env, jobject object)
+#include "simulator_resource_model_schema_jni.h"
+#include "simulator_exceptions_jni.h"
+#include "simulator_utils_jni.h"
+#include "jni_sharedobject_holder.h"
+#include "jni_listener_holder.h"
+#include "jni_queryparam.h"
+#include "jni_string.h"
+#include "jni_vector.h"
+#include "jni_map.h"
+
+#include "simulator_remote_resource.h"
+
+#define VALIDATE_OBJECT(ENV, OBJECT) if (!OBJECT){ThrowBadObjectException(ENV, "No corresponsing native object!"); return;}
+#define VALIDATE_OBJECT_RET(ENV, OBJECT, RET) if (!OBJECT){ThrowBadObjectException(ENV, "No corresponsing native object!"); return RET;}
+
+static SimulatorRemoteResourceSP simulatorRemoteResourceToCpp(
+    JNIEnv *env, jobject object)
 {
-    JniSimulatorRemoteResource *jniResource = GetHandle<JniSimulatorRemoteResource>(env, object);
-    if (env->ExceptionCheck() || !jniResource)
-    {
-        return nullptr;
-    }
-
-    return jniResource->m_resource;
+    JniSharedObjectHolder<SimulatorRemoteResource> *jniResource =
+        getHandle<JniSharedObjectHolder<SimulatorRemoteResource>>(env, object);
+    if (jniResource)
+        return jniResource->get();
+    return nullptr;
 }
 
-class JNIOnObserveListener
+static void onObserveCallback(jobject listener, const std::string &uid, SimulatorResult /*result*/,
+                              const SimulatorResourceModel &representation, const int seq)
 {
-    public:
-        void setJavaOnObserveListener(JNIEnv *env, jobject listener)
-        {
-            m_listener = env->NewWeakGlobalRef(listener);
-        }
+    JNIEnv *env = GetEnv();
+    if (!env)
+        return;
 
-        void onObserveCallback(const std::string &uId, const int errorCode,
-                               SimulatorResourceModelSP representation,
-                               const int seqNumber)
-        {
-            JNIEnv *env = getEnv();
-            if (nullptr == env)
-                return;
+    jclass listenerCls = env->GetObjectClass(listener);
+    jmethodID listenerMethodId = env->GetMethodID(listenerCls, "onObserveNotification",
+                                 "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResourceModel;I)V");
 
-            jobject onObserveListener = env->NewLocalRef(m_listener);
-            if (!onObserveListener)
-            {
-                releaseEnv();
-                return;
-            }
+    jobject jResModel = SimulatorResourceModelToJava(env, representation);
+    jstring jUid = env->NewStringUTF(uid.c_str());
+    env->CallVoidMethod(listener, listenerMethodId, jUid, jResModel, seq);
+    ReleaseEnv();
+}
 
-            jclass onObserveCls = env->GetObjectClass(onObserveListener);
-            if (!onObserveCls)
-            {
-                releaseEnv();
-                return;
-            }
+static void onGetCallback(jobject listener, const std::string &uid, SimulatorResult result,
+                          const SimulatorResourceModel &representation)
+{
+    JNIEnv *env = GetEnv();
+    if (!env)
+        return;
 
-            if (OC_STACK_OK != errorCode && OC_STACK_RESOURCE_CREATED != errorCode
-                && OC_STACK_RESOURCE_DELETED != errorCode)
-            {
-                jmethodID midL = env->GetMethodID(onObserveCls, "onObserveFailed", "(Ljava/lang/Throwable;)V");
-                if (!midL)
-                {
-                    releaseEnv();
-                    return;
-                }
-                env->CallVoidMethod(onObserveListener, midL);
-            }
-            else
-            {
-                JSimulatorResourceModel *jniModel = new JSimulatorResourceModel(representation);
-                if (!jniModel)
-                {
-                    releaseEnv();
-                    return;
-                }
-
-                jobject jRepresentation = JSimulatorResourceModel::toJava(env,
-                        reinterpret_cast<jlong>(jniModel));
-                if (!jRepresentation)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jmethodID midL = env->GetMethodID(onObserveCls, "onObserveCompleted",
-                        "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResourceModel;I)V");
-                if (!midL)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jstring jUid = env->NewStringUTF(uId.c_str());
-
-                env->CallVoidMethod(onObserveListener, midL, jUid, jRepresentation,
-                                    static_cast<jint>(seqNumber));
-                if (env->ExceptionCheck())
-                {
-                    delete jniModel;
-                    releaseEnv();
-                }
-            }
-        }
+    jclass listenerCls = env->GetObjectClass(listener);
+    jmethodID listenerMethodId = env->GetMethodID(listenerCls, "onGetResponse",
+                                 "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResult;Lorg/oic/simulator/SimulatorResourceModel;)V");
 
-    private:
-        jweak m_listener;
-};
+    jobject jResModel = SimulatorResourceModelToJava(env, representation);
+    jstring jUid = env->NewStringUTF(uid.c_str());
+    env->CallVoidMethod(listener, listenerMethodId, jUid,
+                        SimulatorResultToJava(env, result), jResModel);
 
-class JNIOnGetListener
+    ReleaseEnv();
+}
+
+static void onPutCallback(jobject listener, const std::string &uid, SimulatorResult result,
+                          const SimulatorResourceModel &representation)
 {
-    public:
-        void setJavaOnGetListener(JNIEnv *env, jobject listener)
-        {
-            m_listener = env->NewWeakGlobalRef(listener);
-        }
+    JNIEnv *env = GetEnv();
+    if (!env)
+        return;
 
-        void onGetCallback(const std::string &uId, int errorCode,
-                           SimulatorResourceModelSP representation)
-        {
-            JNIEnv *env = getEnv();
-            if (nullptr == env)
-                return;
+    jclass listenerCls = env->GetObjectClass(listener);
+    jmethodID listenerMethodId = env->GetMethodID(listenerCls, "onPutResponse",
+                                 "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResult;Lorg/oic/simulator/SimulatorResourceModel;)V");
 
-            jobject onGetListener = env->NewLocalRef(m_listener);
-            if (!onGetListener)
-            {
-                releaseEnv();
-                return;
-            }
+    jobject jResModel = SimulatorResourceModelToJava(env, representation);
+    jstring jUid = env->NewStringUTF(uid.c_str());
+    env->CallVoidMethod(listener, listenerMethodId, jUid,
+                        SimulatorResultToJava(env, result), jResModel);
 
-            jclass onGetCls = env->GetObjectClass(onGetListener);
-            if (!onGetCls)
-            {
-                releaseEnv();
-                return;
-            }
+    ReleaseEnv();
+}
 
-            // TODO: Revisit is it required?
-            if (OC_STACK_OK != errorCode && OC_STACK_RESOURCE_CREATED != errorCode
-                && OC_STACK_RESOURCE_DELETED != errorCode)
-            {
-                jmethodID midL = env->GetMethodID(onGetCls, "onGetFailed", "(Ljava/lang/Throwable;)V");
-                if (!midL)
-                {
-                    releaseEnv();
-                    return;
-                }
-                env->CallVoidMethod(onGetListener, midL);
-            }
-            else
-            {
-                JSimulatorResourceModel *jniModel = new JSimulatorResourceModel(representation);
-                if (!jniModel)
-                {
-                    releaseEnv();
-                    return;
-                }
-
-                jobject jRepresentation = JSimulatorResourceModel::toJava(env, reinterpret_cast<jlong>(jniModel));
-                if (!jRepresentation)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jmethodID midL = env->GetMethodID(onGetCls, "onGetCompleted",
-                                                  "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResourceModel;)V");
-                if (!midL)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jstring jUid = env->NewStringUTF(uId.c_str());
-                env->CallVoidMethod(onGetListener, midL, jUid, jRepresentation);
-                if (env->ExceptionCheck())
-                {
-                    delete jniModel;
-                    releaseEnv();
-                }
-            }
-        }
+static void onPostCallback(jobject listener, const std::string &uid, SimulatorResult result,
+                           const SimulatorResourceModel &representation)
+{
+    JNIEnv *env = GetEnv();
+    if (!env)
+        return;
 
-    private:
-        jweak m_listener;
-};
+    jclass listenerCls = env->GetObjectClass(listener);
+    jmethodID listenerMethodId = env->GetMethodID(listenerCls, "onPostResponse",
+                                 "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResult;Lorg/oic/simulator/SimulatorResourceModel;)V");
 
-class JNIOnPutListener
-{
-    public:
-        void setJavaOnPutListener(JNIEnv *env, jobject listener)
-        {
-            m_listener = env->NewWeakGlobalRef(listener);
-        }
+    jobject jResModel = SimulatorResourceModelToJava(env, representation);
+    jstring jUid = env->NewStringUTF(uid.c_str());
+    env->CallVoidMethod(listener, listenerMethodId, jUid,
+                        SimulatorResultToJava(env, result), jResModel);
 
-        void onPutCallback(const std::string &uId, int errorCode,
-                           SimulatorResourceModelSP representation)
-        {
-            JNIEnv *env = getEnv();
-            if (nullptr == env)
-                return;
+    ReleaseEnv();
+}
 
-            jobject onPutListener = env->NewLocalRef(m_listener);
-            if (!onPutListener)
-            {
-                releaseEnv();
-                return;
-            }
+static void onVerificationCallback(jobject listener, const std::string &uid, int id,
+                                   OperationState opState)
+{
+    JNIEnv *env = GetEnv();
+    if (!env)
+        return;
 
-            jclass onGetCls = env->GetObjectClass(onPutListener);
-            if (!onGetCls)
-            {
-                releaseEnv();
-                return;
-            }
+    jclass listenerCls = env->GetObjectClass(listener);
+    jmethodID listenerMethodId = nullptr;
+    if (OP_START == opState)
+    {
+        listenerMethodId = env->GetMethodID(listenerCls, "onVerificationStarted", "(Ljava/lang/String;I)V");
+    }
+    else if (OP_COMPLETE == opState)
+    {
+        listenerMethodId = env->GetMethodID(listenerCls, "onVerificationCompleted",
+                                            "(Ljava/lang/String;I)V");
+    }
+    else if (OP_ABORT == opState)
+    {
+        listenerMethodId = env->GetMethodID(listenerCls, "onVerificationAborted", "(Ljava/lang/String;I)V");
+    }
 
-            // TODO: Revisit is it required?
-            if (OC_STACK_OK != errorCode && OC_STACK_RESOURCE_CREATED != errorCode
-                && OC_STACK_RESOURCE_DELETED != errorCode)
-            {
-                jmethodID midL = env->GetMethodID(onGetCls, "onPutFailed", "(Ljava/lang/Throwable;)V");
-                if (!midL)
-                {
-                    releaseEnv();
-                    return;
-                }
-                env->CallVoidMethod(onPutListener, midL);
-            }
-            else
-            {
-                JSimulatorResourceModel *jniModel = new JSimulatorResourceModel(representation);
-                if (!jniModel)
-                {
-                    releaseEnv();
-                    return;
-                }
-
-                jobject jRepresentation = JSimulatorResourceModel::toJava(env,
-                        reinterpret_cast<jlong>(jniModel));
-                if (!jRepresentation)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jmethodID midL = env->GetMethodID(onGetCls, "onPutCompleted",
-                            "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResourceModel;)V");
-                if (!midL)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jstring jUid = env->NewStringUTF(uId.c_str());
-                env->CallVoidMethod(onPutListener, midL, jUid, jRepresentation);
-                if (env->ExceptionCheck())
-                {
-                    delete jniModel;
-                    releaseEnv();
-                }
-            }
-        }
+    // Invoke java callback method
+    if (nullptr != listenerMethodId)
+    {
+        jstring jUid = env->NewStringUTF(uid.c_str());
+        env->CallVoidMethod(listener, listenerMethodId, jUid, id);
+    }
 
-    private:
-        jweak m_listener;
-};
+    if (OP_COMPLETE == opState || OP_ABORT == opState)
+        env->DeleteGlobalRef(listener);
+    ReleaseEnv();
+}
 
-class JNIOnPostListener
+class JniRequestType
 {
     public:
-        void setJavaOnPostListener(JNIEnv *env, jobject listener)
-        {
-            m_listener = env->NewWeakGlobalRef(listener);
-        }
-
-        void onPostCallback(const std::string &uId, int errorCode,
-                            SimulatorResourceModelSP representation)
+        static jobject toJava(JNIEnv *env, RequestType requestType)
         {
-            JNIEnv *env = getEnv();
-            if (nullptr == env)
-                return;
-
-            jobject onPostListener = env->NewLocalRef(m_listener);
-            if (!onPostListener)
+            switch (requestType)
             {
-                releaseEnv();
-                return;
+                case RequestType::RQ_TYPE_GET:
+                    {
+                        static jfieldID fieldID = env->GetStaticFieldID(gSimulatorClassRefs.requestTypeCls,
+                                                  "GET",
+                                                  "Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;");
+                        return env->GetStaticObjectField(gSimulatorClassRefs.requestTypeCls, fieldID);
+                    }
+
+                case RequestType::RQ_TYPE_PUT:
+                    {
+                        static jfieldID fieldID = env->GetStaticFieldID(gSimulatorClassRefs.requestTypeCls,
+                                                  "PUT",
+                                                  "Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;");
+                        return env->GetStaticObjectField(gSimulatorClassRefs.requestTypeCls, fieldID);
+                    }
+
+                case RequestType::RQ_TYPE_POST:
+                    {
+                        static jfieldID fieldID = env->GetStaticFieldID(gSimulatorClassRefs.requestTypeCls,
+                                                  "POST",
+                                                  "Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;");
+                        return env->GetStaticObjectField(gSimulatorClassRefs.requestTypeCls, fieldID);
+                    }
+
+                case RequestType::RQ_TYPE_DELETE:
+                    {
+                        static jfieldID fieldID = env->GetStaticFieldID(gSimulatorClassRefs.requestTypeCls,
+                                                  "DELETE",
+                                                  "Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;");
+                        return env->GetStaticObjectField(gSimulatorClassRefs.requestTypeCls, fieldID);
+                    }
+
+                default:
+                    break;
             }
 
-            jclass onGetCls = env->GetObjectClass(onPostListener);
-            if (!onGetCls)
-            {
-                releaseEnv();
-                return;
-            }
-
-            // TODO: Revisit is it required?
-            if (OC_STACK_OK != errorCode && OC_STACK_RESOURCE_CREATED != errorCode
-                && OC_STACK_RESOURCE_DELETED != errorCode)
-            {
-                jmethodID midL = env->GetMethodID(onGetCls, "onPostFailed", "(Ljava/lang/Throwable;)V");
-                if (!midL)
-                {
-                    releaseEnv();
-                    return;
-                }
-                env->CallVoidMethod(onPostListener, midL);
-            }
-            else
-            {
-                JSimulatorResourceModel *jniModel = new JSimulatorResourceModel(representation);
-                if (!jniModel)
-                {
-                    releaseEnv();
-                    return;
-                }
-
-                jobject jRepresentation = JSimulatorResourceModel::toJava(env,
-                        reinterpret_cast<jlong>(jniModel));
-                if (!jRepresentation)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jmethodID midL = env->GetMethodID(onGetCls, "onPostCompleted",
-                        "(Ljava/lang/String;Lorg/oic/simulator/SimulatorResourceModel;)V");
-                if (!midL)
-                {
-                    delete jniModel;
-                    releaseEnv();
-                    return;
-                }
-
-                jstring jUid = env->NewStringUTF(uId.c_str());
-
-                env->CallVoidMethod(onPostListener, midL, jUid, jRepresentation);
-                if (env->ExceptionCheck())
-                {
-                    delete jniModel;
-                    releaseEnv();
-                }
-            }
+            static jfieldID fieldID = env->GetStaticFieldID(gSimulatorClassRefs.requestTypeCls,
+                                      "UKNOWN",
+                                      "Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;");
+            return env->GetStaticObjectField(gSimulatorClassRefs.requestTypeCls, fieldID);
         }
 
-    private:
-        jweak m_listener;
-
+        static RequestType toCpp(JNIEnv *env, jobject jRequestType)
+        {
+            static jmethodID ordinalMID = env->GetMethodID(
+                                              gSimulatorClassRefs.requestTypeCls, "ordinal", "()I");
+            int ordinal = env->CallIntMethod(jRequestType, ordinalMID);
+            return RequestType(ordinal);
+        }
 };
 
-class JNIOnVerificationListener
+class JniSimulatorRequestModel
 {
     public:
-        void setJavaOnVerificationListener(JNIEnv *env, jobject listener)
+        static jobject toJava(JNIEnv *env, const SimulatorRequestModel &requestModel)
         {
-            m_listener = env->NewWeakGlobalRef(listener);
-        }
-
-        void onVerificationCallback(const std::string &uId, int id, OperationState opState)
-        {
-            JNIEnv *env = getEnv();
-            if (nullptr == env)
-                return;
+            // Convert RequestType
+            jobject jRequestType = JniRequestType::toJava(env, requestModel.getType());
 
-            jobject onVerificationListener = env->NewLocalRef(m_listener);
-            if (!onVerificationListener)
+            // Convert Query Parameters
+            JniMap jQueryParams(env);
+            for (auto &qpEntry : requestModel.getQueryParams())
             {
-                releaseEnv();
-                return;
-            }
+                jstring jQueryParamName = env->NewStringUTF((qpEntry.first).c_str());
+                jobject jQueryParamValues = JniVector(env).toJava(qpEntry.second);
 
-            jclass onVerificationCls = env->GetObjectClass(onVerificationListener);
-            if (!onVerificationCls)
-            {
-                releaseEnv();
-                return;
+                jQueryParams.put(jQueryParamName, jQueryParamValues);
             }
 
-            jmethodID midL;
+            // Convert Request body model
+            jobject jRequestBodyModel  =
+                AttributePropertyToJava(env, requestModel.getRequestBodySchema());
 
-            if (OP_START == opState)
-            {
-                midL = env->GetMethodID(onVerificationCls, "onVerificationStarted", "(Ljava/lang/String;I)V");
-            }
-            else if (OP_COMPLETE == opState)
-            {
-                midL = env->GetMethodID(onVerificationCls, "onVerificationCompleted", "(Ljava/lang/String;I)V");
-            }
-            else
-            {
-                midL = env->GetMethodID(onVerificationCls, "onVerificationAborted", "(Ljava/lang/String;I)V");
-            }
-
-            if (!midL)
-            {
-                releaseEnv();
-                return;
-            }
-
-            jstring jUid = env->NewStringUTF(uId.c_str());
+            // Create Java SimulatorResourceModel object
+            static jmethodID simulatorRequestModelCtor = env->GetMethodID(
+                        gSimulatorClassRefs.simulatorRequestModelCls, "<init>",
+                        "(Lorg/oic/simulator/client/SimulatorRemoteResource$RequestType;"
+                        "Ljava/util/Map;Lorg/oic/simulator/ModelProperty;)V");
 
-            env->CallVoidMethod(onVerificationListener, midL, jUid, (jint)id);
-
-            if (env->ExceptionCheck())
-            {
-                releaseEnv();
-            }
+            return env->NewObject(gSimulatorClassRefs.simulatorRequestModelCls,
+                                  simulatorRequestModelCtor, jRequestType,
+                                  jQueryParams.get(), jRequestBodyModel);
         }
-
-    private:
-        jweak m_listener;
-
 };
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_startObserve
-(JNIEnv *env, jobject thiz, jint observeType, jobject jQueryParamsMap, jobject jListener)
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeGet
+(JNIEnv *env, jobject object, jstring jResInterface, jobject jQueryParams, jobject jListener)
 {
-    if (!jListener)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
-        return;
-    }
-
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
-
-    std::map<std::string, std::string> queryParams;
-    if (jQueryParamsMap)
-        convertJavaMapToQueryParamsMap(env, jQueryParamsMap, queryParams);
+    VALIDATE_CALLBACK(env, jListener)
 
-    ObserveType type = ObserveType::OBSERVE;
-    if (1 == observeType)
-        type = ObserveType::OBSERVE_ALL;
-
-    JNIOnObserveListener *onObserveListener = new JNIOnObserveListener();
-    onObserveListener->setJavaOnObserveListener(env, jListener);
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
     try
     {
-        resource->observe(type,
-                          std::bind(&JNIOnObserveListener::onObserveCallback,
-                                    onObserveListener, std::placeholders::_1,
-                                    std::placeholders::_2, std::placeholders::_3,
-                                    std::placeholders::_4));
+        JniString jniInterface(env, jResInterface);
+        std::map<std::string, std::string> queryParams =
+            JniQueryParameter(env).toCpp(jQueryParams);
+
+        SimulatorRemoteResource::ResponseCallback callback =  std::bind([](
+                    const std::string & uid, SimulatorResult result,
+                    const SimulatorResourceModel & resModel,
+                    const std::shared_ptr<JniListenerHolder> &listenerRef)
+        {
+            onGetCallback(listenerRef->get(), uid, result, resModel);
+        }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+        JniListenerHolder::create(env, jListener));
+
+        resource->get(jniInterface.get(), queryParams, callback);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
-    }
-    catch (SimulatorException &e)
-    {
-        throwSimulatorException(env, e.code(), e.what());
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
-}
-
-JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_stopObserve
-(JNIEnv *env, jobject thiz)
-{
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
-
-    try
+    catch (NoSupportException &e)
     {
-        resource->cancelObserve();
+        ThrowNoSupportException(env, e.what());
     }
     catch (SimulatorException &e)
     {
-        throwSimulatorException(env, e.code(), e.what());
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
+        ThrowSimulatorException(env, e.code(), e.what());
     }
 }
 
 JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_nativeGet
-(JNIEnv *env, jobject thiz, jstring jResourceInterface,
- jobject jQueryParamsMap, jobject jListener)
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativePut
+(JNIEnv *env, jobject object, jstring jResInterface, jobject jQueryParams,
+ jobject jRepresentation, jobject jListener)
 {
-    if (!jListener)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
-        return;
-    }
+    VALIDATE_CALLBACK(env, jListener)
 
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
-    // Interface type
-    const char *interfaceCStr = NULL;
-    std::string interfaceType;
-    if (jResourceInterface)
+    try
     {
-        interfaceCStr = env->GetStringUTFChars(jResourceInterface, NULL);
-        interfaceType = interfaceCStr;
-    }
+        JniString jniInterface(env, jResInterface);
+        std::map<std::string, std::string> queryParams =
+            JniQueryParameter(env).toCpp(jQueryParams);
 
-    // Query parameters
-    std::map<std::string, std::string> queryParams;
-    if (jQueryParamsMap)
-        convertJavaMapToQueryParamsMap(env, jQueryParamsMap, queryParams);
+        SimulatorResourceModel resModel;
+        SimulatorResourceModelToCpp(env, jRepresentation, resModel);
 
-    // Create listener
-    JNIOnGetListener *onGetListener = new JNIOnGetListener();
-    onGetListener->setJavaOnGetListener(env, jListener);
+        SimulatorRemoteResource::ResponseCallback callback =  std::bind([](
+                    const std::string & uid, SimulatorResult result,
+                    const SimulatorResourceModel & resModel,
+                    const std::shared_ptr<JniListenerHolder> &listenerRef)
+        {
+            onPutCallback(listenerRef->get(), uid, result, resModel);
+        }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+        JniListenerHolder::create(env, jListener));
 
-    try
-    {
-        resource->get(interfaceType,
-                      queryParams,
-                      std::bind(&JNIOnGetListener::onGetCallback,
-                                onGetListener, std::placeholders::_1,
-                                std::placeholders::_2, std::placeholders::_3));
+        resource->put(jniInterface.get(), queryParams, resModel, callback);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
-        return;
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
     catch (NoSupportException &e)
     {
-        throwNoSupportException(env, e.code(), e.what());
-        return;
+        ThrowNoSupportException(env, e.what());
     }
     catch (SimulatorException &e)
     {
-        throwSimulatorException(env, e.code(), e.what());
-        return;
+        ThrowSimulatorException(env, e.code(), e.what());
     }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
-        return;
-    }
-
-    if (interfaceCStr)
-        env->ReleaseStringUTFChars(jResourceInterface, interfaceCStr);
 }
 
 JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_nativePut
-(JNIEnv *env, jobject thiz, jstring jResourceInterface,
- jobject jRepresentation, jobject jQueryParamsMap, jobject jListener)
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativePost
+(JNIEnv *env, jobject object, jstring jResInterface, jobject jQueryParams,
+ jobject jRepresentation, jobject jListener)
 {
-    if (!jListener)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
-        return;
-    }
+    VALIDATE_CALLBACK(env, jListener)
 
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
-    // Interface type
-    const char *interfaceCStr = NULL;
-    std::string interfaceType;
-    if (jResourceInterface)
+    try
     {
-        interfaceCStr = env->GetStringUTFChars(jResourceInterface, NULL);
-        interfaceType = interfaceCStr;
-    }
+        JniString jniInterface(env, jResInterface);
+        std::map<std::string, std::string> queryParams =
+            JniQueryParameter(env).toCpp(jQueryParams);
 
-    // Query parameters
-    std::map<std::string, std::string> queryParams;
-    if (jQueryParamsMap)
-        convertJavaMapToQueryParamsMap(env, jQueryParamsMap, queryParams);
+        SimulatorResourceModel resModel;
+        SimulatorResourceModelToCpp(env, jRepresentation, resModel);
 
-    SimulatorResourceModelSP resourceModel =
-        JSimulatorResourceModel::getResourceModelPtr(env, jRepresentation);
-
-    // Create listener
-    JNIOnPutListener *onPutListener = new JNIOnPutListener();
-    onPutListener->setJavaOnPutListener(env, jListener);
+        SimulatorRemoteResource::ResponseCallback callback =  std::bind([](
+                    const std::string & uid, SimulatorResult result,
+                    const SimulatorResourceModel & resModel,
+                    const std::shared_ptr<JniListenerHolder> &listenerRef)
+        {
+            onPostCallback(listenerRef->get(), uid, result, resModel);
+        }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+        JniListenerHolder::create(env, jListener));
 
-    try
-    {
-        resource->put(interfaceType,
-                      queryParams,
-                      resourceModel,
-                      std::bind(&JNIOnPutListener::onPutCallback,
-                                onPutListener, std::placeholders::_1,
-                                std::placeholders::_2, std::placeholders::_3));
+        resource->post(jniInterface.get(), queryParams, resModel, callback);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
-        return;
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
     catch (NoSupportException &e)
     {
-        throwNoSupportException(env, e.code(), e.what());
-        return;
+        ThrowNoSupportException(env, e.what());
     }
     catch (SimulatorException &e)
     {
-        throwSimulatorException(env, e.code(), e.what());
-        return;
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
-        return;
+        ThrowSimulatorException(env, e.code(), e.what());
     }
-
-    if (interfaceCStr)
-        env->ReleaseStringUTFChars(jResourceInterface, interfaceCStr);
 }
 
-JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_nativePost
-(JNIEnv *env, jobject thiz, jstring jResourceInterface,
- jobject jRepresentation, jobject jQueryParamsMap, jobject jListener)
+JNIEXPORT jobject JNICALL
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeSetConfigInfo
+(JNIEnv *env, jobject object, jstring jConfigPath)
 {
-    if (!jListener)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
-        return;
-    }
+    VALIDATE_INPUT_RET(env, !jConfigPath, "Path is null!", nullptr)
 
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT_RET(env, resource, nullptr)
 
-    // Interface type
-    const char *interfaceCStr = NULL;
-    std::string interfaceType;
-    if (jResourceInterface)
+    try
     {
-        interfaceCStr = env->GetStringUTFChars(jResourceInterface, NULL);
-        interfaceType = interfaceCStr;
-    }
+        JniString jniConfigPath(env, jConfigPath);
+        std::map<RequestType, SimulatorRequestModel> requestModels =
+            resource->configure(jniConfigPath.get());
 
-    // Query parameters
-    std::map<std::string, std::string> queryParams;
-    if (jQueryParamsMap)
-        convertJavaMapToQueryParamsMap(env, jQueryParamsMap, queryParams);
+        JniMap jRequestModelsMap(env);
 
-    SimulatorResourceModelSP resourceModel =
-        JSimulatorResourceModel::getResourceModelPtr(env, jRepresentation);
+        // Add entry to map
+        for (auto &requestModelEntry : requestModels)
+        {
+            jobject jRequestType = JniRequestType::toJava(env, requestModelEntry.first);
+            jobject jRequestModel = JniSimulatorRequestModel::toJava(env, requestModelEntry.second);
 
-    // Create listener
-    JNIOnPostListener *onPostListener = new JNIOnPostListener();
-    onPostListener->setJavaOnPostListener(env, jListener);
+            jRequestModelsMap.put(jRequestType, jRequestModel);
+        }
 
-    try
-    {
-        resource->post(interfaceType,
-                       queryParams,
-                       resourceModel,
-                       std::bind(&JNIOnPostListener::onPostCallback,
-                                 onPostListener, std::placeholders::_1,
-                                 std::placeholders::_2, std::placeholders::_3));
+        return jRequestModelsMap.get();
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
-        return;
-    }
-    catch (NoSupportException &e)
-    {
-        throwNoSupportException(env, e.code(), e.what());
-        return;
-    }
-    catch (SimulatorException &e)
-    {
-        throwSimulatorException(env, e.code(), e.what());
-        return;
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
-        return;
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
 
-    if (interfaceCStr)
-        env->ReleaseStringUTFChars(jResourceInterface, interfaceCStr);
+    return nullptr;
 }
 
 JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_setConfigInfo
-(JNIEnv *env, jobject thiz, jstring jConfigPath)
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeStartObserve
+(JNIEnv *env, jobject object, jobject jQueryParams, jobject jListener)
 {
-    if (!jConfigPath)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_PARAM,
-                                  "Configuration file path is null!");
-        return;
-    }
-
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
+    VALIDATE_CALLBACK(env, jListener)
 
-    // Interface type
-    const char *configCStr = NULL;
-    std::string configPath;
-    if (jConfigPath)
-    {
-        configCStr = env->GetStringUTFChars(jConfigPath, NULL);
-        configPath = configCStr;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
     try
     {
-        resource->configure(configPath);
+        std::map<std::string, std::string> queryParams =
+            JniQueryParameter(env).toCpp(jQueryParams);
+
+        SimulatorRemoteResource::ObserveNotificationCallback callback =  std::bind([](
+                    const std::string & uid, SimulatorResult result,
+                    const SimulatorResourceModel & representation, const int seq,
+                    const std::shared_ptr<JniListenerHolder> &listenerRef)
+        {
+            onObserveCallback(listenerRef->get(), uid, result, representation, seq);
+        }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+        std::placeholders::_4, JniListenerHolder::create(env, jListener));
+
+        resource->observe(ObserveType::OBSERVE, callback);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
-        return;
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
-    catch (...)
+    catch (SimulatorException &e)
     {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
-        return;
+        ThrowSimulatorException(env, e.code(), e.what());
     }
-
-    if (configCStr)
-        env->ReleaseStringUTFChars(jConfigPath, configCStr);
 }
 
-JNIEXPORT jint JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_startVerification
-(JNIEnv *env, jobject thiz, jint jReqType, jobject jListener)
+JNIEXPORT void JNICALL
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeStopObserve
+(JNIEnv *env, jobject object)
 {
-    if (!jListener)
-    {
-        throwInvalidArgsException(env, SIMULATOR_INVALID_CALLBACK, "Invalid callback!");
-        return SIMULATOR_INVALID_CALLBACK;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
+    try
     {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return SIMULATOR_BAD_OBJECT;
+        resource->cancelObserve();
     }
-
-    // Convert RequestType
-    RequestType reqType;
-
-    switch (jReqType)
+    catch (SimulatorException &e)
     {
-        case 0:
-            reqType = RequestType::RQ_TYPE_GET;
-            break;
-
-        case 1:
-            reqType = RequestType::RQ_TYPE_PUT;
-            break;
-
-        case 2:
-            reqType = RequestType::RQ_TYPE_POST;
-            break;
-
-        case 3:
-            reqType = RequestType::RQ_TYPE_DELETE;
-            break;
-
-        default:
-            return -1;
+        ThrowSimulatorException(env, e.code(), e.what());
     }
+}
 
-    // Create listener
-    JNIOnVerificationListener *onVerificationListener = new JNIOnVerificationListener();
-    onVerificationListener->setJavaOnVerificationListener(env, jListener);
+JNIEXPORT jint JNICALL
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeStartAutoRequesting
+(JNIEnv *env, jobject object, jobject jRequestType, jobject jListener)
+{
+    VALIDATE_CALLBACK_RET(env, jListener, -1)
 
-    int automationId = -1;
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT_RET(env, resource, -1)
 
     try
     {
-        automationId = resource->startVerification(reqType,
-                       std::bind(&JNIOnVerificationListener::onVerificationCallback,
-                                 onVerificationListener, std::placeholders::_1,
-                                 std::placeholders::_2, std::placeholders::_3));
+        RequestType type = JniRequestType::toCpp(env, jRequestType);
+        SimulatorRemoteResource::AutoRequestGenerationCallback callback =  std::bind([](
+                    const std::string & uid, int id, OperationState opState,
+                    const std::shared_ptr<JniListenerHolder> &listenerRef)
+        {
+            onVerificationCallback(listenerRef->get(), uid, id, opState);
+        }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+        JniListenerHolder::create(env, jListener));
+
+        return resource->startAutoRequesting(type, callback);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
     catch (NoSupportException &e)
     {
-        throwNoSupportException(env, e.code(), e.what());
+        ThrowNoSupportException(env, e.what());
     }
     catch (OperationInProgressException &e)
     {
-        throwOperationInProgressException(env, e.code(), e.what());
+        ThrowOperationInProgressException(env, e.what());
     }
     catch (SimulatorException &e)
     {
-        throwSimulatorException(env, e.code(), e.what());
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
+        ThrowSimulatorException(env, e.code(), e.what());
     }
 
-    return automationId;
+    return -1;
 }
 
 JNIEXPORT void JNICALL
-Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_stopVerification
-(JNIEnv *env, jobject thiz, jint jId)
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeStopAutoRequesting
+(JNIEnv *env, jobject object, jint id)
 {
-    SimulatorRemoteResourceSP resource = JniSimulatorRemoteResource::getResourceHandle(env,
-                                         thiz);
-    if (!resource)
-    {
-        throwSimulatorException(env, SIMULATOR_BAD_OBJECT, "No resource!");
-        return;
-    }
+    SimulatorRemoteResourceSP resource = simulatorRemoteResourceToCpp(env, object);
+    VALIDATE_OBJECT(env, resource)
 
     try
     {
-        resource->stopVerification((int)jId);
+        resource->stopAutoRequesting(id);
     }
     catch (InvalidArgsException &e)
     {
-        throwInvalidArgsException(env, e.code(), e.what());
+        ThrowInvalidArgsException(env, e.code(), e.what());
     }
     catch (NoSupportException &e)
     {
-        throwNoSupportException(env, e.code(), e.what());
-    }
-    catch (...)
-    {
-        throwSimulatorException(env, SIMULATOR_ERROR, "Unknown Exception");
+        ThrowNoSupportException(env, e.what());
     }
 }
 
-JNIEXPORT void JNICALL Java_org_oic_simulator_clientcontroller_SimulatorRemoteResource_dispose
-(JNIEnv *env, jobject thiz)
+JNIEXPORT void JNICALL
+Java_org_oic_simulator_client_SimulatorRemoteResource_nativeDispose
+(JNIEnv *env, jobject object)
 {
-    JniSimulatorRemoteResource *resource = GetHandle<JniSimulatorRemoteResource>(env, thiz);
+    JniSharedObjectHolder<SimulatorRemoteResource> *resource =
+        getHandle<JniSharedObjectHolder<SimulatorRemoteResource>>(env, object);
     delete resource;
-}
\ No newline at end of file
+}
+
+#ifdef __cplusplus
+}
+#endif