69e6d41a38f75b8a75e1e4a9b758d513341dec46
[platform/framework/web/wrt-commons.git] / modules / localization / src / LanguageTagsProvider.cpp
1 /*
2  * Copyright (c) 2012 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    LanguageTagsProvider.cpp
18  * @author  Marcin Kaminski (marcin.ka@samsung.com)
19  * @version 1.0
20  */
21
22 #include "LanguageTagsProvider.h"
23
24 #include <dpl/log/log.h>
25 #include <vconf.h>
26 #include <algorithm>
27 #include <iostream>
28 #include <cassert>
29 #include <dpl/singleton_impl.h>
30 IMPLEMENT_SINGLETON(LanguageTagsProvider)
31
32 /* ========== public ========== */
33 const LanguageTags LanguageTagsProvider::getLanguageTags() const
34 {
35     return m_languageTagsList;
36 }
37
38 void LanguageTagsProvider::setLanguageTags(const LanguageTags& taglist)
39 {
40     m_languageTagsList = taglist;
41     /* If given list does not contain default values ("en" and empty string)
42      * than append them to the list.
43      * In case of empty list given as parameter only two default values
44      * will exist on m_languageTagsList. */
45     DPL::String tofind = L"en";
46     if(std::find(m_languageTagsList.begin(), m_languageTagsList.end(),
47             tofind) == m_languageTagsList.end()) {
48         m_languageTagsList.push_back(L"en");
49     }
50     tofind = L"";
51     if(std::find(m_languageTagsList.begin(), m_languageTagsList.end(),
52             tofind) == m_languageTagsList.end()) {
53         m_languageTagsList.push_back(L"");
54     }
55 }
56
57 void LanguageTagsProvider::setLanguageTagsFromLocales(const char* locales)
58 {
59     LogDebug("Setting new language tags for locales " << locales);
60     this->createTagsFromLocales(locales);
61 }
62
63 void LanguageTagsProvider::resetLanguageTags()
64 {
65     this->loadSystemTags();
66 }
67
68 DPL::String LanguageTagsProvider::BCP47LanguageTagToLocale(const DPL::String& inLanguageTag)
69 {
70     DPL::String languageTag(inLanguageTag);
71     /* Replace all */
72     std::replace(languageTag.begin(), languageTag.end(), '-', '_');
73     return languageTag;
74 }
75
76 DPL::String LanguageTagsProvider::LocaleToBCP47LanguageTag(const DPL::String& inLocaleString)
77 {
78     /* Cut off codepage information from given string (if any exists)
79      * i.e. change en_US.UTF-8 into en_US */
80     DPL::String localeString = inLocaleString.substr(
81             0, inLocaleString.find_first_of(L"."));
82     /* Replace all '_' with '-' */
83     std::replace(localeString.begin(), localeString.end(), '_', '-');
84     return localeString;
85 }
86
87 /* ========== private ========== */
88 LanguageTagsProvider::LanguageTagsProvider()
89 {
90     LogDebug("Creating LanguageTagsProvider instance");
91     this->loadSystemTags();
92 }
93
94 LanguageTagsProvider::~LanguageTagsProvider()
95 {
96 }
97
98 void LanguageTagsProvider::loadSystemTags()
99 {
100     char* language = vconf_get_str(VCONFKEY_LANGSET);
101     if(!language) {
102         LogError("Failed to get language from vconf");
103     }
104     else {
105         LogDebug("Language fetched from vconf: " << language);
106     }
107     createTagsFromLocales(language);
108     free(language);
109 }
110
111 void LanguageTagsProvider::createTagsFromLocales(const char* language)
112 {
113     m_languageTagsList.clear();
114     if(!language) {
115         LogDebug("Setting default language tags");
116         /* If NULL language given than set default language tags
117          * and return. */
118         m_languageTagsList.push_back(L"en");
119         m_languageTagsList.push_back(L"");
120         return;
121     }
122
123     LogDebug("Setting tags for language: " << language);
124     DPL::String langdescr = LocaleToBCP47LanguageTag(DPL::FromUTF8String(language));
125
126     size_t position;
127     if(langdescr.empty()) {
128         LogError("Empty language description while correct value needed");
129     }
130     else {
131         /* Language tags list should not be cleared before this place to
132          * avoid losing current data when new data are invalid */
133         while (true) {
134             LogDebug("Processing language description: " << langdescr);
135             m_languageTagsList.push_back(langdescr);
136
137             position = langdescr.find_last_of(L"-");
138             if (position == DPL::String::npos) {
139                 break;
140             }
141             langdescr = langdescr.substr(0, position);
142         }
143     }
144     /* If current content of langdescr (thus last added added tag)
145      * is not "en" then add english as default locales.
146      * "en" and empty tag are added even when langdescr is not valid. */
147     if (langdescr.compare(L"en") != 0){
148         m_languageTagsList.push_back(L"en");
149     }
150     /* Add empty tag for non-localized content */
151     m_languageTagsList.push_back(L"");
152 }