Merge tizen_5.0 codes into tizen_4.0
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOnMQSubscribeListener.cpp
1 /* ****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "JniOnMQSubscribeListener.h"
22 #include "JniOcResource.h"
23 #include "JniOcRepresentation.h"
24 #include "JniUtils.h"
25
26 JniOnMQSubscribeListener::JniOnMQSubscribeListener(JNIEnv *env,
27                                                    jobject jListener,
28                                                    RemoveListenerCallback removeListener)
29     : m_removeListener(removeListener)
30 {
31     m_jwListener = env->NewWeakGlobalRef(jListener);
32 }
33
34 JniOnMQSubscribeListener::~JniOnMQSubscribeListener()
35 {
36     if (m_jwListener)
37     {
38         jint ret = JNI_ERR;
39         JNIEnv *env = GetJNIEnv(ret);
40         if (nullptr == env)
41         {
42             return;
43         }
44
45         env->DeleteWeakGlobalRef(m_jwListener);
46         m_jwListener = nullptr;
47
48         if (JNI_EDETACHED == ret)
49         {
50             g_jvm->DetachCurrentThread();
51         }
52     }
53 }
54
55 void JniOnMQSubscribeListener::onSubscribeCallback(const HeaderOptions headerOptions,
56     const OCRepresentation& ocRepresentation, const int& eCode, const int& sequenceNumber)
57 {
58     jint envRet = JNI_ERR;
59     JNIEnv *env = GetJNIEnv(envRet);
60     if (nullptr == env)
61     {
62         return;
63     }
64
65     jobject jListener = env->NewLocalRef(m_jwListener);
66     if (!jListener)
67     {
68         checkExAndRemoveListener(env);
69         if (JNI_EDETACHED == envRet)
70         {
71             g_jvm->DetachCurrentThread();
72         }
73         return;
74     }
75     jclass clsL = env->GetObjectClass(jListener);
76     if (!clsL)
77     {
78         env->DeleteLocalRef(jListener);
79         checkExAndRemoveListener(env);
80         if (JNI_EDETACHED == envRet)
81         {
82             g_jvm->DetachCurrentThread();
83         }
84         return;
85     }
86
87     if (OC_STACK_OK != eCode && OC_STACK_RESOURCE_CREATED != eCode &&
88             OC_STACK_RESOURCE_DELETED != eCode && OC_STACK_RESOURCE_CHANGED != eCode)
89     {
90         jobject ex = GetOcException(eCode, "stack error in onSubScribeCallback");
91         if (!ex)
92         {
93             goto JNI_EXIT;
94         }
95         jmethodID midL = env->GetMethodID(clsL, "onSubScribeFailed", "(Ljava/lang/Throwable;)V");
96         if (!midL)
97         {
98             goto JNI_EXIT;
99         }
100
101         env->CallVoidMethod(jListener, midL, ex);
102     }
103     else
104     {
105         OCRepresentation * rep = new OCRepresentation(ocRepresentation);
106         jlong handle = reinterpret_cast<jlong>(rep);
107         jobject jRepresentation = env->NewObject(g_cls_OcRepresentation,
108             g_mid_OcRepresentation_N_ctor_bool, handle, true);
109         if (!jRepresentation)
110         {
111             delete rep;
112             goto JNI_EXIT;
113         }
114
115         if (sequenceNumber != 1 + MAX_SEQUENCE_NUMBER)
116         {
117             jmethodID midL = env->GetMethodID(clsL, "onSubScribeCompleted",
118                         "(Ljava/util/List;Lorg/iotivity/base/OcRepresentation;I)V");
119             if (!midL)
120             {
121                 delete rep;
122                 env->DeleteLocalRef(jRepresentation);
123                 goto JNI_EXIT;
124             }
125
126             jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env,
127                                                                                        headerOptions);
128             if (!jHeaderOptionList)
129             {
130                 delete rep;
131                 env->DeleteLocalRef(jRepresentation);
132                 goto JNI_EXIT;
133             }
134
135             env->CallVoidMethod(jListener, midL, jHeaderOptionList, jRepresentation,
136                 static_cast<jint>(sequenceNumber));
137             if (env->ExceptionCheck())
138             {
139                 LOGE("Java exception is thrown");
140                 delete rep;
141                 env->DeleteLocalRef(jRepresentation);
142                 env->DeleteLocalRef(jHeaderOptionList);
143                 jthrowable ex = env->ExceptionOccurred();
144                 env->ExceptionClear();
145                 m_ownerResource->removeOnMQTopicSubscribeListener(env, m_jwListener);
146                 env->Throw((jthrowable)ex);
147             }
148         }
149         else
150         {
151             jmethodID midL = env->GetMethodID(clsL, "onUnsubScribeCompleted",
152                         "(Lorg/iotivity/base/OcRepresentation;I)V");
153             if (!midL)
154             {
155                 delete rep;
156                 env->DeleteLocalRef(jRepresentation);
157                 goto JNI_EXIT;
158             }
159
160             env->CallVoidMethod(jListener, midL, jRepresentation,
161                         static_cast<jint>(sequenceNumber));
162             if (env->ExceptionCheck())
163             {
164                 LOGE("Java exception is thrown");
165                 delete rep;
166                 env->DeleteLocalRef(jRepresentation);
167                 jthrowable ex = env->ExceptionOccurred();
168                 env->ExceptionClear();
169                 m_ownerResource->removeOnMQTopicSubscribeListener(env, m_jwListener);
170                 env->Throw((jthrowable)ex);
171             }
172
173             checkExAndRemoveListener(env);
174         }
175     }
176
177     env->DeleteLocalRef(clsL);
178     env->DeleteLocalRef(jListener);
179     if (JNI_EDETACHED == envRet)
180     {
181         g_jvm->DetachCurrentThread();
182     }
183     return;
184
185 JNI_EXIT:
186     env->DeleteLocalRef(clsL);
187     env->DeleteLocalRef(jListener);
188     checkExAndRemoveListener(env);
189     if (JNI_EDETACHED == envRet)
190     {
191         g_jvm->DetachCurrentThread();
192     }
193 }
194
195 void JniOnMQSubscribeListener::checkExAndRemoveListener(JNIEnv* env)
196 {
197     if (env->ExceptionCheck())
198     {
199         jthrowable ex = env->ExceptionOccurred();
200         env->ExceptionClear();
201         m_removeListener(env, m_jwListener);
202         env->Throw((jthrowable)ex);
203     }
204     else
205     {
206         m_removeListener(env, m_jwListener);
207     }
208 }