85ac27ec642dcd37f1e5885112580a0cd763e627
[platform/framework/web/wrt-commons.git] / modules / localization / src / w3c_file_localization.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file    w3c_file_localization.cpp
18  * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version 1.0
20  */
21 #include <stddef.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <assert.h>
26
27 #include <dpl/localization/w3c_file_localization.h>
28
29 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
30 #include <dpl/localization/localization_utils.h>
31
32 #include <dpl/log/log.h>
33 #include <dpl/string.h>
34 #include <dpl/optional.h>
35 #include <dpl/foreach.h>
36
37 #include <LanguageTagsProvider.h>
38
39 using namespace WrtDB;
40
41 namespace {
42 const DPL::String FILE_URI_BEGIN = L"file://";
43 const DPL::String WIDGET_URI_BEGIN = L"widget://";
44 const DPL::String APP_URI_BEGIN = L"app://";
45 const DPL::String LOCALE_PREFIX = L"locales/";
46
47 DPL::Optional<std::string> GetFilePathInWidgetPackageInternal(
48     const std::string& basePath,
49     std::string filePath)
50 {
51     LogDebug("Looking for file: " << filePath << "  in: " << basePath);
52
53     const LanguageTags& ltags =
54         LanguageTagsProviderSingleton::Instance().getLanguageTags();
55
56     //Check if string isn't empty
57     if (filePath.size() == 0) {
58         return DPL::Optional<std::string>::Null;
59     }
60     //Removing preceding '/'
61     if (filePath[0] == '/') {
62         filePath.erase(0, 1);
63     }
64     // In some cases (start file localization) url has unnecessary "/" at the
65     // end
66     if (filePath[filePath.size() - 1] == '/') {
67         filePath.erase(filePath.size() - 1, 1);
68     }
69     //Check if string isn't empty
70     if (filePath.size() == 0) {
71         return DPL::Optional<std::string>::Null;
72     }
73
74     LogDebug("locales size = " << ltags.size());
75     for (LanguageTags::const_iterator it = ltags.begin();
76          it != ltags.end();
77          ++it)
78     {
79         LogDebug("Trying locale: " << *it);
80         std::string path = basePath;
81         if (path[path.size() - 1] == '/') {
82             path.erase(path.size() - 1);
83         }
84
85         if (it->empty()) {
86             path += "/" + filePath;
87         } else {
88             path += "/locales/" + DPL::ToUTF8String(*it) + "/" + filePath;
89         }
90
91         LogDebug("Trying locale: " << *it << " | " << path);
92         struct stat buf;
93         if (0 == stat(path.c_str(), &buf)) {
94             if ((buf.st_mode & S_IFMT) == S_IFREG) {
95                 path.erase(0, basePath.length());
96                 return DPL::Optional<std::string>(path);
97             }
98         }
99     }
100
101     return DPL::Optional<std::string>::Null;
102 }
103
104 DPL::Optional<DPL::String> GetFilePathInWidgetPackageInternal(
105     const DPL::String& basePath,
106     const DPL::String& filePath)
107 {
108     DPL::Optional<std::string> path =
109         GetFilePathInWidgetPackageInternal(DPL::ToUTF8String(basePath),
110                                            DPL::ToUTF8String(filePath));
111     DPL::Optional<DPL::String> dplPath;
112     if (!!path) {
113         dplPath = DPL::FromUTF8String(*path);
114     }
115     return dplPath;
116 }
117 }
118
119 namespace W3CFileLocalization {
120 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
121     DbWidgetHandle widgetHandle,
122     const DPL::String &url)
123 {
124     return getFilePathInWidgetPackageFromUrl(
125                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)),
126                url);
127 }
128
129 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
130     const WrtDB::TizenAppId &tzAppId,
131     const DPL::String &url)
132 {
133     return getFilePathInWidgetPackageFromUrl(
134                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
135                url);
136 }
137
138 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
139     WrtDB::WidgetDAOReadOnlyPtr dao,
140     const DPL::String &url)
141 {
142     DPL::String req = url;
143
144     if (req.find(WIDGET_URI_BEGIN) == 0) {
145         req.erase(0, WIDGET_URI_BEGIN.length());
146     } else if (req.find(FILE_URI_BEGIN) == 0) {
147         req.erase(0, FILE_URI_BEGIN.length());
148         if (req.find(dao->getPath()) == 0) {
149             req.erase(0, dao->getPath().length());
150         }
151         if (req.find(LOCALE_PREFIX) == 0) {
152             req.erase(0, LOCALE_PREFIX.length());
153             size_t position = req.find('/');
154             // should always be >0 as correct locales path is
155             // always locales/xx/ or locales/xx-XX/
156             if (position != std::string::npos && position > 0) {
157                 req.erase(0, position + 1);
158             }
159         }
160     } else if(req.find(APP_URI_BEGIN) == 0) {
161         req.erase(0, APP_URI_BEGIN.length());
162         DPL::String id = *dao->getTizenAppId();
163         if(req.substr(0, id.size()) != id)
164         {
165             LogError("Tizen id does not match, ignoring");
166             return DPL::Optional<DPL::String>::Null;
167         }
168         req.erase(0, id.length());
169     } else {
170         LogDebug("Unknown path format, ignoring");
171         return DPL::Optional<DPL::String>::Null;
172     }
173
174     auto widgetPath = dao->getPath();
175
176     LogDebug("Required path: " << req);
177     DPL::Optional<DPL::String> found =
178         GetFilePathInWidgetPackageInternal(widgetPath, req);
179
180     if (!found) {
181         LogError("Path not found within current locale in current widget");
182         return DPL::Optional<DPL::String>::Null;
183     }
184
185     found = widgetPath + *found;
186
187     return found;
188 }
189
190 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
191     WrtDB::DbWidgetHandle widgetHandle,
192     const DPL::String& file)
193 {
194     return getFilePathInWidgetPackage(
195                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)),
196                file);
197 }
198
199 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
200     const WrtDB::TizenAppId &tzAppId,
201     const DPL::String& file)
202 {
203     return getFilePathInWidgetPackage(
204                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
205                file);
206 }
207
208 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
209     WrtDB::WidgetDAOReadOnlyPtr dao,
210     const DPL::String& file)
211 {
212     return GetFilePathInWidgetPackageInternal(dao->getPath(), file);
213 }
214
215 DPL::OptionalString getStartFile(const WrtDB::TizenAppId & tzAppId)
216 {
217     return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
218 }
219
220 DPL::OptionalString getStartFile(const WrtDB::DbWidgetHandle handle)
221 {
222     return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(handle)));
223 }
224
225 DPL::OptionalString getStartFile(WrtDB::WidgetDAOReadOnlyPtr dao)
226 {
227     WidgetDAOReadOnly::LocalizedStartFileList locList =
228         dao->getLocalizedStartFileList();
229     WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
230     LanguageTags tagsList =
231         LanguageTagsProviderSingleton::Instance().getLanguageTags();
232
233     DPL::OptionalString defaultLoc = dao->getDefaultlocale();
234     if (!!defaultLoc) {
235         tagsList.push_back(*defaultLoc);
236     }
237
238     FOREACH(tag, tagsList)
239     {
240         FOREACH(sFile, locList)
241         {
242             if (*tag == sFile->widgetLocale) {
243                 FOREACH(it, list)
244                 {
245                     if (it->startFileId == sFile->startFileId) {
246                         return it->src;
247                     }
248                 }
249             }
250         }
251     }
252
253     return DPL::OptionalString::Null;
254 }
255
256 OptionalWidgetIcon getIcon(const WrtDB::TizenAppId & tzAppId)
257 {
258     return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
259 }
260
261 OptionalWidgetIcon getIcon(WrtDB::DbWidgetHandle widgetHandle)
262 {
263     return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
264 }
265
266 OptionalWidgetIcon getIcon(WrtDB::WidgetDAOReadOnlyPtr dao)
267 {
268     WidgetDAOReadOnly::WidgetLocalizedIconList locList =
269         dao->getLocalizedIconList();
270     WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
271     LanguageTags tagsList =
272         LanguageTagsProviderSingleton::Instance().getLanguageTags();
273
274     DPL::OptionalString defaultLoc = dao->getDefaultlocale();
275     if (!!defaultLoc) {
276         tagsList.push_back(*defaultLoc);
277     }
278
279     FOREACH(tag, tagsList)
280     {
281         FOREACH(icon, locList)
282         {
283             if (*tag == icon->widgetLocale) {
284                 FOREACH(it, list)
285                 {
286                     if (it->iconId == icon->iconId) {
287                         WidgetIcon ret;
288                         ret.src = it->iconSrc;
289                         ret.width = it->iconWidth;
290                         ret.height = it->iconHeight;
291                         return ret;
292                     }
293                 }
294             }
295         }
296     }
297
298     return OptionalWidgetIcon::Null;
299 }
300
301 WidgetIconList getValidIconsList(WrtDB::DbWidgetHandle widgetHandle)
302 {
303     return getValidIconsList(
304                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
305 }
306
307 WidgetIconList getValidIconsList(const WrtDB::TizenAppId &tzAppId)
308 {
309     return getValidIconsList(
310                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
311 }
312
313 WidgetIconList getValidIconsList(WrtDB::WidgetDAOReadOnlyPtr dao)
314 {
315     WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
316
317     WidgetIconList outlist;
318
319     FOREACH(it, list)
320     {
321         LogDebug(":" << it->iconSrc);
322         if (!!getFilePathInWidgetPackage(dao->getHandle(),
323                                          it->iconSrc))
324         {
325             WidgetIcon ret;
326             ret.src = it->iconSrc;
327             ret.width = it->iconWidth;
328             ret.height = it->iconHeight;
329             outlist.push_back(ret);
330         }
331     }
332     return outlist;
333 }
334
335 OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::DbWidgetHandle widgetHandle)
336 {
337     return getStartFileInfo(
338                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
339 }
340
341 OptionalWidgetStartFileInfo getStartFileInfo(
342     const WrtDB::TizenAppId &tzAppId)
343 {
344     return getStartFileInfo(
345                WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
346 }
347
348 OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::WidgetDAOReadOnlyPtr dao)
349 {
350     WidgetStartFileInfo info;
351
352     WidgetDAOReadOnly::LocalizedStartFileList locList =
353         dao->getLocalizedStartFileList();
354     WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
355     const LanguageTags tagsList =
356         LanguageTagsProviderSingleton::Instance().getLanguageTags();
357
358     FOREACH(tag, tagsList)
359     {
360         FOREACH(sFile, locList)
361         {
362             if (*tag == sFile->widgetLocale) {
363                 FOREACH(it, list)
364                 {
365                     if (it->startFileId ==
366                         sFile->startFileId)
367                     {
368                         info.file = it->src;
369                         info.encoding = sFile->encoding;
370                         info.type = sFile->type;
371                         if (tag->empty()) {
372                             info.localizedPath = it->src;
373                         } else {
374                             info.localizedPath = L"locales/" + *tag + L"/";
375                             info.localizedPath += it->src;
376                         }
377                         return info;
378                     }
379                 }
380             }
381         }
382     }
383
384     return OptionalWidgetStartFileInfo::Null;
385 }
386
387 WidgetLocalizedInfo getLocalizedInfo(const WrtDB::DbWidgetHandle handle)
388 {
389     return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(handle)));
390 }
391
392 WidgetLocalizedInfo getLocalizedInfo(const WrtDB::TizenAppId & tzAppId)
393 {
394     return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
395 }
396
397 WidgetLocalizedInfo getLocalizedInfo(WidgetDAOReadOnlyPtr dao)
398 {
399     LanguageTags languages =
400         LanguageTagsProviderSingleton::Instance().getLanguageTags();
401     DPL::OptionalString dl = dao->getDefaultlocale();
402     if (!!dl) {
403         languages.push_back(*dl);
404     }
405
406     WidgetLocalizedInfo result;
407     FOREACH(i, languages)
408     {
409         WidgetLocalizedInfo languageResult = dao->getLocalizedInfo(*i);
410
411 #define OVERWRITE_IF_NULL(FIELD) if (!result.FIELD) { \
412         result.FIELD = languageResult.FIELD; \
413 }
414
415         OVERWRITE_IF_NULL(name);
416         OVERWRITE_IF_NULL(shortName);
417         OVERWRITE_IF_NULL(description);
418         OVERWRITE_IF_NULL(license);
419         OVERWRITE_IF_NULL(licenseHref);
420
421 #undef OVERWRITE_IF_NULL
422     }
423
424     return result;
425 }
426 }