Tizen 2.0 Release
[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 #include <stddef.h>
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 value (empty string)
42      * than append it to the list.
43      * In case of empty list given as parameter only default value
44      * will exist on m_languageTagsList. */
45     DPL::String tofind = L"";
46     if(std::find(m_languageTagsList.begin(), m_languageTagsList.end(),
47             tofind) == m_languageTagsList.end()) {
48         m_languageTagsList.push_back(L"");
49     }
50 }
51
52 void LanguageTagsProvider::setLanguageTagsFromLocales(const char* locales)
53 {
54     LogDebug("Setting new language tags for locales " << locales);
55     this->createTagsFromLocales(locales);
56 }
57
58 void LanguageTagsProvider::resetLanguageTags()
59 {
60     this->loadSystemTags();
61 }
62
63 void LanguageTagsProvider::addWidgetDefaultLocales(const DPL::String& defaultLocale){
64     if (defaultLocale.size() > 0 &&
65         std::find(m_languageTagsList.begin(), m_languageTagsList.end(), defaultLocale) == m_languageTagsList.end())
66     {
67         if (m_languageTagsList.size() < 2) {
68             m_languageTagsList.push_front(defaultLocale);
69         } else {
70             LanguageTags::iterator placeToInsert = m_languageTagsList.end();
71             --placeToInsert;
72             if (*placeToInsert != L"")
73             {
74                 ++placeToInsert;
75             }
76             m_languageTagsList.insert(placeToInsert, defaultLocale);
77         }
78     }
79 }
80
81 DPL::String LanguageTagsProvider::BCP47LanguageTagToLocale(const DPL::String& inLanguageTag)
82 {
83     DPL::String languageTag(inLanguageTag);
84     /* Replace all */
85     std::replace(languageTag.begin(), languageTag.end(), '-', '_');
86     return languageTag;
87 }
88
89 DPL::String LanguageTagsProvider::LocaleToBCP47LanguageTag(const DPL::String& inLocaleString)
90 {
91     /* Cut off codepage information from given string (if any exists)
92      * i.e. change en_US.UTF-8 into en_US */
93     DPL::String localeString = inLocaleString.substr(
94             0, inLocaleString.find_first_of(L"."));
95     /* Replace all '_' with '-' */
96     std::replace(localeString.begin(), localeString.end(), '_', '-');
97     return localeString;
98 }
99
100 /* ========== private ========== */
101 LanguageTagsProvider::LanguageTagsProvider()
102 {
103     LogDebug("Creating LanguageTagsProvider instance");
104     this->loadSystemTags();
105 }
106
107 LanguageTagsProvider::~LanguageTagsProvider()
108 {
109 }
110
111 void LanguageTagsProvider::loadSystemTags()
112 {
113     char* language = vconf_get_str(VCONFKEY_LANGSET);
114     if(!language) {
115         LogError("Failed to get language from vconf");
116     }
117     else {
118         LogDebug("Language fetched from vconf: " << language);
119     }
120     createTagsFromLocales(language);
121     free(language);
122 }
123
124 void LanguageTagsProvider::createTagsFromLocales(const char* language)
125 {
126     m_languageTagsList.clear();
127     if(!language) {
128         LogDebug("Setting default language tags");
129         /* If NULL language given than set default language tags
130          * and return. */
131         m_languageTagsList.push_back(L"");
132         return;
133     }
134
135     LogDebug("Setting tags for language: " << language);
136     DPL::String langdescr = LocaleToBCP47LanguageTag(DPL::FromUTF8String(language));
137
138     size_t position;
139     if(langdescr.empty()) {
140         LogError("Empty language description while correct value needed");
141     }
142     else {
143         /* Language tags list should not be cleared before this place to
144          * avoid losing current data when new data are invalid */
145         while (true) {
146             LogDebug("Processing language description: " << langdescr);
147             m_languageTagsList.push_back(langdescr);
148
149             position = langdescr.find_last_of(L"-");
150             if (position == DPL::String::npos) {
151                 break;
152             }
153             langdescr = langdescr.substr(0, position);
154         }
155     }
156     /* Add empty tag for non-localized content */
157     m_languageTagsList.push_back(L"");
158 }