Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOcResource.cpp
index 9d30ba2..f376cdd 100644 (file)
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
 
-JniOcResource::JniOcResource(std::shared_ptr<OCResource> resource)
-    : m_sharedResource(resource)
-{
-}
+class JniOcResourceImpl : public std::enable_shared_from_this<JniOcResourceImpl>
+{
+public:
+    typedef std::shared_ptr<JniOcResourceImpl> Ptr;
+
+    JniOcResourceImpl(std::shared_ptr<OCResource> &resource);
+    ~JniOcResourceImpl();
+
+    OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+        QualityOfService QoS);
+    OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService QoS);
+    OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService QoS);
+    OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult deleteResource(JNIEnv* env, jobject jListener);
+    OCStackResult deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS);
+
+    OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService qos);
+
+    OCStackResult cancelObserve(JNIEnv* env);
+    OCStackResult cancelObserve(JNIEnv* env, QualityOfService qos);
+
+    void setHeaderOptions(const HeaderOptions &headerOptions);
+    void unsetHeaderOptions();
+    std::string host();
+    std::string uri();
+    OCConnectivityType connectivityType() const;
+    bool isObservable();
+    std::vector< std::string >  getResourceTypes() const;
+    std::vector< std::string >  getResourceInterfaces(void) const;
+    OCResourceIdentifier uniqueIdentifier() const;
+    std::string sid() const;
+    std::string deviceName() const;
+
+    JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener);
+    JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener);
+    JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener);
+    JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener);
+    JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener);
+
+    void removeOnGetListener(JNIEnv* env, jobject jListener);
+    void removeOnPutListener(JNIEnv* env, jobject jListener);
+    void removeOnPostListener(JNIEnv* env, jobject jListener);
+    void removeOnDeleteListener(JNIEnv* env, jobject jListener);
+    void removeOnObserveListener(JNIEnv* env, jobject jListener);
+
+    std::shared_ptr<OCResource> getOCResource();
+
+#ifdef WITH_MQ
+    JniOnMQTopicFoundListener* addOnTopicFoundListener(JNIEnv* env, jobject jListener);
+    void removeOnTopicFoundListener(JNIEnv* env, jobject jListener);
+
+    JniOnMQSubscribeListener* addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
+    void removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
+
+    OCStackResult discoveryMQTopics(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                    jobject jListener, QualityOfService QoS);
+    OCStackResult createMQTopic(JNIEnv* env, const OCRepresentation &representation,
+                                const std::string &targetUri,
+                                const QueryParamsMap &queryParametersMap,
+                                jobject jListener, QualityOfService QoS);
+#endif
+#ifdef MQ_SUBSCRIBER
+    OCStackResult subscribeMQTopic(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                   jobject jListener, QualityOfService QoS);
+    OCStackResult unsubscribeMQTopic(QualityOfService QoS);
+    OCStackResult requestMQPublish(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                   jobject jListener, QualityOfService QoS);
+#endif
+#ifdef MQ_PUBLISHER
+    OCStackResult publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+                                 const QueryParamsMap &queryParametersMap,
+                                 jobject jListener, QualityOfService QoS);
+#endif
+
+private:
+
+    static void onGetCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                              const int eCode, JniOnGetListener *listener,
+                              std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onPutCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                              const int eCode, JniOnPutListener *listener,
+                              std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onPostCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                               const int eCode, JniOnPostListener *listener,
+                               std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onDeleteCallback(const HeaderOptions& opts,
+                                 const int eCode, JniOnDeleteListener *listener,
+                                 std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onObserveCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                  const int eCode, const int& sequenceNumber,
+                                  JniOnObserveListener *listener,
+                                  std::weak_ptr<JniOcResourceImpl> weakRef);
+
+
+    JniListenerManager<JniOnGetListener> m_onGetManager;
+    JniListenerManager<JniOnPutListener> m_onPutManager;
+    JniListenerManager<JniOnPostListener> m_onPostManager;
+    JniListenerManager<JniOnDeleteListener> m_onDeleteManager;
+    JniListenerManager<JniOnObserveListener> m_onObserveManager;
+#ifdef WITH_MQ
+    JniListenerManager<JniOnMQTopicFoundListener> m_onFoundTopicResourceManager;
+    JniListenerManager<JniOnMQSubscribeListener> m_onSubcribeTopicManager;
+#endif
+
+    std::shared_ptr<OCResource> m_sharedResource;
+};
 
