iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / QueryProcessor / ConditionedQuery.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 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 #include "ConditionedQuery.h"
21
22 SSMRESULT CConditionedQuery::finalConstruct()
23 {
24     SSMRESULT res = SSM_E_FAIL;
25
26     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_ITasker, (IBase **)&m_pTasker));
27     SSM_CLEANUP_ASSERT(CreateInstance(OID_IConditionedQueryResult,
28                                       (IBase **)&m_pConditionedQueryResult));
29
30     m_conditionedQueryEvent = NULL;
31
32     m_untrackedConditionsCount = 0;
33
34     m_reservedForActivate = false;
35
36     m_userTriggerId = 0;
37
38     m_targetDeviceDataId = -1;
39
40 CLEANUP:
41     return res;
42 }
43
44 void CConditionedQuery::finalRelease()
45 {
46     m_conditionedQueryEvent = NULL;
47
48     SAFE_RELEASE(m_pConditionedQueryResult);
49
50     for (std::vector<IConditionedModel *>::iterator itor = m_conditionedModels.begin();
51          itor != m_conditionedModels.end(); ++itor)
52     {
53         (*itor)->registerConditionedModelEvent(NULL);
54         SAFE_RELEASE((*itor));
55     }
56 }
57
58 SSMRESULT CConditionedQuery::create(IN IContextModel::ActivationType activationType,
59                                     IN int totalConditionsCount)
60 {
61     m_activationType = activationType;
62     m_untrackedConditionsCount = totalConditionsCount;
63     return SSM_S_OK;
64 }
65
66 SSMRESULT CConditionedQuery::registerQueryConditionEvent(IN IConditionedQueryEvent
67         *pConditionedQueryEvent)
68 {
69     m_conditionedQueryEvent = pConditionedQueryEvent;
70     return SSM_S_OK;
71 }
72
73 SSMRESULT CConditionedQuery::onConditionedModelTriggered(IN int triggerId)
74 {
75     SSMRESULT res = SSM_E_FAIL;
76     int         evaluatedConditions = m_conditionedModels.size();
77
78     for (unsigned int i = 0; i < m_conditionedModels.size(); i++)
79     {
80         if (m_conditionedModels[i]->hasAffectedData())
81         {
82             evaluatedConditions--;
83         }
84     }
85
86     if (evaluatedConditions == 0)
87     {
88         m_pConditionedQueryResult->addRef();
89         SSM_CLEANUP_ASSERT(m_pTasker->addTask(this, (IConditionedQueryResult *)m_pConditionedQueryResult));
90     }
91
92     res = SSM_S_OK;
93
94 CLEANUP:
95     return res;
96 }
97
98 void CConditionedQuery::onExecute(IN void *pArg)
99 {
100     if (m_conditionedQueryEvent)
101     {
102         m_conditionedQueryEvent->onConditionedQueryEvent(m_userTriggerId, (IConditionedQueryResult *)pArg);
103     }
104 }
105
106 void CConditionedQuery::onTerminate(IN void *pArg)
107 {
108     IConditionedQueryResult *pResult = (IConditionedQueryResult *)pArg;
109     SAFE_RELEASE(pResult);
110 }
111
112 SSMRESULT CConditionedQuery::registerConditionedModel(IN IConditionedModel *pConditionedModel)
113 {
114     SSMRESULT           res = SSM_E_FAIL;
115     IContextModel       *pContextModel = NULL;
116
117     SSM_CLEANUP_ASSERT(pConditionedModel->registerConditionedModelEvent(this));
118     SSM_CLEANUP_ASSERT(m_pConditionedQueryResult->addConditionedModel(pConditionedModel));
119     pConditionedModel->addRef();
120     m_conditionedModels.push_back(pConditionedModel);
121
122     m_untrackedConditionsCount--;
123
124     SSM_CLEANUP_ASSERT(pConditionedModel->getBaseContextModel(&pContextModel));
125
126     //Some special cases, we use device::dataId property to efficient request
127     if (pContextModel->getModelName() == "Device")
128     {
129         ModelConditionVec   modelConditionVec;
130         SSM_CLEANUP_ASSERT(pConditionedModel->getWatchCondition(&modelConditionVec));
131         for (ModelConditionVec::iterator itor = modelConditionVec.begin();
132              itor != modelConditionVec.end(); ++itor)
133         {
134             if (itor->modelProperty.propertyName == "dataId" &&
135                 itor->predicate == ModelCondition::PREDICATE_EQ)
136             {
137                 m_targetDeviceDataId = atoi(itor->modelProperty.propertyValue.c_str());
138                 break;
139             }
140         }
141     }
142
143     if (hasAllConditionedModels() == true && m_reservedForActivate)
144     {
145         SSM_CLEANUP_ASSERT(activateTriggers(m_userTriggerId));
146     }
147
148 CLEANUP:
149     SAFE_RELEASE(pContextModel);
150     return res;
151 }
152
153 SSMRESULT CConditionedQuery::activateTriggers(IN int userTriggerId)
154 {
155     SSMRESULT           res = SSM_E_FAIL;
156     int                 triggerId = 0;
157     IContextModel       *pBaseContextModel = NULL;
158
159     m_userTriggerId = userTriggerId;
160
161     if (hasAllConditionedModels() == false)
162     {
163         m_reservedForActivate = true;
164         return SSM_S_OK;
165     }
166
167     for (std::vector<IConditionedModel *>::iterator itor = m_conditionedModels.begin();
168          itor != m_conditionedModels.end(); ++itor)
169     {
170         SSM_CLEANUP_ASSERT((*itor)->activateTrigger(&triggerId));
171         SSM_CLEANUP_ASSERT((*itor)->getBaseContextModel(&pBaseContextModel));
172
173         switch (pBaseContextModel->getConstructionType())
174         {
175             case IContextModel::CONSTRUCTION_TYPE_EXTERNAL:
176             case IContextModel::CONSTRUCTION_TYPE_REMOTE:
177                 SSM_CLEANUP_ASSERT(pBaseContextModel->activate(m_activationType, m_targetDeviceDataId));
178                 break;
179
180             default:
181                 break;
182         }
183         SAFE_RELEASE(pBaseContextModel);
184     }
185
186 CLEANUP:
187     SAFE_RELEASE(pBaseContextModel);
188     return res;
189 }
190
191 SSMRESULT CConditionedQuery::deactivateTriggers()
192 {
193     SSMRESULT res = SSM_E_FAIL;
194     IContextModel       *pBaseContextModel = NULL;
195
196     for (std::vector<IConditionedModel *>::iterator itor = m_conditionedModels.begin();
197          itor != m_conditionedModels.end(); ++itor)
198     {
199         SSM_CLEANUP_ASSERT((*itor)->deactivateTrigger());
200         SSM_CLEANUP_ASSERT((*itor)->getBaseContextModel(&pBaseContextModel));
201
202         switch (pBaseContextModel->getConstructionType())
203         {
204             case IContextModel::CONSTRUCTION_TYPE_EXTERNAL:
205             case IContextModel::CONSTRUCTION_TYPE_REMOTE:
206                 SSM_CLEANUP_ASSERT(pBaseContextModel->deactivate(m_activationType, m_targetDeviceDataId));
207                 break;
208
209             default:
210                 break;
211         }
212         SAFE_RELEASE(pBaseContextModel);
213     }
214
215 CLEANUP:
216     SAFE_RELEASE(pBaseContextModel);
217     return res;
218 }
219
220 SSMRESULT CConditionedQuery::getConditionedQueryResult(OUT IConditionedQueryResult
221         **ppConditionedQueryResult)
222 {
223     SSMRESULT res = SSM_E_FAIL;
224
225     SSM_CLEANUP_ASSERT(m_pConditionedQueryResult->queryInterface(OID_IConditionedQueryResult,
226                        (IBase **)ppConditionedQueryResult));
227
228 CLEANUP:
229     return res;
230 }
231
232 bool CConditionedQuery::hasAllConditionedModels()
233 {
234     return m_untrackedConditionsCount == 0 ? true : false;
235 }