1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific locale governing permissions and
13  * limitations under the License.
14  */
15 #include "date_rule_init.h"
16 #include "i18n_hilog.h"
17 
18 namespace OHOS {
19 namespace Global {
20 namespace I18n {
DateRuleInit(std::string & locale)21 DateRuleInit::DateRuleInit(std::string& locale)
22 {
23     dateTimeRule = new DateTimeRule(locale);
24     if (dateTimeRule == nullptr) {
25         HILOG_ERROR_I18N("DateTimeRule construct failed.");
26         return;
27     }
28     this->locale = dateTimeRule->GetLocale();
29     filter = new DateTimeFilter(this->locale, dateTimeRule);
30     if (filter == nullptr) {
31         HILOG_ERROR_I18N("DateTimeFilter construct failed.");
32     }
33     Init();
34 }
35 
~DateRuleInit()36 DateRuleInit::~DateRuleInit()
37 {
38     if (dateTimeRule != nullptr) {
39         delete dateTimeRule;
40     }
41     if (filter != nullptr) {
42         delete filter;
43     }
44 }
45 
Detect(icu::UnicodeString & message)46 std::vector<MatchedDateTimeInfo> DateRuleInit::Detect(icu::UnicodeString& message)
47 {
48     std::vector<MatchedDateTimeInfo> matches = GetMatches(message);
49     std::vector<MatchedDateTimeInfo> clearMatches = ClearFind(message);
50     std::vector<MatchedDateTimeInfo> pastMatches = PastFind(message);
51     if (filter != nullptr) {
52         // Filter results that don't meet rules
53         matches = filter->Filter(message, matches, clearMatches, pastMatches);
54     }
55     return matches;
56 }
57 
58 // Obtains result that meet the clear rules
ClearFind(icu::UnicodeString & message)59 std::vector<MatchedDateTimeInfo> DateRuleInit::ClearFind(icu::UnicodeString& message)
60 {
61     return this->clearRulesEngine.Match(message);
62 }
63 
64 // Obtains result that meet the past rules
PastFind(icu::UnicodeString & message)65 std::vector<MatchedDateTimeInfo> DateRuleInit::PastFind(icu::UnicodeString& message)
66 {
67     return this->pastRulesEngine.Match(message);
68 }
69 
Init()70 void DateRuleInit::Init()
71 {
72     // create rulesEngine based on the UniverseRules.
73     RulesSet rulesSet1(dateTimeRule->GetUniverseRules(), dateTimeRule->GetSubRules(), dateTimeRule->GetParam(),
74         dateTimeRule->GetParamBackup());
75     RulesEngine rulesEngine1(dateTimeRule, rulesSet1);
76     universalAndLocaleRules.push_back(rulesEngine1);
77 
78     std::unordered_map<std::string, std::string> nullMap;
79     // create rulesEngine based on the LocalesRules.
80     if (dateTimeRule->GetLocalesRules().size() != 0) {
81         RulesSet rulesSet2(dateTimeRule->GetLocalesRules(), dateTimeRule->GetSubRules(), dateTimeRule->GetParam(),
82             nullMap);
83         RulesEngine rulesEngine2(dateTimeRule, rulesSet2);
84         universalAndLocaleRules.push_back(rulesEngine2);
85     }
86 
87     // create rulesEngine based on the LocalesRulesBackup.
88     if (dateTimeRule->GetLocalesRulesBackup().size() != 0) {
89         RulesSet rulesSet3(dateTimeRule->GetLocalesRulesBackup(), dateTimeRule->GetSubRules(),
90             dateTimeRule->GetParamBackup(), nullMap);
91         RulesEngine rulesEngine3(dateTimeRule, rulesSet3);
92         universalAndLocaleRules.push_back(rulesEngine3);
93     }
94 
95     // create rulesEngine based on the SubRules.
96     for (auto& kv : dateTimeRule->GetSubRulesMap()) {
97         RulesSet rulesSet4(kv.second, dateTimeRule->GetSubRules(), dateTimeRule->GetParam(),
98             dateTimeRule->GetParamBackup());
99         RulesEngine rulesEngine4(dateTimeRule, rulesSet4);
100         subDetectsMap[kv.first] = rulesEngine4;
101     }
102 
103     // create rulesEngine based on the FilterRules.
104     RulesSet rulesSet5(dateTimeRule->GetFilterRules(), dateTimeRule->GetSubRules(), dateTimeRule->GetParam(),
105         dateTimeRule->GetParamBackup());
106     RulesEngine rulesEngine5(dateTimeRule, rulesSet5);
107     this->clearRulesEngine = rulesEngine5;
108 
109     // create rulesEngine based on the PastRules.
110     RulesSet rulesSet6(dateTimeRule->GetPastRules(), nullMap, dateTimeRule->GetParam(),
111         dateTimeRule->GetParamBackup());
112     RulesEngine rulesEngine6(dateTimeRule, rulesSet6);
113     this->pastRulesEngine = rulesEngine6;
114 }
115 
116 // obtains the date and time information in the message.
GetMatches(icu::UnicodeString & message)117 std::vector<MatchedDateTimeInfo> DateRuleInit::GetMatches(icu::UnicodeString& message)
118 {
119     std::vector<MatchedDateTimeInfo> matches;
120     for (auto& detect : universalAndLocaleRules) {
121         std::vector<MatchedDateTimeInfo> tempMatches = detect.Match(message);
122         for (MatchedDateTimeInfo& match : tempMatches) {
123             GetMatchedInfo(matches, match, message);
124         }
125     }
126     return matches;
127 }
128 
GetMatchedInfo(std::vector<MatchedDateTimeInfo> & matches,MatchedDateTimeInfo & match,icu::UnicodeString & message)129 void DateRuleInit::GetMatchedInfo(std::vector<MatchedDateTimeInfo>& matches, MatchedDateTimeInfo& match,
130     icu::UnicodeString& message)
131 {
132     // splitting results based on subRules.
133     if (subDetectsMap.find(match.GetRegex()) != subDetectsMap.end()) {
134         RulesEngine subRulesEngine = subDetectsMap[match.GetRegex()];
135         icu::UnicodeString subMessage = message.tempSubString(match.GetBegin(), match.GetEnd() - match.GetBegin());
136         std::vector<MatchedDateTimeInfo> subMatches = subRulesEngine.Match(subMessage);
137         for (auto& subMatch : subMatches) {
138             subMatch.SetBegin(subMatch.GetBegin() + match.GetBegin());
139             subMatch.SetEnd(subMatch.GetEnd() + match.GetBegin());
140         }
141         matches.insert(matches.end(), subMatches.begin(), subMatches.end());
142     } else {
143         matches.push_back(match);
144     }
145 }
146 } // namespace I18n
147 } // namespace Global
148 } // namespace OHOS