Utilize extracted i18n db in LanguageSubtagRstTree.
[platform/framework/web/wrt-installer.git] / src / 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/log/log.h>
23 #include <dpl/db/orm.h>
24 #include <dpl/string.h>
25 #include <dpl/scope_guard.h>
26 #include <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
27 #include <wrt-commons/i18n-dao-ro/i18n_database.h>
28 #include <iterator>
29 #include <vector>
30 #include <ctype.h>
31 #include <dpl/singleton_impl.h>
32 IMPLEMENT_SINGLETON(LanguageSubtagRstTree)
33
34 namespace I18nDAOReadOnly = I18n::DB::I18nDAOReadOnly;
35
36 bool LanguageSubtagRstTree::ValidateLanguageTag(const std::string &tag_input)
37 {
38     std::string tag = tag_input;
39     std::transform(tag.begin(), tag.end(), tag.begin(), &tolower);
40
41     std::vector<DPL::String> parts;
42     DPL::Tokenize(DPL::FromUTF8String(tag),
43                   '-',
44                   std::back_inserter(parts),
45                   false);
46     std::vector<DPL::String>::iterator token = parts.begin();
47     if (token == parts.end())
48     {
49         return false;
50     }
51
52     I18n::DB::Interface::attachDatabaseRO();
53     DPL_SCOPE_EXIT()
54     {
55         I18n::DB::Interface::detachDatabase();
56     };
57
58     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE))
59     {
60         ++token;
61     }
62     else
63     {
64         return false;
65     }
66
67     if (token == parts.end())
68     {
69         return true;
70     }
71
72     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG))
73     {
74         ++token;
75     }
76
77     if (token == parts.end())
78     {
79         return true;
80     }
81
82     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT))
83     {
84         ++token;
85     }
86
87     if (token == parts.end())
88     {
89         return true;
90     }
91
92     if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION))
93     {
94         ++token;
95     }
96
97     if (token == parts.end())
98     {
99         return true;
100     }
101
102     while (token != parts.end())
103     {
104         if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_VARIANT))
105         {
106             ++token;
107         }
108         else
109         {
110             break;
111         }
112     }
113
114     //'u' - unicode extension - only one BCP47 extension is registered.
115     //TODO: unicode extension should be also validated (l.wrzosek)
116     if (token == parts.end())
117     {
118         return true;
119     }
120
121     if (*token == L"u")
122     {
123         ++token;
124         bool one_or_more = false;
125         while (token != parts.end() &&
126                token->size() > 1 &&
127                token->size() <= 8)
128         {
129             one_or_more = true;
130             ++token;
131         }
132         if (!one_or_more)
133         {
134             return false;
135         }
136     }
137
138     //'x' - privateuse
139     if (token == parts.end())
140     {
141         return true;
142     }
143
144     if (*token == L"x")
145     {
146         ++token;
147         bool one_or_more = false;
148         while (token != parts.end() &&
149                !token->empty() &&
150                token->size() <= 8)
151         {
152             one_or_more = true;
153             ++token;
154         }
155         if (!one_or_more)
156         {
157             return false;
158         }
159     }
160
161     if (token == parts.end())
162     {
163         return true;
164     }
165
166     //Try private use now:
167     token = parts.begin();
168     if (*token == L"x")
169     {
170         ++token;
171         bool one_or_more = false;
172         while (token != parts.end() &&
173                !token->empty() &&
174                token->size() <= 8)
175         {
176             one_or_more = true;
177             ++token;
178         }
179         return one_or_more;
180     }
181
182     //grandfathered is always rejected
183     return false;
184 }
185
186 #define TEST_LANG(str, cond) \
187     if (LanguageSubtagRstTreeSingleton::Instance(). \
188             ValidateLanguageTag(str) == cond) { \
189         LogDebug("Good validate status for lang: " << str); \
190     } else { \
191         LogError("Wrong validate status for lang: " << str \
192                                                     << ", should be " << 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