ed7f38eaae3c54965e0d1b61ac41431a530c2b03
[platform/framework/web/wrt-plugins-tizen.git] / src / Content / ContentSearchVisitor.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "time.h"
19 #include <iomanip>
20 #include <Commons/Exception.h>
21 #include "ContentSearchVisitor.h"
22 #include "ContentUtility.h"
23 #include <Logger.h>
24
25 namespace DeviceAPI {
26 namespace Content {
27
28 const string STR_LEFT_BRACKET(" (");
29 const string STR_RIGHT_BRACKET(") ");
30 const string STR_AND(" AND ");
31 const string STR_OR(" OR ");
32 const string STR_GREATER_THAN (">");
33 const string STR_LESS_THAN ("<");
34 const string STR_EQUAL ("=");
35 const string STR_S_QUOTATION ("'");
36 const string STR_PERCENT ("%");
37 const string STR_MIN_LATITUDE("-90");
38 const string STR_MAX_LATITUDE("90");
39 const string STR_MIN_LONGITUDE("-180");
40 const string STR_MAX_LONGITUDE("180");
41
42
43
44 typedef enum
45 {
46         MEDIA_ID = 0,
47         MEDIA_TITLE,
48         MEDIA_FILEPATH,
49         MEDIA_THUMBNAILPATH,
50         MEDIA_CREATEDDATE,
51         MEDIA_MODIFIEDDATE,
52         MEDIA_DESCRIPTION,
53         MEDIA_RATING,
54
55 }media_attribute_e;
56
57
58 map<string, string> MediaSearchVisitor::attrFolderEnumMap = {
59                 {"id",                  "id"},
60                 {"directoryURI",        "FOLDER_PATH"},
61                 {"title",               "FOLDER_NAME"},
62                 {"storageType",         "FOLDER_STORAGE_TYPE"},
63                 {"modifiedDate",        "FOLDER_MODIFIED_TIME"},
64 };
65
66 map<string, string> MediaSearchVisitor::attrMediaEnumMap = {
67 //media item attribues.
68                 {"id",                  "MEDIA_ID"},
69                 {"type",                "MEDIA_TYPE"},
70                 {"mimeType",            "MEDIA_MIME_TYPE"},
71                 {"name",                "MEDIA_DISPLAY_NAME"},
72                 {"title",               "MEDIA_TITLE"},
73                 {"contentURI",          "MEDIA_PATH"},
74                 {"thumbnailURIs",       "MEDIA_THUMBNAIL_PATH"},
75                 {"description",         "MEDIA_DESCRIPTION"},
76                 {"rating",              "MEDIA_RATING"},
77                 {"createdDate",         "MEDIA_ADDED_TIME"},
78                 {"releaseDate",         "MEDIA_DATETAKEN"},
79                 {"modifiedDate",        "MEDIA_MODIFIED_TIME"},
80 //media image,video,audio attribues.
81                 {"geolocation.latitude",        "MEDIA_LATITUDE"},
82                 {"geolocation.longitude",       "MEDIA_LONGITUDE"},
83                 {"album",               "MEDIA_ALBUM"},
84                 {"artists",             "MEDIA_ARTIST"},
85                 {"width",               "MEDIA_WIDTH"},
86                 {"height",              "MEDIA_HEIGHT"},
87                 {"genres",              "MEDIA_GENRE"},
88                 {"size",                "MEDIA_SIZE"},
89
90 };
91
92 MediaSearchVisitor::MediaSearchVisitor()
93 {
94
95 }
96
97 MediaSearchVisitor::~MediaSearchVisitor()
98 {
99
100 }
101
102 void MediaSearchVisitor::visitPreComposite(FilterType& type, int depth)
103 {
104         m_query.append(STR_LEFT_BRACKET);
105 }
106
107 void MediaSearchVisitor::visitInComposite(FilterType& type, int depth)
108 {
109         if(type == UNION_FILTER)
110                 m_query.append(STR_OR);
111         else if(type == INTERSECTION_FILTER)
112                 m_query.append(STR_AND);
113         else{
114                 ThrowMsg(PlatformException, "Filter Type is wrong.");
115         }
116 }
117
118 void MediaSearchVisitor::visitPostComposite(FilterType& type, int depth)
119 {
120         m_query.append(STR_RIGHT_BRACKET);
121 }
122
123
124 string MediaSearchVisitor::getPlatformAttr(string attrName)
125 {
126         string platformAttr;
127         map<string, string>::iterator pos;
128
129         if( queryType == QUERY_FOLDER)
130         {
131                 pos = attrFolderEnumMap.find(attrName);
132
133                 if(attrFolderEnumMap.end() != pos)
134                 {
135                         platformAttr = pos->second;
136                 }
137                 else
138                 {
139                         ThrowMsg(PlatformException, "Attribute(" << attrName << ") is not supported.");
140                 }
141         }
142         else if(queryType == QUERY_MEDIA)
143         {
144                 pos = attrMediaEnumMap.find(attrName);
145
146                 if(attrMediaEnumMap.end() != pos)
147                 {
148                         platformAttr = pos->second;
149                 }
150                 else
151                 {
152                         ThrowMsg(PlatformException, "Attribute(" << attrName << ") is not supported.");
153                 }
154
155         }
156         return platformAttr;
157 }
158
159
160 void MediaSearchVisitor::visitAttribute(string& attrName, MatchFlag& matchFlag, AnyPtr& matchValue, int depth)
161 {
162         string attrPlatform = getPlatformAttr(attrName);
163         if(matchValue == NULL)
164         {
165                 ThrowMsg(PlatformException, "matchValue is not valid data.");
166         }       
167
168         m_query.append(convertAttribute(attrPlatform, matchValue, matchFlag));
169 }
170
171 string MediaSearchVisitor::toDateDbStr(tm &date) const
172 {
173         time_t time;
174         time = mktime(&date);
175         stringstream ss;
176         ss << time;
177         return ss.str();
178 }
179
180 string MediaSearchVisitor::convertAttribute(string &attrName, AnyPtr& matchValue, MatchFlag& matchFlag)
181 {
182         string valueStr;
183         string operatorStr;
184         string conditionStr;
185
186         string matchValueStr;
187
188         if(attrName.compare("MEDIA_TYPE")==0)
189         {
190                 if(matchValue->getString().compare("IMAGE")==0)
191                         matchValueStr = "0";
192                 else if(matchValue->getString().compare("VIDEO")==0)
193                         matchValueStr = "1";
194                 else if(matchValue->getString().compare("AUDIO")==0)
195                         matchValueStr = "3";
196                 else if(matchValue->getString().compare("OTHER")==0)
197                         matchValueStr = "4";
198                 else
199                 {
200                         ThrowMsg(PlatformException, "mediaType(" << matchValue->getString() << ") is not supported.");
201                 }
202         }
203         else if(attrName.compare("contentURI")==0 || attrName.compare("thumbnailURIs")==0)
204         {
205                 matchValueStr = ContentUtility::convertUriToPath(matchValue->getString());
206         }
207         else if(attrName.compare("MEDIA_LATITUDE")==0){
208             if(matchValue->getDouble() < MIN_LATITUDE || 
209                 matchValue->getDouble() > MAX_LATITUDE)
210             {
211                 ThrowMsg(PlatformException, "latitude range is -90 ~ 90");
212             }
213             else
214             {
215                 matchValueStr = matchValue->toString();
216             }
217         }
218         else if(attrName.compare("MEDIA_LONGITUDE")==0){
219             if(matchValue->getDouble() < MIN_LONGITUDE|| 
220                 matchValue->getDouble() > MAX_LONGITUDE)
221             {
222                 ThrowMsg(PlatformException, "longitude range is -180 ~ 180");
223             }
224             else
225             {
226                 matchValueStr = matchValue->toString();
227             }
228         }
229         else
230         {
231                 matchValueStr = matchValue->toString();
232         }
233
234         if(matchValue->isType(PrimitiveType_Time))
235         {
236             tm date = *matchValue->getDateTm();
237             if(attrName.compare("MEDIA_DATETAKEN")==0)
238             {
239                 char buf[512];
240                 strftime(buf, sizeof(buf), "'%Y:%m:%d %H:%M:%S'", &date);
241                 valueStr = buf;
242             }
243             else
244             {
245                 valueStr = toDateDbStr(date);
246             }
247                 m_operationKey = EQUAL;
248         }
249         else
250         {
251                 ostringstream os;
252
253              switch (matchFlag) {
254
255              case MATCH_CONTAINS:
256                  m_operationKey = LIKE;
257                  os << STR_S_QUOTATION <<  STR_PERCENT << matchValueStr << STR_PERCENT << STR_S_QUOTATION;
258                  break;
259              case MATCH_STARTSWITH:
260                  m_operationKey = LIKE;
261                  os << STR_S_QUOTATION << matchValueStr << STR_PERCENT << STR_S_QUOTATION;
262                  break;
263              case MATCH_ENDSWITH:
264                  m_operationKey = LIKE;
265                  os << STR_S_QUOTATION <<  STR_PERCENT << matchValueStr << STR_S_QUOTATION;
266                  break;
267              case MATCH_FULLSTRING:
268                  m_operationKey = FULLSTRING;
269                  os << STR_S_QUOTATION << matchValueStr << STR_S_QUOTATION << " COLLATE NOCASE ";
270                  break;
271              case MATCH_EXISTS:
272                  m_operationKey = EXISTS;
273                  break;
274              case MATCH_EXACTLY:
275              default:
276                  m_operationKey = EQUAL;
277                  os << STR_S_QUOTATION << matchValueStr << STR_S_QUOTATION;
278              }
279
280                 valueStr = os.str();
281         }
282
283       operatorStr = operatorKey[m_operationKey];
284
285         if( m_operationKey != EXISTS)
286         {
287             conditionStr = STR_LEFT_BRACKET + attrName + operatorStr + valueStr + STR_RIGHT_BRACKET;
288        }
289        else
290        {
291             conditionStr = STR_LEFT_BRACKET + attrName + operatorStr + STR_RIGHT_BRACKET;
292        }
293
294         return conditionStr;
295 }
296
297 condition_e MediaSearchVisitor::getOperationKey()
298 {
299     return m_operationKey;
300 }
301
302
303 void MediaSearchVisitor::visitAttributeRange(string& attrName,AnyPtr& initialValue,AnyPtr& endValue,int depth)
304 {
305         if(initialValue == NULL || endValue == NULL)
306                 return;
307
308         string str;
309         string initialValueStr;
310         string endValueStr;
311
312         string attrPlatform = getPlatformAttr(attrName);
313
314         if(!initialValue->isNullOrUndefined()) 
315         {
316                 if(initialValue->isType(PrimitiveType_Time))
317                 {
318                 tm date = *initialValue->getDateTm();
319                 if(attrPlatform.compare("MEDIA_DATETAKEN")==0)
320                 {
321                     char buf[512];
322                     strftime(buf, sizeof(buf), "'%Y:%m:%d %H:%M:%S'", &date);
323                     initialValueStr = buf;
324                 }
325                 else
326                 {
327                     initialValueStr = toDateDbStr(date);
328                 }
329                 } 
330                 else 
331                 {
332                     initialValueStr = initialValue->toString();
333                 }
334         }
335
336         if (!endValue->isNullOrUndefined()) 
337         {
338                 if(endValue->isType(PrimitiveType_Time))
339                 {
340                 tm date = *endValue->getDateTm();
341                 if(attrPlatform.compare("MEDIA_DATETAKEN")==0)
342                 {
343                     char buf[512];
344                     strftime(buf, sizeof(buf), "'%Y:%m:%d %H:%M:%S'", &date);
345                     endValueStr = buf;
346                 }
347                 else
348                 {
349                     endValueStr = toDateDbStr(date);
350                 }
351                 }
352                 else 
353                 {
354                         endValueStr = endValue->toString();
355                 }
356         }
357
358         if (!initialValue->isNullOrUndefined() && endValue->isNullOrUndefined()) 
359         {
360             initialValueStr = initialValue->toString();
361             if(attrPlatform.compare("MEDIA_LATITUDE")==0)
362             {
363                 if(initialValue->getDouble() < MIN_LATITUDE)
364                 {
365                     initialValueStr = STR_MIN_LATITUDE;
366                 }
367             }
368             else if(attrPlatform.compare("MEDIA_LONGITUDE")==0)
369             {
370                 if(initialValue->getDouble() < MIN_LONGITUDE)
371                 {
372                     initialValueStr = STR_MIN_LONGITUDE;
373                 }
374             }
375                 str = STR_LEFT_BRACKET + attrPlatform + STR_GREATER_THAN + STR_EQUAL + 
376                                 STR_S_QUOTATION + initialValueStr + STR_S_QUOTATION + STR_RIGHT_BRACKET;
377         }
378         else if(initialValue->isNullOrUndefined() && !endValue->isNullOrUndefined()) 
379         {
380             if(attrPlatform.compare("MEDIA_LATITUDE")==0)
381             {
382                 initialValueStr = STR_MIN_LATITUDE;
383                 str = STR_LEFT_BRACKET + attrPlatform + STR_GREATER_THAN + STR_EQUAL + STR_S_QUOTATION + 
384                     initialValueStr + STR_S_QUOTATION + STR_AND + attrPlatform + STR_LESS_THAN + STR_S_QUOTATION + 
385                     endValueStr + STR_S_QUOTATION + STR_RIGHT_BRACKET;
386             }
387             else if(attrPlatform.compare("MEDIA_LONGITUDE")==0)
388             {
389                 initialValueStr = STR_MIN_LONGITUDE;
390                 str = STR_LEFT_BRACKET + attrPlatform + STR_GREATER_THAN + STR_EQUAL + STR_S_QUOTATION + 
391                     initialValueStr + STR_S_QUOTATION + STR_AND + attrPlatform + STR_LESS_THAN + STR_S_QUOTATION + 
392                     endValueStr + STR_S_QUOTATION + STR_RIGHT_BRACKET;
393             }
394             else
395             {
396                 str = STR_LEFT_BRACKET + attrPlatform + STR_LESS_THAN + STR_S_QUOTATION + 
397                     endValueStr + STR_S_QUOTATION + STR_RIGHT_BRACKET;
398             }
399         } 
400         else if (!initialValue->isNullOrUndefined() && !endValue->isNullOrUndefined()) 
401         {
402             if(attrPlatform.compare("MEDIA_LATITUDE")==0)
403             {
404                 if(initialValue->getDouble() < MIN_LATITUDE)
405                 {
406                     initialValueStr = STR_MIN_LATITUDE;
407                 }
408             }
409             else if(attrPlatform.compare("MEDIA_LONGITUDE")==0)
410             {
411                 if(initialValue->getDouble() < MIN_LONGITUDE)
412                 {
413                     initialValueStr = STR_MIN_LONGITUDE;
414                 }
415             }
416             str = STR_LEFT_BRACKET + attrPlatform + STR_GREATER_THAN + STR_EQUAL + STR_S_QUOTATION + 
417                 initialValueStr + STR_S_QUOTATION + STR_AND + attrPlatform + STR_LESS_THAN + STR_S_QUOTATION + 
418                 endValueStr + STR_S_QUOTATION + STR_RIGHT_BRACKET;
419         }
420
421         m_query.append(str);
422
423 }
424
425 string MediaSearchVisitor::getResult() const
426 {
427         return m_query;
428 }       
429
430 void MediaSearchVisitor::setQueryType(QueryType value)
431 {
432         queryType = value;
433 }
434
435
436
437
438 }
439 }