-JniOcResource::~JniOcResource()
+JniOcResourceImpl::JniOcResourceImpl(std::shared_ptr<OCResource> &resource)
+    : m_sharedResource(resource) {}
+
+JniOcResourceImpl::~JniOcResourceImpl()
 {
-    LOGD("~JniOcResource()");
+    LOGD("~JniOcResourceImpl()");
 
     m_sharedResource = nullptr;
 
@@ -58,36 +191,44 @@ JniOcResource::~JniOcResource()
     }
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
+void JniOcResourceImpl::onGetCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnGetListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Get callback called on deleted object\n");
+        return;
+    }
+
+    listener->onGetCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](
-        const HeaderOptions& opts,
-        const OCRepresentation& rep,
-        const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(queryParametersMap, getCallback);
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
     QualityOfService QoS)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts, const OCRepresentation& rep,
-        const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(queryParametersMap, getCallback, QoS);
 }
 
-OCStackResult JniOcResource::get(
+OCStackResult JniOcResourceImpl::get(
     JNIEnv* env,
     const std::string &resourceType,
     const std::string &resourceInterface,
@@ -96,206 +237,238 @@ OCStackResult JniOcResource::get(
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap,
         getCallback);
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const QueryParamsMap &queryParametersMap,
     jobject jListener, QualityOfService QoS)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap,
         getCallback, QoS);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+void JniOcResourceImpl::onPutCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnPutListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Put callback called on deleted object\n");
+        return;
+    }
+
+    listener->onPutCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(representation, queryParametersMap, putCallback);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(representation, queryParametersMap, putCallback, QoS);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(resourceType, resourceInterface, representation,
         queryParametersMap, putCallback);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(resourceType, resourceInterface, representation,
         queryParametersMap, putCallback, QoS);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+void JniOcResourceImpl::onPostCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnPostListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Post callback called on deleted object\n");
+        return;
+    }
+
+    listener->onPostCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(representation, queryParametersMap, postCallback);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(representation, queryParametersMap, postCallback, QoS);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(resourceType, resourceInterface, representation,
         queryParametersMap, postCallback);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(resourceType, resourceInterface, representation,
         queryParametersMap, postCallback, QoS);
 }
 
-OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::onDeleteCallback(const HeaderOptions& opts,
+                                      const int eCode, JniOnDeleteListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Delete callback called on deleted object\n");
+        return;
+    }
+
+    listener->onDeleteCallback(opts, eCode);
+}
+
+OCStackResult JniOcResourceImpl::deleteResource(JNIEnv* env, jobject jListener)
 {
     JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener);
 
-    DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts,
-        const int eCode)
-    {
-        onDeleteListener->onDeleteCallback(opts, eCode);
-    };
+    DeleteCallback deleteCallback = std::bind(JniOcResourceImpl::onDeleteCallback, std::placeholders::_1,
+                                        std::placeholders::_2, onDeleteListener,
+                                        shared_from_this());
 
     return m_sharedResource->deleteResource(deleteCallback);
 }
 
-OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
+OCStackResult JniOcResourceImpl::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
 {
     JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener);
 
-    DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, const int eCode)
-    {
-        onDeleteListener->onDeleteCallback(opts, eCode);
-    };
+    DeleteCallback deleteCallback = std::bind(JniOcResourceImpl::onDeleteCallback, std::placeholders::_1,
+                                        std::placeholders::_2, onDeleteListener,
+                                        shared_from_this());
 
     return m_sharedResource->deleteResource(deleteCallback, QoS);
 }
 
-OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+void JniOcResourceImpl::onObserveCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, const int& sequenceNumber,
+                                      JniOnObserveListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Observe callback called on deleted object\n");
+        return;
+    }
+
+    listener->onObserveCallback(opts, rep, eCode, sequenceNumber);
+}
+
+OCStackResult JniOcResourceImpl::observe(JNIEnv* env, ObserveType observeType,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener);
 
-    ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
-    {
-        onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber);
-    };
+    ObserveCallback observeCallback = std::bind(JniOcResourceImpl::onObserveCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3,
+                                        std::placeholders::_4, onObserveListener,
+                                        shared_from_this());
 
     return m_sharedResource->observe(observeType, queryParametersMap, observeCallback);
 }
 
-OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+OCStackResult JniOcResourceImpl::observe(JNIEnv* env, ObserveType observeType,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener);
 
-    ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
-    {
-        onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber);
-    };
+    ObserveCallback observeCallback = std::bind(JniOcResourceImpl::onObserveCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3,
+                                        std::placeholders::_4, onObserveListener,
+                                        shared_from_this());
 
     return m_sharedResource->observe(observeType, queryParametersMap, observeCallback, QoS);
 }
 
-OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
+OCStackResult JniOcResourceImpl::cancelObserve(JNIEnv* env, QualityOfService qos)
 {
     // In Low case, after delete the callback and send empty message when client receive the notify.
     // But TCP does not support EMPTY message.
@@ -306,178 +479,197 @@ OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
     return m_sharedResource->cancelObserve(qos);
 }
 
-void JniOcResource::setHeaderOptions(const HeaderOptions &headerOptions)
+void JniOcResourceImpl::setHeaderOptions(const HeaderOptions &headerOptions)
 {
     m_sharedResource->setHeaderOptions(headerOptions);
 }
 
-void JniOcResource::unsetHeaderOptions()
+void JniOcResourceImpl::unsetHeaderOptions()
 {
     m_sharedResource->unsetHeaderOptions();
 }
 
-std::string JniOcResource::host()
+std::string JniOcResourceImpl::host()
 {
     return m_sharedResource->host();
 }
 
-std::string JniOcResource::uri()
+std::string JniOcResourceImpl::uri()
 {
     return m_sharedResource->uri();
 }
 
-OCConnectivityType JniOcResource::connectivityType() const
+OCConnectivityType JniOcResourceImpl::connectivityType() const
 {
     return m_sharedResource->connectivityType();
 }
 
-bool JniOcResource::isObservable()
+bool JniOcResourceImpl::isObservable()
 {
     return m_sharedResource->isObservable();
 }
 
-std::vector< std::string > JniOcResource::getResourceTypes() const
+std::vector< std::string > JniOcResourceImpl::getResourceTypes() const
 {
     return m_sharedResource->getResourceTypes();
 }
 
-std::vector< std::string > JniOcResource::getResourceInterfaces(void) const
+std::vector< std::string > JniOcResourceImpl::getResourceInterfaces(void) const
 {
     return m_sharedResource->getResourceInterfaces();
 }
 
-OCResourceIdentifier JniOcResource::uniqueIdentifier() const
+OCResourceIdentifier JniOcResourceImpl::uniqueIdentifier() const
 {
     return m_sharedResource->uniqueIdentifier();
 }
 
-std::string JniOcResource::sid() const
+std::string JniOcResourceImpl::sid() const
 {
     return m_sharedResource->sid();
 }
 
-std::string JniOcResource::deviceName() const
+std::string JniOcResourceImpl::deviceName() const
 {
     return m_sharedResource->deviceName();
 }
 
