e26fef0a98e18560e3b75e2bb0e525f39027cace
[platform/framework/web/crosswalk-tizen.git] / src / common / locale_manager.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "common/locale_manager.h"
6
7 #include <runtime_info.h>
8 #include <memory>
9 #include <algorithm>
10
11 #include "common/logger.h"
12 #include "common/file_utils.h"
13
14 namespace wrt {
15
16 namespace {
17
18 std::string localeToBCP47LangTag(
19     const std::string locale) {
20   // Cut off codepage information from given string (if any exists)
21   // i.e. change en_US.UTF-8 into en_US */
22   std::string lang = locale.substr(0, locale.find_first_of("."));
23
24   // Replace all '_' with '-'
25   std::replace(lang.begin(), lang.end(), '_', '-');
26   return lang;
27 }
28
29 }  // namespace
30
31
32 LocaleManager::LocaleManager() {
33   UpdateSystemLocale();
34 }
35
36 LocaleManager::~LocaleManager() {
37   runtime_info_unset_changed_cb(RUNTIME_INFO_KEY_LANGUAGE);
38 }
39
40 void LocaleManager::EnableAutoUpdate(bool enable) {
41   if (enable) {
42     auto callback = [](runtime_info_key_e, void* user_data) {
43         LocaleManager* locale = static_cast<LocaleManager*>(user_data);
44         locale->UpdateSystemLocale();
45     };
46     runtime_info_set_changed_cb(RUNTIME_INFO_KEY_LANGUAGE, callback, this);
47   } else {
48     runtime_info_unset_changed_cb(RUNTIME_INFO_KEY_LANGUAGE);
49   }
50 }
51
52 void LocaleManager::SetDefaultLocale(const std::string& locale) {
53   if (!default_locale_.empty() && system_locales_.size() > 0 &&
54        system_locales_.back() == default_locale_) {
55     system_locales_.pop_back();
56   }
57   default_locale_ = locale;
58   if (!default_locale_.empty()) {
59     system_locales_.push_back(locale);
60   }
61 }
62
63 void LocaleManager::UpdateSystemLocale() {
64   char* str = NULL;
65   if (RUNTIME_INFO_ERROR_NONE !=
66       runtime_info_get_value_string(RUNTIME_INFO_KEY_LANGUAGE, &str)
67      || str == NULL) {
68     return;
69   }
70   std::string lang = localeToBCP47LangTag(str);
71   free(str);
72
73   if (lang.length() == 0) {
74     LOGGER(ERROR) << "Language tag was invalid";
75     return;
76   }
77
78   system_locales_.clear();
79   while (true) {
80     LOGGER(DEBUG) << "Processing language description: " << lang;
81     system_locales_.push_back(lang);
82
83     // compatibility with lower language Tag by SDK
84     std::string lower = lang;
85     std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
86     if (lower != lang) {
87       system_locales_.push_back(lower);
88     }
89     size_t position = lang.find_last_of("-");
90     if (position == std::string::npos) {
91       break;
92     }
93     lang = lang.substr(0, position);
94   }
95   if (!default_locale_.empty()) {
96     system_locales_.push_back(default_locale_);
97   }
98 }
99
100 std::string LocaleManager::GetLocalizedString(const StringMap& strmap) {
101   if (strmap.empty()) {
102     return std::string();
103   }
104
105   // find string with system locales
106   for (auto& locale : system_locales_) {
107     auto it = strmap.find(locale);
108     if (it != strmap.end()) {
109       return it->second;
110     }
111   }
112
113   // find string with empty locale
114   auto it = strmap.find("");
115   if (it != strmap.end()) {
116     return it->second;
117   }
118
119   // If localized string is not found, return first string.
120   return strmap.begin()->second;
121 }
122
123 }  // namespace wrt