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