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