Modifying version number for building on tizen 3.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SSMCore / src / QueryProcessor / QueryEngine.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 "QueryEngine.h"
21 #include "DataReader.h"
22
23 SSMRESULT CQueryEngine::finalConstruct()
24 {
25     SSMRESULT res = SSM_E_FAIL;
26
27     m_cqid = 0;
28
29     m_pQueryEngineEvent = NULL;
30
31     SSM_CLEANUP_ASSERT(CreateInstance(OID_ITasker, (IBase **)&m_pTasker));
32
33     SSM_CLEANUP_ASSERT(CreateGlobalInstance(OID_IPropagationEngine, (IBase **)&m_pPropagationEngine));
34
35 CLEANUP:
36     return res;
37 }
38
39 void CQueryEngine::finalRelease()
40 {
41     m_pQueryEngineEvent = NULL;
42
43     m_mtxQueries.lock();
44
45     for (std::map<int, IConditionedQuery *>::iterator itor = m_conditionedQueries.begin();
46          itor != m_conditionedQueries.end(); ++itor)
47     {
48         itor->second->deactivateTriggers();
49         SAFE_RELEASE(itor->second);
50     }
51
52     for (std::map<int, CContextQuery *>::iterator itor = m_contextQueries.begin();
53          itor != m_contextQueries.end(); ++itor)
54     {
55         //Token *root = itor->second->getRoot();
56         //SAFE_DELETE(root);
57         SAFE_DELETE(itor->second);
58     }
59
60     m_mtxQueries.unlock();
61 }
62
63 SSMRESULT CQueryEngine::processQueryResult(IN int userTriggerId,
64         IN std::vector<result_model> *result)
65 {
66     SSMRESULT           res = SSM_E_FAIL;
67     ModelPropertyVec    modelData;
68     std::vector<result_model> result_model_data_id;
69     IntVec                  modelID;
70     std::vector<std::string> contextName;
71     IContextModel           *temp_contextmodel = NULL;
72     IContextModel           *temp_contextmodel2 = NULL;
73
74     intptr_t             *pData = NULL;
75
76     CDataReader *pDataReader = NULL;
77
78     m_mtxQueries.lock();
79
80     if (m_contextQueries.find(userTriggerId) == m_contextQueries.end())
81     {
82         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
83     }
84
85     m_contextQueries[userTriggerId]->check_result_model();
86     m_contextQueries[userTriggerId]->return_modelID(&modelID);
87
88
89     m_contextQueries[userTriggerId]->return_contextName(&contextName);
90
91     for (unsigned int i = 0; i < modelID.size(); i++)
92     {
93         SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(contextName.at(i), &temp_contextmodel2));
94
95         for (unsigned int j = 0 ; j < result->size() ; j++)
96         {
97             int data;
98             if (result->at(j).dataId.size() <= 0)
99             {
100                 continue;
101             }
102
103             int modelid = modelID.at(i);
104             std::vector<int> dataid;
105             for (unsigned int k = 0 ; k < result->at(j).dataId.size() ; k++)
106             {
107                 SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel(result->at(j).modelName,
108                                    &temp_contextmodel));
109                 data = result->at(j).dataId.at(k);
110
111                 if (modelID.at(i) < result->at(j).modelID )
112                 {
113                     SSM_CLEANUP_ASSERT(temp_contextmodel->getParentDataId(data, temp_contextmodel2, &data));
114                     dataid.push_back(data);
115                 }
116                 else if (modelID.at(i) > result->at(j).modelID )
117                 {
118                     SSM_CLEANUP_ASSERT(temp_contextmodel->getChildDataId(data, temp_contextmodel2, &dataid));
119                 }
120                 else
121                 {
122                     dataid.push_back(data);
123                 }
124                 SAFE_RELEASE(temp_contextmodel);
125             }
126
127             m_contextQueries[userTriggerId]->integrate_result(&result_model_data_id, modelid, &dataid,
128                     temp_contextmodel2->getModelName());
129         }
130
131         SAFE_RELEASE(temp_contextmodel2);
132     }
133
134     pDataReader = new CDataReader();
135
136     for (unsigned int i = 0; i < result_model_data_id.size(); i++)
137     {
138         std::vector<CModelData *>    modelDataSet;
139
140         for (unsigned int j = 0; j < (result_model_data_id)[i].dataId.size(); j++)
141         {
142             CModelData *pModelData = new CModelData();
143             IContextModel       *pCM = NULL;
144             ModelPropertyVec    modelPropertyVec;
145
146             SSM_CLEANUP_ASSERT(m_pPropagationEngine->getContextModel((result_model_data_id)[i].modelName,
147                                &pCM));
148             SSM_CLEANUP_ASSERT(pCM->getModelData((result_model_data_id)[i].dataId[j], &modelPropertyVec));
149             pModelData->setDataId((result_model_data_id)[i].dataId[j]);
150             for (ModelPropertyVec::iterator itor = modelPropertyVec.begin();
151                  itor != modelPropertyVec.end(); ++itor)
152             {
153                 pModelData->addModelData(itor->propertyName, itor->propertyValue);
154             }
155
156             modelDataSet.push_back(pModelData);
157
158             SAFE_RELEASE(pCM);
159         }
160
161         SSM_CLEANUP_ASSERT(pDataReader->addModelData((result_model_data_id)[i].modelName, &modelDataSet));
162     }
163     pData = new intptr_t [3];
164     pData[0] = EVENT_TYPE_OUTER;
165     pData[1] = userTriggerId;
166     pData[2] = reinterpret_cast<intptr_t>(pDataReader);
167
168     m_pTasker->addTask(this, (void *)pData);
169
170     res = SSM_S_OK;
171
172 CLEANUP:
173     m_mtxQueries.unlock();
174     SAFE_RELEASE(temp_contextmodel);
175     SAFE_RELEASE(temp_contextmodel2);
176     return res;
177 }
178
179 SSMRESULT CQueryEngine::validateQueryResult(IN IConditionedQueryResult *pConditionedQueryResult,
180         OUT std::vector<result_model> *resultData)
181 {
182     SSMRESULT               res = SSM_E_FAIL;
183     IContextModel           *pContextModel = NULL;
184     IConditionedModel       *pConditionedModel = NULL;
185
186     for (unsigned int i = 0 ; i < pConditionedQueryResult->getConditionedModelCount() ; i++)
187     {
188         std::vector<int>    temp_dataID;
189         result_model        temp_result;
190         SSM_CLEANUP_ASSERT(pConditionedQueryResult->getConditionedContextModel(i, &pConditionedModel));
191         SSM_CLEANUP_ASSERT(pConditionedModel->getAffectedData(&temp_dataID));
192
193         if (temp_dataID.size() == 0)
194         {
195             break;
196         }
197
198         SSM_CLEANUP_ASSERT(pConditionedModel->getBaseContextModel(&pContextModel));
199         temp_result.modelID = pContextModel->getModelId();
200         temp_result.dataId = temp_dataID;
201         temp_result.modelName = pContextModel->getModelName();
202         resultData->push_back(temp_result);
203         SAFE_RELEASE(pConditionedModel);
204         SAFE_RELEASE(pContextModel);
205     }
206
207     if (resultData->size() == pConditionedQueryResult->getConditionedModelCount())
208     {
209         res = SSM_S_OK;
210     }
211     else
212     {
213         res = SSM_S_FALSE;
214     }
215
216 CLEANUP:
217     SAFE_RELEASE(pConditionedModel);
218     SAFE_RELEASE(pContextModel);
219     return res;
220 }
221
222 SSMRESULT CQueryEngine::onConditionedQueryEvent(IN int userTriggerId,
223         IN IConditionedQueryResult *pConditionedQueryResult)
224 {
225     SSMRESULT                   res = SSM_E_FAIL;
226     std::vector<result_model>   result;
227
228     SSM_CLEANUP_ASSERT(validateQueryResult(pConditionedQueryResult, &result));
229     SSM_CLEANUP_ASSERT(processQueryResult(userTriggerId, &result));
230
231 CLEANUP:
232     return res;
233 }
234
235 void CQueryEngine::onExecute(void *pArg)
236 {
237     intptr_t *pData = (intptr_t *)pArg;
238
239     switch (pData[0])
240     {
241         case EVENT_TYPE_INNER:
242             processQueryResult(pData[1], (std::vector<result_model> *)pData[2]);
243             break;
244
245         case EVENT_TYPE_OUTER:
246             if (m_pQueryEngineEvent != NULL)
247             {
248                 m_pQueryEngineEvent->onQueryEngineEvent(pData[1], (IDataReader *)pData[2]);
249             }
250             break;
251
252         default:
253             break;
254     }
255 }
256
257 void CQueryEngine::onTerminate(void *pArg)
258 {
259     intptr_t *pData = (intptr_t *)pArg;
260     std::vector<result_model>   *pResult = NULL;
261     CDataReader                 *pDataReader = NULL;
262
263     switch (pData[0])
264     {
265         case EVENT_TYPE_INNER:
266             pResult = (std::vector<result_model> *)(((int *)pArg)[2]);
267             SAFE_DELETE(pResult);
268             break;
269
270         case EVENT_TYPE_OUTER:
271             pDataReader = (CDataReader *)(((int *)pArg)[2]);
272             SAFE_DELETE(pDataReader);
273             break;
274
275         default:
276             break;
277     }
278     SAFE_ARRAY_DELETE(pData);
279 }
280
281 SSMRESULT CQueryEngine::executeContextQuery(IN std::string contextQuery, OUT int *cqid)
282 {
283     SSMRESULT               res = SSM_E_FAIL;
284     IConditionedQuery       *pConditionedQuery = NULL;
285     IConditionedQueryResult *pConditionedQueryResult = NULL;
286     QueryCondition          queryConditions;
287     CContextQuery           *clsContextQuery = NULL;
288     Token                   token;
289     CCQLParser              cqlParser;
290     IContextModel::ActivationType   queryCommandType;
291
292     cqlParser.parse(contextQuery, &token);
293
294     if (!cqlParser.check_grammer(&token))
295     {
296         res = SSM_E_FAIL;
297         goto CLEANUP;
298     }
299
300     clsContextQuery = new CContextQuery();
301     SSM_CLEANUP_NULL_ASSERT(clsContextQuery);
302     SSM_CLEANUP_ASSERT(clsContextQuery->initialize(token));
303     clsContextQuery->make_QueryCondition(&queryConditions);
304
305     if (CCQLParser::tolower(token.child_token[0].name) == "subscribe")
306     {
307         queryCommandType = IContextModel::ACTIVATION_TYPE_SUBSCRIBE;
308     }
309     else
310     {
311         queryCommandType = IContextModel::ACTIVATION_TYPE_GET;
312     }
313
314     SSM_CLEANUP_ASSERT(m_pPropagationEngine->createConditionedQuery(queryCommandType,
315                        &queryConditions, this, &pConditionedQuery));
316
317     m_mtxQueries.lock();
318     pConditionedQuery->addRef();
319     m_conditionedQueries[m_cqid] = pConditionedQuery;
320     m_contextQueries[m_cqid] = clsContextQuery;
321     m_mtxQueries.unlock();
322
323     if (pConditionedQuery->hasAllConditionedModels() == true)
324     {
325         std::vector<result_model>   *pResult = NULL;
326
327         SSM_CLEANUP_ASSERT(pConditionedQuery->getConditionedQueryResult(&pConditionedQueryResult));
328         pResult = new std::vector<result_model>();
329         if (validateQueryResult(pConditionedQueryResult, pResult) == SSM_S_OK)
330         {
331             //We have valid data, let's deliver to application.
332             intptr_t  *pData = new intptr_t [3];
333             pData[0] = EVENT_TYPE_INNER;
334             pData[1] = m_cqid;
335             pData[2] = reinterpret_cast<intptr_t>(pResult);
336
337             m_pTasker->addTask(this, (void *)pData);
338         }
339         else
340         {
341             SAFE_DELETE(pResult);
342             if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
343             {
344                 //There is no valid data. let's request new one
345                 SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
346             }
347         }
348     }
349     else
350     {
351         if (queryCommandType == IContextModel::ACTIVATION_TYPE_GET)
352         {
353             //There is no models such name
354             SSM_CLEANUP_ASSERT(SSM_E_FAIL);
355         }
356     }
357
358     //Every subscribe command must request new data to models
359     if (queryCommandType == IContextModel::ACTIVATION_TYPE_SUBSCRIBE)
360     {
361         SSM_CLEANUP_ASSERT(pConditionedQuery->activateTriggers(m_cqid));
362     }
363
364     *cqid = m_cqid++;
365
366 CLEANUP:
367     SAFE_RELEASE(pConditionedQuery);
368     SAFE_RELEASE(pConditionedQueryResult);
369     return res;
370 }
371
372 //TODO: Registration with multiple instance support
373 SSMRESULT CQueryEngine::registerQueryEvent(IN IQueryEngineEvent *pQueryEngineEvent)
374 {
375     m_pQueryEngineEvent = pQueryEngineEvent;
376     return SSM_S_OK;
377 }
378
379 SSMRESULT CQueryEngine::unregisterQueryEvent(IN IQueryEngineEvent *pQueryEngineEvent)
380 {
381     if (m_pQueryEngineEvent == pQueryEngineEvent)
382     {
383         m_pQueryEngineEvent = NULL;
384         return SSM_S_OK;
385     }
386
387     return SSM_E_FAIL;
388 }
389
390 SSMRESULT CQueryEngine::killContextQuery(IN int cqid)
391 {
392     SSMRESULT res = SSM_E_FAIL;
393
394     std::map<int, IConditionedQuery *>::iterator itorConditionedQueries;
395     std::map<int, CContextQuery *>::iterator itorContextQuries;
396
397     m_mtxQueries.lock();
398     itorConditionedQueries = m_conditionedQueries.find(cqid);
399     itorContextQuries = m_contextQueries.find(cqid);
400
401     if (itorConditionedQueries != m_conditionedQueries.end())
402     {
403         SSM_CLEANUP_ASSERT(itorConditionedQueries->second->deactivateTriggers());
404         itorConditionedQueries->second->release();
405         m_conditionedQueries.erase(itorConditionedQueries);
406     }
407
408     if (itorContextQuries != m_contextQueries.end())
409     {
410         SAFE_DELETE(itorContextQuries->second);
411         m_contextQueries.erase(itorContextQuries);
412     }
413
414 CLEANUP:
415     m_mtxQueries.unlock();
416     return res;
417 }