2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * @file w3c_file_localization.cpp
18 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
22 #include <sys/types.h>
27 #include <dpl/localization/w3c_file_localization.h>
29 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
30 #include <dpl/localization/localization_utils.h>
32 #include <dpl/log/wrt_log.h>
33 #include <dpl/string.h>
34 #include <dpl/foreach.h>
36 #include <LanguageTagsProvider.h>
38 using namespace WrtDB;
41 const DPL::String FILE_URI_BEGIN = L"file://";
42 const DPL::String WIDGET_URI_BEGIN = L"widget://";
43 const DPL::String APP_URI_BEGIN = L"app://";
44 const DPL::String LOCALE_PREFIX = L"locales/";
46 DPL::OptionalStdString GetFilePathInWidgetPackageInternal(
47 const std::string& basePath,
50 WrtLogD("Looking for file: %s in: %s", filePath.c_str(), basePath.c_str());
52 const LanguageTags& ltags =
53 LanguageTagsProviderSingleton::Instance().getLanguageTags();
55 //Check if string isn't empty
56 if (filePath.size() == 0) {
57 return DPL::OptionalStdString();
59 //Removing preceding '/'
60 if (filePath[0] == '/') {
63 // In some cases (start file localization) url has unnecessary "/" at the
65 if (filePath[filePath.size() - 1] == '/') {
66 filePath.erase(filePath.size() - 1, 1);
68 //Check if string isn't empty
69 if (filePath.size() == 0) {
70 return DPL::OptionalStdString();
73 WrtLogD("locales size = %i", ltags.size());
74 for (LanguageTags::const_iterator it = ltags.begin();
78 WrtLogD("Trying locale: %ls", it->c_str());
79 std::string path = basePath;
80 if (path[path.size() - 1] == '/') {
81 path.erase(path.size() - 1);
85 path += "/" + filePath;
87 path += "/locales/" + DPL::ToUTF8String(*it) + "/" + filePath;
90 WrtLogD("Trying locale: %ls | %s", it->c_str(), path.c_str());
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::OptionalStdString(path);
100 return DPL::OptionalStdString();
103 DPL::OptionalString GetFilePathInWidgetPackageInternal(
104 const DPL::String& basePath,
105 const DPL::String& filePath)
107 DPL::OptionalStdString path =
108 GetFilePathInWidgetPackageInternal(DPL::ToUTF8String(basePath),
109 DPL::ToUTF8String(filePath));
110 DPL::OptionalString dplPath;
112 dplPath = DPL::FromUTF8String(*path);
118 namespace W3CFileLocalization {
119 static bool isExistFileCached(const std::string& path)
121 static std::map<std::string, bool> pathCache;
124 if (pathCache.find(path) == pathCache.end())
128 if (0 == stat(path.c_str(), &buf))
130 pathCache[path] = true;
136 pathCache[path] = false;
142 return pathCache[path];
145 std::string getFilePathInWidgetPackageFromUrl(const std::string &tzAppId, const std::string &url)
147 const std::string SCHEME_FILE = "file://";
148 const std::string SCHEME_WIDGET = "widget://";
149 const std::string SCHEM_APP = "app://";
150 const std::string LOCALE_PATH = "locales/";
151 const std::string DOUBLE_ROOT = "//";
153 static std::string lastTzAppId;
154 static WidgetDAOReadOnlyPtr dao;
155 static std::string srcPath;
157 std::string workingUrl = url;
161 if (lastTzAppId != tzAppId)
163 lastTzAppId = tzAppId;
164 dao.reset(new WidgetDAOReadOnly(DPL::FromUTF8String(tzAppId)));
165 srcPath = DPL::ToUTF8String(dao->getPath());
168 // backup suffix string
169 std::string backupSuffix;
170 size_t pos = workingUrl.find_first_of("#?");
172 if (pos != std::string::npos)
174 backupSuffix = workingUrl.substr(pos);
175 workingUrl.resize(pos);
179 if (workingUrl.compare(0, SCHEME_WIDGET.length(), SCHEME_WIDGET) == 0)
181 // remove "widget://"
182 workingUrl.erase(0, SCHEME_WIDGET.length());
184 else if (workingUrl.compare(0, SCHEME_FILE.length(), SCHEME_FILE) == 0)
187 workingUrl.erase(0, SCHEME_FILE.length());
189 // exception handling for "//"
190 if (workingUrl.compare(0, DOUBLE_ROOT.length(), DOUBLE_ROOT) == 0)
192 workingUrl.erase(0, 1);
193 WrtLogD("workingUrl: %s", workingUrl.c_str());
197 if (workingUrl.compare(0, srcPath.length(), srcPath) == 0)
199 workingUrl.erase(0, srcPath.length());
202 // remove locale path
203 if (workingUrl.compare(0, LOCALE_PATH.length(), LOCALE_PATH) == 0)
205 workingUrl.erase(0, LOCALE_PATH.length());
207 pos = workingUrl.find_first_of('/');
209 if (pos != std::string::npos && pos > 0)
211 workingUrl.erase(0, pos+1);
215 else if (workingUrl.compare(0, SCHEM_APP.length(), SCHEM_APP) == 0)
218 workingUrl.erase(0, SCHEM_APP.length());
220 // remove tizen app id
221 if (workingUrl.compare(0, tzAppId.length(), tzAppId) == 0)
223 workingUrl.erase(0, tzAppId.length());
227 WrtLogE("Tizen id does not match, ignoring");
233 if (!workingUrl.empty() && workingUrl[0] == '/')
235 workingUrl.erase(0, 1);
238 if (!workingUrl.empty() && workingUrl[workingUrl.length()-1] == '/') {
239 workingUrl.erase(workingUrl.length()-1, 1);
242 if (workingUrl.empty())
244 WrtLogE("URL Localization Error!");
248 const LanguageTags& ltags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
252 std::string path = srcPath;
258 if (isExistFileCached(path) == false)
263 path += DPL::ToUTF8String(*it) + "/";
265 if (isExistFileCached(path) == false)
273 if (isExistFileCached(path) == true)
281 // restore suffix string
284 // return empty string
289 if (!backupSuffix.empty())
291 workingUrl += backupSuffix;
298 DPL::OptionalString getFilePathInWidgetPackageFromUrl(
299 const WrtDB::TizenAppId &tzAppId,
300 const DPL::String &url)
302 return getFilePathInWidgetPackageFromUrl(
303 WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
307 DPL::OptionalString getFilePathInWidgetPackageFromUrl(
308 WrtDB::WidgetDAOReadOnlyPtr dao,
309 const DPL::String &url)
311 DPL::String req = url;
314 DPL::String::size_type pos = req.find_first_of('#');
315 if(pos != DPL::String::npos)
317 suffix = req.substr(pos) + suffix;
318 req.resize(pos); //truncate fragment identifier
321 pos = req.find_first_of('?');
322 if(pos != DPL::String::npos)
324 suffix = req.substr(pos) + suffix;
325 req.resize(pos); //truncate query string
328 if (req.find(WIDGET_URI_BEGIN) == 0) {
329 req.erase(0, WIDGET_URI_BEGIN.length());
330 } else if (req.find(FILE_URI_BEGIN) == 0) {
331 req.erase(0, FILE_URI_BEGIN.length());
332 if (req.find(dao->getPath()) == 0) {
333 req.erase(0, dao->getPath().length());
335 if (req.find(LOCALE_PREFIX) == 0) {
336 req.erase(0, LOCALE_PREFIX.length());
337 size_t position = req.find('/');
338 // should always be >0 as correct locales path is
339 // always locales/xx/ or locales/xx-XX/
340 if (position != std::string::npos && position > 0) {
341 req.erase(0, position + 1);
344 } else if(req.find(APP_URI_BEGIN) == 0) {
345 req.erase(0, APP_URI_BEGIN.length());
346 DPL::String id = dao->getTizenAppId();
347 if(req.substr(0, id.size()) != id)
349 WrtLogE("Tizen id does not match, ignoring");
350 return DPL::OptionalString();
352 req.erase(0, id.length());
354 WrtLogD("Unknown path format, ignoring");
355 return DPL::OptionalString();
358 auto widgetPath = dao->getPath();
360 WrtLogD("Required path: %ls", req.c_str());
361 DPL::OptionalString found =
362 GetFilePathInWidgetPackageInternal(widgetPath, req);
365 WrtLogE("Path not found within current locale in current widget");
366 return DPL::OptionalString();
369 found = widgetPath + *found + suffix;
374 DPL::OptionalString getFilePathInWidgetPackage(
375 const WrtDB::TizenAppId &tzAppId,
376 const DPL::String& file)
378 return getFilePathInWidgetPackage(
379 WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)),
383 DPL::OptionalString getFilePathInWidgetPackage(
384 WrtDB::WidgetDAOReadOnlyPtr dao,
385 const DPL::String& file)
387 return GetFilePathInWidgetPackageInternal(dao->getPath(), file);
390 DPL::OptionalString getStartFile(const WrtDB::TizenAppId & tzAppId)
392 return getStartFile(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
395 DPL::OptionalString getStartFile(WrtDB::WidgetDAOReadOnlyPtr dao)
397 WidgetDAOReadOnly::LocalizedStartFileList locList =
398 dao->getLocalizedStartFileList();
399 WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
400 LanguageTags tagsList =
401 LanguageTagsProviderSingleton::Instance().getLanguageTags();
403 DPL::OptionalString defaultLoc = dao->getDefaultlocale();
405 tagsList.push_back(*defaultLoc);
408 FOREACH(tag, tagsList)
410 FOREACH(sFile, locList)
412 if (*tag == sFile->widgetLocale) {
415 if (it->startFileId == sFile->startFileId) {
423 return DPL::OptionalString();
426 OptionalWidgetIcon getIcon(const WrtDB::TizenAppId & tzAppId)
428 return getIcon(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
431 OptionalWidgetIcon getIcon(WrtDB::WidgetDAOReadOnlyPtr dao)
433 WidgetDAOReadOnly::WidgetLocalizedIconList locList =
434 dao->getLocalizedIconList();
435 WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
436 LanguageTags tagsList =
437 LanguageTagsProviderSingleton::Instance().getLanguageTags();
439 DPL::OptionalString defaultLoc = dao->getDefaultlocale();
441 tagsList.push_back(*defaultLoc);
444 FOREACH(tag, tagsList)
446 FOREACH(icon, locList)
448 if (*tag == icon->widgetLocale) {
451 if (it->iconId == icon->iconId) {
453 ret.src = it->iconSrc;
454 ret.width = it->iconWidth;
455 ret.height = it->iconHeight;
463 return OptionalWidgetIcon();
466 WidgetIconList getValidIconsList(const WrtDB::TizenAppId &tzAppId)
468 return getValidIconsList(
469 WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
472 WidgetIconList getValidIconsList(WrtDB::WidgetDAOReadOnlyPtr dao)
474 WidgetDAOReadOnly::WidgetIconList list = dao->getIconList();
476 WidgetIconList outlist;
480 WrtLogD(":%ls", it->iconSrc.c_str());
481 if (!!getFilePathInWidgetPackage(dao->getTizenAppId(),
485 ret.src = it->iconSrc;
486 ret.width = it->iconWidth;
487 ret.height = it->iconHeight;
488 outlist.push_back(ret);
494 OptionalWidgetStartFileInfo getStartFileInfo(
495 const WrtDB::TizenAppId &tzAppId)
497 return getStartFileInfo(
498 WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
501 OptionalWidgetStartFileInfo getStartFileInfo(WrtDB::WidgetDAOReadOnlyPtr dao)
503 WidgetStartFileInfo info;
505 WidgetDAOReadOnly::LocalizedStartFileList locList =
506 dao->getLocalizedStartFileList();
507 WidgetDAOReadOnly::WidgetStartFileList list = dao->getStartFileList();
508 const LanguageTags tagsList =
509 LanguageTagsProviderSingleton::Instance().getLanguageTags();
511 FOREACH(tag, tagsList)
513 FOREACH(sFile, locList)
515 if (*tag == sFile->widgetLocale) {
518 if (it->startFileId ==
522 info.encoding = sFile->encoding;
523 info.type = sFile->type;
525 info.localizedPath = it->src;
527 info.localizedPath = L"locales/" + *tag + L"/";
528 info.localizedPath += it->src;
537 return OptionalWidgetStartFileInfo();
540 WidgetLocalizedInfo getLocalizedInfo(const WrtDB::TizenAppId & tzAppId)
542 return getLocalizedInfo(WidgetDAOReadOnlyPtr(new WidgetDAOReadOnly(tzAppId)));
545 WidgetLocalizedInfo getLocalizedInfo(WidgetDAOReadOnlyPtr dao)
547 LanguageTags languages =
548 LanguageTagsProviderSingleton::Instance().getLanguageTags();
549 DPL::OptionalString dl = dao->getDefaultlocale();
551 languages.push_back(*dl);
554 WidgetLocalizedInfo result;
555 FOREACH(i, languages)
557 WidgetLocalizedInfo languageResult = dao->getLocalizedInfo(*i);
559 #define OVERWRITE_IF_NULL(FIELD) if (!result.FIELD) { \
560 result.FIELD = languageResult.FIELD; \
563 OVERWRITE_IF_NULL(name);
564 OVERWRITE_IF_NULL(shortName);
565 OVERWRITE_IF_NULL(description);
566 OVERWRITE_IF_NULL(license);
567 OVERWRITE_IF_NULL(licenseHref);
569 #undef OVERWRITE_IF_NULL