Imported Upstream version 0.9.1
[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(IContextModel::ActivationType activationType,
59                                     int totalConditionsCount)
60 {
61     m_activationType = activationType;
62     m_untrackedConditionsCount = totalConditionsCount;
63     return SSM_S_OK;
64 }
65
66 SSMRESULT CConditionedQuery::registerQueryConditionEvent(IConditionedQueryEvent
67         *pConditionedQueryEvent)
68 {
69     m_conditionedQueryEvent = pConditionedQueryEvent;
70     return SSM_S_OK;
71 }
72
73 SSMRESULT CConditionedQuery::onConditionedModelTriggered(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(void *pArg)
99 {
100     if (m_conditionedQueryEvent)
101     {
102         m_conditionedQueryEvent->onConditionedQueryEvent(m_userTriggerId, (IConditionedQueryResult *)pArg);
103     }
104 }
105
106 void CConditionedQuery::onTerminate(void *pArg)
107 {
108     IConditionedQueryResult *pResult = (IConditionedQueryResult *)pArg;
109     SAFE_RELEASE(pResult);
110 }
111
112 SSMRESULT CConditionedQuery::registerConditionedModel(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         m_reservedForActivate = false;
146         SSM_CLEANUP_ASSERT(activateTriggers(m_userTriggerId));
147     }
148
149 CLEANUP:
150     SAFE_RELEASE(pContextModel);
151     return res;
152 }
153
154 SSMRESULT CConditionedQuery::activateTriggers(int userTriggerId)
155 {
156     SSMRESULT           res = SSM_E_FAIL;
157     int                 triggerId = 0;
158     IContextModel       *pBaseContextModel = NULL;
159
160     m_userTriggerId = userTriggerId;
161
162     if (hasAllConditionedModels() == false)
163     {
164         m_reservedForActivate = true;
165         return SSM_S_OK;
166     }
167
168     for (std::vector<IConditionedModel *>::iterator itor = m_conditionedModels.begin();
169          itor != m_conditionedModels.end(); ++itor)
170     {
171         SSM_CLEANUP_ASSERT((*itor)->activateTrigger(&triggerId));
172         SSM_CLEANUP_ASSERT((*itor)->getBaseContextModel(&pBaseContextModel));
173
174         switch (pBaseContextModel->getConstructionType())
175         {
176             case IContextModel::CONSTRUCTION_TYPE_EXTERNAL:
177             case IContextModel::CONSTRUCTION_TYPE_REMOTE:
178                 SSM_CLEANUP_ASSERT(pBaseContextModel->activate(m_activationType, m_targetDeviceDataId));
179                 break;
180
181             default:
182                 break;
183         }
184         SAFE_RELEASE(pBaseContextModel);
185     }
186
187 CLEANUP:
188     SAFE_RELEASE(pBaseContextModel);
189     return res;
190 }
191
192 SSMRESULT CConditionedQuery::deactivateTriggers()
193 {
194     SSMRESULT res = SSM_E_FAIL;
195     IContextModel       *pBaseContextModel = NULL;
196
197     for (std::vector<IConditionedModel *>::iterator itor = m_conditionedModels.begin();
198          itor != m_conditionedModels.end(); ++itor)
199     {
200         SSM_CLEANUP_ASSERT((*itor)->deactivateTrigger());
201         SSM_CLEANUP_ASSERT((*itor)->getBaseContextModel(&pBaseContextModel));
202
203         switch (pBaseContextModel->getConstructionType())
204         {
205             case IContextModel::CONSTRUCTION_TYPE_EXTERNAL:
206             case IContextModel::CONSTRUCTION_TYPE_REMOTE:
207                 SSM_CLEANUP_ASSERT(pBaseContextModel->deactivate(m_activationType, m_targetDeviceDataId));
208                 break;
209
210             default:
211                 break;
212         }
213         SAFE_RELEASE(pBaseContextModel);
214     }
215
216     if (m_reservedForActivate == true)
217     {
218         res = SSM_S_OK;
219     }
220
221 CLEANUP:
222     SAFE_RELEASE(pBaseContextModel);
223     return res;
224 }
225
226 SSMRESULT CConditionedQuery::getConditionedQueryResult(IConditionedQueryResult
227         **ppConditionedQueryResult)
228 {
229     SSMRESULT res = SSM_E_FAIL;
230
231     SSM_CLEANUP_ASSERT(m_pConditionedQueryResult->queryInterface(OID_IConditionedQueryResult,
232                        (IBase **)ppConditionedQueryResult));
233
234 CLEANUP:
235     return res;
236 }
237
238 bool CConditionedQuery::hasAllConditionedModels()
239 {
240     return m_untrackedConditionsCount == 0 ? true : false;
241 }