Imported Upstream version 0.9.1
[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 = new CModelData();
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->setDataId((result_model_data_id)[i].dataId[j]);
148             for (ModelPropertyVec::iterator itor = modelPropertyVec.begin();
149                  itor != modelPropertyVec.end(); ++itor)
150             {
151                 pModelData->addModelData(itor->propertyName, itor->propertyValue);
152             }
153
154             modelDataSet.push_back(pModelData);
155
156             SAFE_RELEASE(pCM);
157         }
158
159         SSM_CLEANUP_ASSERT(pDataReader->addModelData((result_model_data_id)[i].modelName, &modelDataSet));
160     }
161     pData = new intptr_t [3];
162     pData[0] = EVENT_TYPE_OUTER;
163     pData[1] = userTriggerId;
164     pData[2] = reinterpret_cast<intptr_t>(pDataReader);
165
166     m_pTasker->addTask(this, (void *)pData);
167
168     res = SSM_S_OK;
169
170 CLEANUP:
171     m_mtxQueries.unlock();
172     SAFE_RELEASE(temp_contextmodel);
173     SAFE_RELEASE(temp_contextmodel2);
174     return res;
175 }
176
177 SSMRESULT CQueryEngine::validateQueryResult(IConditionedQueryResult *pConditionedQueryResult,
178         std::vector<result_model> *resultData)
179 {
180     SSMRESULT               res = SSM_E_FAIL;
181     IContextModel           *pContextModel = NULL;
182     IConditionedModel       *pConditionedModel = NULL;
183
184     for (unsigned int i = 0 ; i < pConditionedQueryResult->getConditionedModelCount() ; i++)
185     {
186         std::vector<int>    temp_dataID;
187         result_model        temp_result;
188         SSM_CLEANUP_ASSERT(pConditionedQueryResult->getConditionedContextModel(i, &pConditionedModel));
189         SSM_CLEANUP_ASSERT(pConditionedModel->getAffectedData(&temp_dataID));
190
191         if (temp_dataID.size() == 0)
192         {
193             break;
194         }
195
196         SSM_CLEANUP_ASSERT(pConditionedModel->getBaseContextModel(&pContextModel));
197         temp_result.modelID = pContextModel->getModelId();
198         temp_result.dataId = temp_dataID;
199         temp_result.modelName = pContextModel->getModelName();
200         resultData->push_back(temp_result);
201         SAFE_RELEASE(pConditionedModel);
202         SAFE_RELEASE(pContextModel);
203     }
204
205     if (resultData->size() == pConditionedQueryResult->getConditionedModelCount())
206     {
207         res = SSM_S_OK;
208     }
209     else
210     {
211         res = SSM_S_FALSE;
212     }
213
214 CLEANUP:
215     SAFE_RELEASE(pConditionedModel);
216     SAFE_RELEASE(pContextModel);
217     return res;
218 }
219
220 SSMRESULT CQueryEngine::onConditionedQueryEvent(int userTriggerId,
221         IConditionedQueryResult *pConditionedQueryResult)
222 {
223     SSMRESULT                   res = SSM_E_FAIL;
224     std::vector<result_model>   result;
225
226     SSM_CLEANUP_ASSERT(validateQueryResult(pConditionedQueryResult, &result));
227     SSM_CLEANUP_ASSERT(processQueryResult(userTriggerId, &result));
228
229 CLEANUP:
230     return res;
231 }
232
233 void CQueryEngine::onExecute(void *pArg)
234 {
235     intptr_t *pData = (intptr_t *)pArg;
236
237     switch (pData[0])
238     {
239         case EVENT_TYPE_INNER:
240             processQueryResult(pData[1], (std::vector<result_model> *)pData[2]);
241             break;
242
243         case EVENT_TYPE_OUTER:
244             if (m_pQueryEngineEvent != NULL)
245             {
246                 m_pQueryEngineEvent->onQueryEngineEvent(pData[1], (IDataReader *)pData[2]);
247             }
248             break;
249
250         default:
251             break;
252     }
253 }
254
255 void CQueryEngine::onTerminate(void *pArg)
256 {
257     intptr_t *pData = (intptr_t *)pArg;
258     std::vector<result_model>   *pResult = NULL;
259     CDataReader                 *pDataReader = NULL;
260
261     switch (pData[0])
262     {
263         case EVENT_TYPE_INNER:
264             pResult = (std::vector<result_model> *)pData[2];
265             SAFE_DELETE(pResult);
266             break;
267
268         case EVENT_TYPE_OUTER:
269             pDataReader = (CDataReader *)pData[2];
270             SAFE_DELETE(pDataReader);
271             break;
272
273         default:
274             break;
275     }
276     SAFE_ARRAY_DELETE(pData);
277 }
278
279 SSMRESULT CQueryEngine::executeContextQuery(std::string contextQuery, int *cqid)
280 {
281     SSMRESULT               res = SSM_E_FAIL;
282     IConditionedQuery       *pConditionedQuery = NULL;
283     IConditionedQueryResult *pConditionedQueryResult = NULL;
284     QueryCondition          queryConditions;
285     CContextQuery           *clsContextQuery = NULL;
286     Token                   token;
287     CCQLParser              cqlParser;
288     IContextModel::ActivationType   queryCommandType;
289
290     if (!cqlParser.parse(contextQuery, &token))
291     {
292         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
293     }
294
295     if (!cqlParser.check_grammer(&token))
296     {
297         SSM_CLEANUP_ASSERT(SSM_E_FAIL);
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(IQueryEngineEvent *pQueryEngineEvent)
374 {
375     m_pQueryEngineEvent = pQueryEngineEvent;
376     return SSM_S_OK;
377 }
378
379 SSMRESULT CQueryEngine::unregisterQueryEvent(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(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 }