Initialize Tizen 2.3
[framework/web/wrt-installer.git] / src_wearable / wrt-installer / language_subtag_rst_tree.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    language_subtag_rst_tree.cpp
18  * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version 1.0
20  */
21 #include <language_subtag_rst_tree.h>
22 #include <dpl/db/orm.h>
23 #include <dpl/string.h>
24 #include <dpl/scope_guard.h>
25 #include <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
26 #include <wrt-commons/i18n-dao-ro/i18n_database.h>
27 #include <iterator>
28 #include <vector>
29 #include <ctype.h>
30 #include <dpl/singleton_impl.h>
31 #include <installer_log.h>
32
33 IMPLEMENT_SINGLETON(LanguageSubtagRstTree)
34
35 namespace I18nDAOReadOnly = I18n::DB::I18nDAOReadOnly;
36
37 bool LanguageSubtagRstTree::ValidateLanguageTag(const std::string &tag_input)
38 {
39     std::string tag = tag_input;
40     std::transform(tag.begin(), tag.end(), tag.begin(), &tolower);
41
42     std::vector<DPL::String> parts;
43     DPL::Tokenize(DPL::FromUTF8String(tag),
44                   '-',
45                   std::back_inserter(parts),
46                   false);
47     std::vector<DPL::String>::iterator token = parts.begin();
48     if (token == parts.end())
49     {
50         return false;
51     }
52
53     I18n::DB::Interface::attachDatabaseRO();
54     DPL_SCOPE_EXIT()
55     {
56         I18n::DB::Interface::detachDatabase();
57     };
58
59     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE))
60     {
61         ++token;
62     }
63     else
64     {
65         return false;
66     }
67
68     if (token == parts.end())
69     {
70         return true;
71     }
72
73     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG))
74     {
75         ++token;
76     }
77
78     if (token == parts.end())
79     {
80         return true;
81     }
82
83     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT))
84     {
85         ++token;
86     }
87
88     if (token == parts.end())
89     {
90         return true;
91     }
92
93     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION))
94     {
95         ++token;
96     }
97
98     if (token == parts.end())
99     {
100         return true;
101     }
102
103     while (token != parts.end())
104     {
105         if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_VARIANT))
106         {
107             ++token;
108         }
109         else
110         {
111             break;
112         }
113     }
114
115     //'u' - unicode extension - only one BCP47 extension is registered.
116     //TODO: unicode extension should be also validated (l.wrzosek)
117     if (token == parts.end())
118     {
119         return true;
120     }
121
122     if (*token == L"u")
123     {
124         ++token;
125         bool one_or_more = false;
126         while (token != parts.end() &&
127                token->size() > 1 &&
128                token->size() <= 8)
129         {
130             one_or_more = true;
131             ++token;
132         }
133         if (!one_or_more)
134         {
135             return false;
136         }
137     }
138
139     //'x' - privateuse
140     if (token == parts.end())
141     {
142         return true;
143     }
144
145     if (*token == L"x")
146     {
147         ++token;
148         bool one_or_more = false;
149         while (token != parts.end() &&
150                !token->empty() &&
151                token->size() <= 8)
152         {
153             one_or_more = true;
154             ++token;
155         }
156         if (!one_or_more)
157         {
158             return false;
159         }
160     }
161
162     if (token == parts.end())
163     {
164         return true;
165     }
166
167     //Try private use now:
168     token = parts.begin();
169     if (*token == L"x")
170     {
171         ++token;
172         bool one_or_more = false;
173         while (token != parts.end() &&
174                !token->empty() &&
175                token->size() <= 8)
176         {
177             one_or_more = true;
178             ++token;
179         }
180         return one_or_more;
181     }
182
183     //grandfathered is always rejected
184     return false;
185 }
186
187 #define TEST_LANG(str, cond) \
188     if (LanguageSubtagRstTreeSingleton::Instance(). \
189             ValidateLanguageTag(str) == cond) { \
190         _D("Good validate status for lang: %s", str); \
191     } else { \
192         _E("Wrong validate status for lang: %s, should be %d", str, cond); \
193     }
194
195 void LanguageSubtagRstTree::Initialize()
196 {
197     /* Temporarily added unit test. Commented out due to performance drop.
198      * TEST_LANG("zh", true);
199      * TEST_LANG("esx-al", true);
200      * TEST_LANG("zh-Hant", true);
201      * TEST_LANG("zh-Hant-CN", true);
202      * TEST_LANG("zh-Hant-CN-x-private1-private2", true);
203      * TEST_LANG("plxxx", false);
204      * TEST_LANG("pl-x-private111", false);
205      * TEST_LANG("x-private1", false); //do not support pure private ones
206      * TEST_LANG("x-private22", false);
207      * TEST_LANG("i-private22", false); //do not support i-*
208      */
209 }
210
211 #undef TEST_LANG