-JniOnGetListener* JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener)
+JniOnGetListener* JniOcResourceImpl::addOnGetListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onGetManager.addListener(env, jListener, this);
+    return this->m_onGetManager.addListener(env, jListener,
+                                            std::bind(&JniOcResourceImpl::removeOnGetListener, this,
+                                            std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnPutListener* JniOcResource::addOnPutListener(JNIEnv* env, jobject jListener)
+JniOnPutListener* JniOcResourceImpl::addOnPutListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onPutManager.addListener(env, jListener, this);
+    return this->m_onPutManager.addListener(env, jListener,
+                                            std::bind(&JniOcResourceImpl::removeOnPutListener, this,
+                                            std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnPostListener* JniOcResource::addOnPostListener(JNIEnv* env, jobject jListener)
+JniOnPostListener* JniOcResourceImpl::addOnPostListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onPostManager.addListener(env, jListener, this);
+    return this->m_onPostManager.addListener(env, jListener,
+                                             std::bind(&JniOcResourceImpl::removeOnPostListener, this,
+                                             std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnDeleteListener* JniOcResource::addOnDeleteListener(JNIEnv* env, jobject jListener)
+JniOnDeleteListener* JniOcResourceImpl::addOnDeleteListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onDeleteManager.addListener(env, jListener, this);
+    return this->m_onDeleteManager.addListener(env, jListener,
+                                               std::bind(&JniOcResourceImpl::removeOnDeleteListener, this,
+                                               std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnObserveListener* JniOcResource::addOnObserveListener(JNIEnv* env, jobject jListener)
+JniOnObserveListener* JniOcResourceImpl::addOnObserveListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onObserveManager.addListener(env, jListener, this);
+    return this->m_onObserveManager.addListener(env, jListener,
+                                                std::bind(&JniOcResourceImpl::removeOnObserveListener, this,
+                                                std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnGetListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnGetListener(JNIEnv* env, jobject jListener)
 {
     this->m_onGetManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnPutListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnPutListener(JNIEnv* env, jobject jListener)
 {
     this->m_onPutManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnPostListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnPostListener(JNIEnv* env, jobject jListener)
 {
     this->m_onPostManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnDeleteListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnDeleteListener(JNIEnv* env, jobject jListener)
 {
     this->m_onDeleteManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnObserveListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnObserveListener(JNIEnv* env, jobject jListener)
 {
     this->m_onObserveManager.removeListener(env, jListener);
 }
 
 #ifdef WITH_MQ
-JniOnMQTopicFoundListener* JniOcResource::addOnTopicFoundListener(JNIEnv* env, jobject jListener)
+JniOnMQTopicFoundListener* JniOcResourceImpl::addOnTopicFoundListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onFoundTopicResourceManager.addListener(env, jListener, this);
+    return this->m_onFoundTopicResourceManager.addListener(env, jListener,
+                                                           std::bind(&JniOcResource::removeOnTopicFoundListener, this,
+                                                           std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnTopicFoundListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnTopicFoundListener(JNIEnv* env, jobject jListener)
 {
     this->m_onFoundTopicResourceManager.removeListener(env, jListener);
 }
 
-JniOnMQSubscribeListener* JniOcResource::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
+JniOnMQSubscribeListener* JniOcResourceImpl::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onSubcribeTopicManager.addListener(env, jListener, this);
+    return this->m_onSubcribeTopicManager.addListener(env, jListener,
+                                                      std::bind(&JniOcResource::removeOnMQTopicSubscribeListener, this
+                                                      std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
 {
     this->m_onSubcribeTopicManager.removeListener(env, jListener);
 }
 #endif
 
-std::shared_ptr<OCResource> JniOcResource::getOCResource()
+std::shared_ptr<OCResource> JniOcResourceImpl::getOCResource()
 {
     return this->m_sharedResource;
 }
 
-JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz)
-{
-    JniOcResource *resource = GetHandle<JniOcResource>(env, thiz);
-    if (env->ExceptionCheck())
-    {
-        LOGE("Failed to get native handle from OcResource");
-    }
-    if (!resource)
-    {
-        ThrowOcException(JNI_NO_NATIVE_POINTER, "");
-    }
-    return resource;
-}
-
 #ifdef WITH_MQ
-OCStackResult JniOcResource::discoveryMQTopics(JNIEnv* env,
+OCStackResult JniOcResourceImpl::discoveryMQTopics(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQTopicFoundListener *onTopicFoundListener = addOnTopicFoundListener(env, jListener);
 
-    MQTopicCallback findCallback = [onTopicFoundListener](const int& eCode,
-            const std::string& uri, std::shared_ptr<OCResource> resource)
+    MQTopicCallback findCallback = std::bind([](const int& eCode,
+                                                const std::string& uri, std::shared_ptr<OCResource> resource,
+                                                JniOnMQTopicFoundListener *listener,
+                                                std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onTopicFoundListener->foundTopicCallback(eCode, uri, resource);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Topic callback called on deleted object\n");
+            return;
+        }
+        listener->foundTopicCallback(eCode, uri, resource);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+       onTopicFoundListener, shared_from_this());
 
     return m_sharedResource->discoveryMQTopics(queryParametersMap, findCallback, QoS);
 }
 
-OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
+OCStackResult JniOcResourceImpl::createMQTopic(JNIEnv* env,
     const OCRepresentation &representation, const std::string &targetUri,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQTopicFoundListener *onTopicCreatedListener = addOnTopicFoundListener(env, jListener);
 
-    MQTopicCallback createCallback = [onTopicCreatedListener](const int& eCode,
-            const std::string& uri, std::shared_ptr<OCResource> resource)
+    MQTopicCallback createCallback = std::bind([](const int& eCode,
+                                                  const std::string& uri,
+                                                  std::shared_ptr<OCResource> resource,
+                                                  JniOnMQTopicFoundListener *listener,
+                                                  std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onTopicCreatedListener->createdTopicCallback(eCode, uri, resource);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Topic callback called on deleted object\n");
+            return;
+        }
+        listener->createdTopicCallback(eCode, uri, resource);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+       onTopicCreatedListener, shared_from_this());
 
     return m_sharedResource->createMQTopic(representation, targetUri,
                                            queryParametersMap,
@@ -485,57 +677,290 @@ OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
 }
 #endif
 #ifdef MQ_SUBSCRIBER
-OCStackResult JniOcResource::subscribeMQTopic(JNIEnv* env,
+OCStackResult JniOcResourceImpl::subscribeMQTopic(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQSubscribeListener *onSubscribeListener = addOnMQTopicSubscribeListener(env, jListener);
 
-    ObserveCallback subscribeCallback = [onSubscribeListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
+    ObserveCallback subscribeCallback = std::bind([](const HeaderOptions& opts,
+                                                     const OCRepresentation& rep, const int& eCode,
+                                                     const int& sequenceNumber,
+                                                     JniOnMQSubscribeListener *listener,
+                                                     std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onSubscribeListener->onSubscribeCallback(opts, rep, eCode, sequenceNumber);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Subscribe MQ callback called on deleted object\n");
+            return;
+        }
+        listener->onSubscribeCallback(opts, rep, eCode, sequenceNumber);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4,
+       onSubscribeListener, shared_from_this());
 
     return m_sharedResource->subscribeMQTopic(ObserveType::Observe, queryParametersMap,
                                               subscribeCallback, QoS);
 }
 
-OCStackResult JniOcResource::unsubscribeMQTopic(QualityOfService QoS)
+OCStackResult JniOcResourceImpl::unsubscribeMQTopic(QualityOfService QoS)
 {
     return m_sharedResource->unsubscribeMQTopic(QoS);
 }
 
-OCStackResult JniOcResource::requestMQPublish(JNIEnv* env,
+OCStackResult JniOcResourceImpl::requestMQPublish(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->requestMQPublish(queryParametersMap, postCallback, QoS);
 }
 #endif
 #ifdef MQ_PUBLISHER
-OCStackResult JniOcResource::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->publishMQTopic(representation, queryParametersMap,
                                             postCallback, QoS);
 }
 #endif
 
+
+JniOcResource::JniOcResource(std::shared_ptr<OCResource> &resource)
+{
+    m_impl = std::make_shared<JniOcResourceImpl>(resource);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->get(env, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+    QualityOfService QoS)
+{
+    return m_impl->get(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::get(
+    JNIEnv* env,
+    const std::string &resourceType,
+    const std::string &resourceInterface,
+    const QueryParamsMap &queryParametersMap,
+    jobject jListener)
+{
+    return m_impl->get(env, resourceType, resourceInterface, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const QueryParamsMap &queryParametersMap,
+    jobject jListener, QualityOfService QoS)
+{
+    return m_impl->get(env, resourceType, resourceInterface, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->put(env, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->put(env, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->put(env, resourceType, resourceInterface, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->put(env, resourceType, resourceInterface, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->post(env, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->post(env, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->post(env, resourceType, resourceInterface, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->post(env, resourceType, resourceInterface, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener)
+{
+    return m_impl->deleteResource(env, jListener);
+}
+
+OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->deleteResource(env, jListener, QoS);
+}
+
+OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->observe(env, observeType, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->observe(env, observeType, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
+{
+    return m_impl->cancelObserve(env, qos);
+}
+
+void JniOcResource::setHeaderOptions(const HeaderOptions &headerOptions)
+{
+    m_impl->setHeaderOptions(headerOptions);
+}
+
+void JniOcResource::unsetHeaderOptions()
+{
+    m_impl->unsetHeaderOptions();
+}
+
+std::string JniOcResource::host()
+{
+    return m_impl->host();
+}
+
+std::string JniOcResource::uri()
+{
+    return m_impl->uri();
+}
+
+OCConnectivityType JniOcResource::connectivityType() const
+{
+    return m_impl->connectivityType();
+}
+
+bool JniOcResource::isObservable()
+{
+    return m_impl->isObservable();
+}
+
+std::vector< std::string > JniOcResource::getResourceTypes() const
+{
+    return m_impl->getResourceTypes();
+}
+
+std::vector< std::string > JniOcResource::getResourceInterfaces(void) const
+{
+    return m_impl->getResourceInterfaces();
+}
+
+OCResourceIdentifier JniOcResource::uniqueIdentifier() const
+{
+    return m_impl->uniqueIdentifier();
+}
+
+std::string JniOcResource::sid() const
+{
+    return m_impl->sid();
+}
+
+std::string JniOcResource::deviceName() const
+{
+    return m_impl->deviceName();
+}
+
+std::shared_ptr<OCResource> JniOcResource::getOCResource()
+{
+    return m_impl->getOCResource();
+}
+
+JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz)
+{
+    JniOcResource *resource = GetHandle<JniOcResource>(env, thiz);
+    if (env->ExceptionCheck())
+    {
+        LOGE("Failed to get native handle from OcResource");
+    }
+    if (!resource)
+    {
+        ThrowOcException(JNI_NO_NATIVE_POINTER, "");
+    }
+    return resource;
+}
+
+#ifdef WITH_MQ
+OCStackResult JniOcResource::discoveryMQTopics(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->discoveryMQTopics(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
+    const OCRepresentation &representation, const std::string &targetUri,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->createMQTopic(env, representation, targetUri, queryParametersMap, jListener, QoS);
+}
+#endif
+#ifdef MQ_SUBSCRIBER
+OCStackResult JniOcResource::subscribeMQTopic(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->subscribeMQTopic(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::unsubscribeMQTopic(QualityOfService QoS)
+{
+    return m_impl->unsubscribeMQTopic(QoS);
+}
+
+OCStackResult JniOcResource::requestMQPublish(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return  m_impl->requestMQPublish(env, queryParametersMap, jListener, QoS);
+}
+#endif
+#ifdef MQ_PUBLISHER
+OCStackResult JniOcResource::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->publishMQTopic(env, representation, queryParametersMap, jListener, QoS);
+}
+#endif
+
 /*
 * Class:     org_iotivity_base_OcResource
 * Method:    get