Tizen 2.0 Release
[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 LOCALE_PREFIX = L"locales/";
45
46 DPL::Optional<std::string> GetFilePathInWidgetPackageInternal(
47         const std::string& basePath,
48         std::string filePath)
49 {
50     LogDebug("Looking for file: " << filePath << "  in: " << basePath);
51
52     const LanguageTags& ltags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
53
54     //Check if string isn't empty
55     if (filePath.size() == 0) { return DPL::Optional<std::string>::Null; }
56     //Removing preceding '/'
57     if (filePath[0] == '/') { filePath.erase(0, 1); }
58     // In some cases (start file localization) url has unnecessary "/" at the end
59     if(filePath[filePath.size()-1] == '/') { filePath.erase(filePath.size()-1, 1); }
60     //Check if string isn't empty
61     if (filePath.size() == 0) { return DPL::Optional<std::string>::Null; }
62
63     LogDebug("locales size = " << ltags.size());
64     for (LanguageTags::const_iterator it = ltags.begin();
65             it != ltags.end();
66             ++it) {
67         LogDebug("Trying locale: " << *it);
68         std::string path = basePath;
69         if (path[path.size() - 1] == '/') {
70             path.erase(path.size() - 1);
71         }
72
73         if (it->empty()) {
74             path += "/" + filePath;
75         } else {
76             path += "/locales/" + DPL::ToUTF8String(*it) + "/" + filePath;
77         }
78
79         LogDebug("Trying locale: " << *it << " | " << path);
80         struct stat buf;
81         if (0 == stat(path.c_str(), &buf)) {
82             if ((buf.st_mode & S_IFMT) == S_IFREG) {
83                 path.erase(0, basePath.length());
84                 return DPL::Optional<std::string>(path);
85             }
86         }
87     }
88
89     return DPL::Optional<std::string>::Null;
90 }
91
92 DPL::Optional<DPL::String> GetFilePathInWidgetPackageInternal(
93         const DPL::String& basePath,
94         const DPL::String& filePath)
95 {
96     DPL::Optional<std::string> path =
97         GetFilePathInWidgetPackageInternal(DPL::ToUTF8String(basePath),
98                                            DPL::ToUTF8String(filePath));
99     DPL::Optional<DPL::String> dplPath;
100     if (!!path) {
101         dplPath = DPL::FromUTF8String(*path);
102     }
103     return dplPath;
104 }
105 }
106
107 namespace W3CFileLocalization {
108
109 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
110         DbWidgetHandle widgetHandle,
111         const DPL::String &url)
112 {
113     return getFilePathInWidgetPackageFromUrl(
114             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)),
115             url);
116 }
117
118 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
119         const WrtDB::WidgetPkgName &pkgname,
120         const DPL::String &url)
121 {
122     return getFilePathInWidgetPackageFromUrl(
123             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)),
124             url);
125 }
126
127 DPL::Optional<DPL::String> getFilePathInWidgetPackageFromUrl(
128         WrtDB::WidgetDAOReadOnlyPtr dao,
129         const DPL::String &url)
130 {
131     DPL::String req = url;
132
133     if (req.find(WIDGET_URI_BEGIN) == 0) {
134         req.erase(0, WIDGET_URI_BEGIN.length());
135     } else if (req.find(FILE_URI_BEGIN) == 0) {
136         req.erase(0, FILE_URI_BEGIN.length());
137         if (req.find(dao->getPath()) == 0) {
138             req.erase(0, dao->getPath().length());
139         }
140         if (req.find(LOCALE_PREFIX) == 0) {
141             req.erase(0, LOCALE_PREFIX.length());
142             size_t position = req.find('/');
143             // should always be >0 as correct locales path is
144             // always locales/xx/ or locales/xx-XX/
145             if (position != std::string::npos && position > 0) {
146                 req.erase(0, position+1);
147             }
148         }
149     } else {
150         LogDebug("Unknown path format, ignoring");
151         return DPL::Optional<DPL::String>::Null;
152     }
153
154     auto widgetPath = dao->getPath();
155
156     DPL::Optional<DPL::String> found =
157         GetFilePathInWidgetPackageInternal(widgetPath, req);
158
159     if (!found) {
160         LogError("Path not found within current locale in current widget");
161         return DPL::Optional<DPL::String>::Null;
162     }
163
164     found = widgetPath + *found;
165
166     return found;
167 }
168
169 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
170         WrtDB::DbWidgetHandle widgetHandle,
171         const DPL::String& file)
172 {
173     return getFilePathInWidgetPackage(
174             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)),
175             file);
176 }
177
178 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
179         const WrtDB::WidgetPkgName &pkgname,
180         const DPL::String& file)
181 {
182     return getFilePathInWidgetPackage(
183             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)),
184             file);
185 }
186
187 DPL::Optional<DPL::String> getFilePathInWidgetPackage(
188         WrtDB::WidgetDAOReadOnlyPtr dao,
189         const DPL::String& file)
190 {
191     return GetFilePathInWidgetPackageInternal(dao->getPath(), file);
192 }
193
194 DPL::OptionalString getStartFile(const WrtDB::WidgetPkgName & pkgname)
195 {
196     return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)));
197 }
198
199 DPL::OptionalString getStartFile(const WrtDB::DbWidgetHandle handle)
200 {
201     return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(handle)));
202 }
203
204 DPL::OptionalString getStartFile(WrtDB::WidgetDAOReadOnlyPtr dao)
205 {
206     WidgetDAOReadOnly::LocalizedStartFileList locList = dao->getLocalizedStartFileList();
207     WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
208     LanguageTags tagsList = LanguageTagsProviderSingleton::Instance().getLanguageTags();
209
210     DPL::OptionalString defaultLoc = dao->getDefaultlocale();
211     if (!!defaultLoc) {
212         tagsList.push_back(*defaultLoc);
213     }
214
215     FOREACH(tag, tagsList)
216     {
217         FOREACH(sFile, locList)
218         {
219             if (*tag == sFile->widgetLocale) {
220                 FOREACH(it, list)
221                 {
222                     if (it->startFileId == sFile->startFileId) {
223                         return it->src;
224                     }
225                 }
226             }
227         }
228     }
229
230     return DPL::OptionalString::Null;
231 }
232
233 OptionalWidgetIcon getIcon(const WrtDB::WidgetPkgName & pkgname)
234 {
235     return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)));
236 }
237
238 OptionalWidgetIcon getIcon(WrtDB::DbWidgetHandle widgetHandle)
239 {
240     return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
241 }
242
243 OptionalWidgetIcon getIcon(WrtDB::WidgetDAOReadOnlyPtr dao)
244 {
245     WidgetDAOReadOnly::WidgetLocalizedIconList locList = dao->getLocalizedIconList();
246     WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
247     LanguageTags tagsList = LanguageTagsProviderSingleton::Instance().getLanguageTags();
248
249     DPL::OptionalString defaultLoc = dao->getDefaultlocale();
250     if (!!defaultLoc) {
251         tagsList.push_back(*defaultLoc);
252     }
253
254     FOREACH(tag, tagsList)
255     {
256         FOREACH(icon, locList)
257         {
258             if (*tag == icon->widgetLocale) {
259                 FOREACH(it, list)
260                 {
261                     if (it->iconId == icon->iconId) {
262                         WidgetIcon ret;
263                         ret.src = it->iconSrc;
264                         ret.width = it->iconWidth;
265                         ret.height = it->iconHeight;
266                         return ret;
267                     }
268                 }
269             }
270         }
271     }
272
273     return OptionalWidgetIcon::Null;
274 }
275
276 WidgetIconList getValidIconsList(WrtDB::DbWidgetHandle widgetHandle)
277 {
278     return getValidIconsList(
279             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
280 }
281
282 WidgetIconList getValidIconsList(const WrtDB::WidgetPkgName &pkgname)
283 {
284     return getValidIconsList(
285             WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)));
286 }
287
288 WidgetIconList getValidIconsList(WrtDB::WidgetDAOReadOnlyPtr dao)
289 {
290     WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
291
292     WidgetIconList outlist;
293
294     FOREACH(it, list)
295     {
296         LogDebug(":" << it->iconSrc);
297         if (!!getFilePathInWidgetPackage(dao->getHandle(),
298                                          it->iconSrc))
299         {
300             WidgetIcon ret;
301             ret.src = it->iconSrc;
302             ret.width = it->iconWidth;
303             ret.height = it->iconHeight;
304             outlist.push_back(ret);
305         }
306     }
307     return outlist;
308 }
309
310 OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::DbWidgetHandle widgetHandle)
311 {
312     return getStartFileInfo(
313         WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(widgetHandle)));
314 }
315
316 OptionalWidgetStartFileInfo getStartFileInfo(const WrtDB::WidgetPkgName &pkgname)
317 {
318     return getStartFileInfo(
319         WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)));
320
321 }
322
323
324 OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::WidgetDAOReadOnlyPtr dao)
325 {
326     WidgetStartFileInfo info;
327
328     WidgetDAOReadOnly::LocalizedStartFileList locList =
329         dao->getLocalizedStartFileList();
330     WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
331     const LanguageTags tagsList = LanguageTagsProviderSingleton::Instance().getLanguageTags();
332
333     FOREACH(tag, tagsList)
334     {
335         FOREACH(sFile, locList)
336         {
337             if (*tag == sFile->widgetLocale) {
338                 FOREACH(it, list)
339                 {
340                     if (it->startFileId ==
341                         sFile->startFileId) {
342                         info.file = it->src;
343                         info.encoding = sFile->encoding;
344                         info.type = sFile->type;
345                         if (tag->empty()) {
346                             info.localizedPath = it->src;
347                         } else {
348                             info.localizedPath = L"locales/" + *tag + L"/";
349                             info.localizedPath += it->src;
350                         }
351                         return info;
352                     }
353                 }
354             }
355         }
356     }
357
358     return OptionalWidgetStartFileInfo::Null;
359 }
360
361 WidgetLocalizedInfo getLocalizedInfo(const WrtDB::DbWidgetHandle handle)
362 {
363     return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(handle)));
364 }
365
366 WidgetLocalizedInfo getLocalizedInfo(const WrtDB::WidgetPkgName & pkgname)
367 {
368     return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(pkgname)));
369 }
370
371 WidgetLocalizedInfo getLocalizedInfo(WidgetDAOReadOnlyPtr dao)
372 {
373     LanguageTags languages = LanguageTagsProviderSingleton::Instance().getLanguageTags();
374     DPL::OptionalString dl = dao->getDefaultlocale();
375     if (!!dl) {
376         languages.push_back(*dl);
377     }
378
379     WidgetLocalizedInfo result;
380     FOREACH(i, languages)
381     {
382         WidgetLocalizedInfo languageResult = dao->getLocalizedInfo(*i);
383
384 #define OVERWRITE_IF_NULL(FIELD) if (!result.FIELD) { \
385         result.FIELD = languageResult.FIELD; \
386 }
387
388         OVERWRITE_IF_NULL(name);
389         OVERWRITE_IF_NULL(shortName);
390         OVERWRITE_IF_NULL(description);
391         OVERWRITE_IF_NULL(license);
392         OVERWRITE_IF_NULL(licenseHref);
393
394 #undef OVERWRITE_IF_NULL
395     }
396
397     return result;
398 }
399 }