1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci 16020a203aSopenharmony_ci#include "event_json_parser.h" 17020a203aSopenharmony_ci 18020a203aSopenharmony_ci#include <cctype> 19020a203aSopenharmony_ci#include <cinttypes> 20020a203aSopenharmony_ci#include <fstream> 21020a203aSopenharmony_ci#include <map> 22020a203aSopenharmony_ci 23020a203aSopenharmony_ci#include "hiview_logger.h" 24020a203aSopenharmony_ci 25020a203aSopenharmony_cinamespace OHOS { 26020a203aSopenharmony_cinamespace HiviewDFX { 27020a203aSopenharmony_cinamespace { 28020a203aSopenharmony_ciDEFINE_LOG_TAG("Event-JsonParser"); 29020a203aSopenharmony_ci 30020a203aSopenharmony_ciconstexpr char BASE[] = "__BASE"; 31020a203aSopenharmony_ciconstexpr char LEVEL[] = "level"; 32020a203aSopenharmony_ciconstexpr char TAG[] = "tag"; 33020a203aSopenharmony_ciconstexpr char TYPE[] = "type"; 34020a203aSopenharmony_ciconstexpr char PRIVACY[] = "privacy"; 35020a203aSopenharmony_ciconstexpr char PRESERVE[] = "preserve"; 36020a203aSopenharmony_ciconst std::map<std::string, uint8_t> EVENT_TYPE_MAP = { 37020a203aSopenharmony_ci {"FAULT", 1}, {"STATISTIC", 2}, {"SECURITY", 3}, {"BEHAVIOR", 4} 38020a203aSopenharmony_ci}; 39020a203aSopenharmony_ci 40020a203aSopenharmony_cibool ReadSysEventDefFromFile(const std::string& path, Json::Value& hiSysEventDef) 41020a203aSopenharmony_ci{ 42020a203aSopenharmony_ci std::ifstream fin(path, std::ifstream::binary); 43020a203aSopenharmony_ci if (!fin.is_open()) { 44020a203aSopenharmony_ci HIVIEW_LOGW("failed to open file, path: %{public}s.", path.c_str()); 45020a203aSopenharmony_ci return false; 46020a203aSopenharmony_ci } 47020a203aSopenharmony_ci Json::CharReaderBuilder jsonRBuilder; 48020a203aSopenharmony_ci Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_); 49020a203aSopenharmony_ci JSONCPP_STRING errs; 50020a203aSopenharmony_ci return parseFromStream(jsonRBuilder, fin, &hiSysEventDef, &errs); 51020a203aSopenharmony_ci} 52020a203aSopenharmony_ci} 53020a203aSopenharmony_ci 54020a203aSopenharmony_ciEventJsonParser::EventJsonParser(const std::string& defFilePath) 55020a203aSopenharmony_ci{ 56020a203aSopenharmony_ci // read json file 57020a203aSopenharmony_ci ReadDefFile(defFilePath); 58020a203aSopenharmony_ci} 59020a203aSopenharmony_ci 60020a203aSopenharmony_cistd::string EventJsonParser::GetTagByDomainAndName(const std::string& domain, const std::string& name) const 61020a203aSopenharmony_ci{ 62020a203aSopenharmony_ci return GetDefinedBaseInfoByDomainName(domain, name).tag; 63020a203aSopenharmony_ci} 64020a203aSopenharmony_ci 65020a203aSopenharmony_ciint EventJsonParser::GetTypeByDomainAndName(const std::string& domain, const std::string& name) const 66020a203aSopenharmony_ci{ 67020a203aSopenharmony_ci return GetDefinedBaseInfoByDomainName(domain, name).type; 68020a203aSopenharmony_ci} 69020a203aSopenharmony_ci 70020a203aSopenharmony_cibool EventJsonParser::GetPreserveByDomainAndName(const std::string& domain, const std::string& name) const 71020a203aSopenharmony_ci{ 72020a203aSopenharmony_ci return GetDefinedBaseInfoByDomainName(domain, name).preserve; 73020a203aSopenharmony_ci} 74020a203aSopenharmony_ci 75020a203aSopenharmony_ciBaseInfo EventJsonParser::GetDefinedBaseInfoByDomainName(const std::string& domain, 76020a203aSopenharmony_ci const std::string& name) const 77020a203aSopenharmony_ci{ 78020a203aSopenharmony_ci if (hiSysEventDefMap_ == nullptr) { 79020a203aSopenharmony_ci HIVIEW_LOGD("sys def map is null"); 80020a203aSopenharmony_ci return BaseInfo(); 81020a203aSopenharmony_ci } 82020a203aSopenharmony_ci auto domainIter = hiSysEventDefMap_->find(domain); 83020a203aSopenharmony_ci if (domainIter == hiSysEventDefMap_->end()) { 84020a203aSopenharmony_ci HIVIEW_LOGD("domain %{public}s is not defined.", domain.c_str()); 85020a203aSopenharmony_ci return BaseInfo(); 86020a203aSopenharmony_ci } 87020a203aSopenharmony_ci auto domainNames = hiSysEventDefMap_->at(domain); 88020a203aSopenharmony_ci auto nameIter = domainNames.find(name); 89020a203aSopenharmony_ci if (nameIter == domainNames.end()) { 90020a203aSopenharmony_ci HIVIEW_LOGD("%{public}s is not defined in domain %{public}s.", name.c_str(), domain.c_str()); 91020a203aSopenharmony_ci return BaseInfo(); 92020a203aSopenharmony_ci } 93020a203aSopenharmony_ci return nameIter->second; 94020a203aSopenharmony_ci} 95020a203aSopenharmony_ci 96020a203aSopenharmony_cibool EventJsonParser::HasIntMember(const Json::Value& jsonObj, const std::string& name) const 97020a203aSopenharmony_ci{ 98020a203aSopenharmony_ci return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isInt(); 99020a203aSopenharmony_ci} 100020a203aSopenharmony_ci 101020a203aSopenharmony_cibool EventJsonParser::HasStringMember(const Json::Value& jsonObj, const std::string& name) const 102020a203aSopenharmony_ci{ 103020a203aSopenharmony_ci return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isString(); 104020a203aSopenharmony_ci} 105020a203aSopenharmony_ci 106020a203aSopenharmony_cibool EventJsonParser::HasBoolMember(const Json::Value& jsonObj, const std::string& name) const 107020a203aSopenharmony_ci{ 108020a203aSopenharmony_ci return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isBool(); 109020a203aSopenharmony_ci} 110020a203aSopenharmony_ci 111020a203aSopenharmony_civoid EventJsonParser::InitEventInfoMapRef(const Json::Value& eventJson, JSON_VALUE_LOOP_HANDLER handler) const 112020a203aSopenharmony_ci{ 113020a203aSopenharmony_ci if (!eventJson.isObject()) { 114020a203aSopenharmony_ci return; 115020a203aSopenharmony_ci } 116020a203aSopenharmony_ci auto attrList = eventJson.getMemberNames(); 117020a203aSopenharmony_ci for (auto it = attrList.cbegin(); it != attrList.cend(); it++) { 118020a203aSopenharmony_ci std::string key = *it; 119020a203aSopenharmony_ci if (key.empty()) { 120020a203aSopenharmony_ci continue; 121020a203aSopenharmony_ci } 122020a203aSopenharmony_ci if (handler != nullptr) { 123020a203aSopenharmony_ci handler(key, eventJson[key]); 124020a203aSopenharmony_ci } 125020a203aSopenharmony_ci } 126020a203aSopenharmony_ci} 127020a203aSopenharmony_ci 128020a203aSopenharmony_ciBaseInfo EventJsonParser::ParseBaseConfig(const Json::Value& eventNameJson) const 129020a203aSopenharmony_ci{ 130020a203aSopenharmony_ci BaseInfo baseInfo; 131020a203aSopenharmony_ci if (!eventNameJson.isObject() || !eventNameJson[BASE].isObject()) { 132020a203aSopenharmony_ci HIVIEW_LOGD("__BASE definition is invalid."); 133020a203aSopenharmony_ci return baseInfo; 134020a203aSopenharmony_ci } 135020a203aSopenharmony_ci 136020a203aSopenharmony_ci Json::Value baseJsonInfo = eventNameJson[BASE]; 137020a203aSopenharmony_ci if (!baseJsonInfo.isObject() || !HasStringMember(baseJsonInfo, TYPE)) { 138020a203aSopenharmony_ci HIVIEW_LOGD("type is not defined in __BASE."); 139020a203aSopenharmony_ci return baseInfo; 140020a203aSopenharmony_ci } 141020a203aSopenharmony_ci std::string typeDes = baseJsonInfo[TYPE].asString(); 142020a203aSopenharmony_ci if (EVENT_TYPE_MAP.find(typeDes) == EVENT_TYPE_MAP.end()) { 143020a203aSopenharmony_ci HIVIEW_LOGD("type is defined as %{public}s, but a valid type must be FAULT, STATISTIC, SECURITY, or BEHAVIOR", 144020a203aSopenharmony_ci typeDes.c_str()); 145020a203aSopenharmony_ci return baseInfo; 146020a203aSopenharmony_ci } 147020a203aSopenharmony_ci baseInfo.type = EVENT_TYPE_MAP.at(typeDes); 148020a203aSopenharmony_ci 149020a203aSopenharmony_ci if (!HasStringMember(baseJsonInfo, LEVEL)) { 150020a203aSopenharmony_ci HIVIEW_LOGD("level is not defined in __BASE."); 151020a203aSopenharmony_ci return baseInfo; 152020a203aSopenharmony_ci } 153020a203aSopenharmony_ci baseInfo.level = baseJsonInfo[LEVEL].asString(); 154020a203aSopenharmony_ci 155020a203aSopenharmony_ci if (HasStringMember(baseJsonInfo, TAG)) { 156020a203aSopenharmony_ci baseInfo.tag = baseJsonInfo[TAG].asString(); 157020a203aSopenharmony_ci } 158020a203aSopenharmony_ci 159020a203aSopenharmony_ci if (HasIntMember(baseJsonInfo, PRIVACY)) { 160020a203aSopenharmony_ci int privacy = baseJsonInfo[PRIVACY].asInt(); 161020a203aSopenharmony_ci baseInfo.privacy = privacy > 0 ? static_cast<uint8_t>(privacy) : baseInfo.privacy; 162020a203aSopenharmony_ci } 163020a203aSopenharmony_ci 164020a203aSopenharmony_ci if (HasBoolMember(baseJsonInfo, PRESERVE)) { 165020a203aSopenharmony_ci baseInfo.preserve = baseJsonInfo[PRESERVE].asBool(); 166020a203aSopenharmony_ci } 167020a203aSopenharmony_ci 168020a203aSopenharmony_ci return baseInfo; 169020a203aSopenharmony_ci} 170020a203aSopenharmony_ci 171020a203aSopenharmony_civoid EventJsonParser::ParseHiSysEventDef(const Json::Value& hiSysEventDef, std::shared_ptr<DOMAIN_INFO_MAP> sysDefMap) 172020a203aSopenharmony_ci{ 173020a203aSopenharmony_ci InitEventInfoMapRef(hiSysEventDef, [this, sysDefMap] (const std::string& key, const Json::Value& value) { 174020a203aSopenharmony_ci sysDefMap->insert(std::make_pair(key, this->ParseNameConfig(value))); 175020a203aSopenharmony_ci }); 176020a203aSopenharmony_ci} 177020a203aSopenharmony_ci 178020a203aSopenharmony_ciNAME_INFO_MAP EventJsonParser::ParseNameConfig(const Json::Value& domainJson) const 179020a203aSopenharmony_ci{ 180020a203aSopenharmony_ci NAME_INFO_MAP allNames; 181020a203aSopenharmony_ci if (!domainJson.isObject()) { 182020a203aSopenharmony_ci return allNames; 183020a203aSopenharmony_ci } 184020a203aSopenharmony_ci InitEventInfoMapRef(domainJson, [this, &allNames] (const std::string& key, const Json::Value& value) { 185020a203aSopenharmony_ci allNames[key] = ParseBaseConfig(value); 186020a203aSopenharmony_ci }); 187020a203aSopenharmony_ci return allNames; 188020a203aSopenharmony_ci} 189020a203aSopenharmony_ci 190020a203aSopenharmony_civoid EventJsonParser::ReadDefFile(const std::string& defFilePath) 191020a203aSopenharmony_ci{ 192020a203aSopenharmony_ci Json::Value hiSysEventDef; 193020a203aSopenharmony_ci if (!ReadSysEventDefFromFile(defFilePath, hiSysEventDef)) { 194020a203aSopenharmony_ci HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s", defFilePath.c_str()); 195020a203aSopenharmony_ci return; 196020a203aSopenharmony_ci } 197020a203aSopenharmony_ci auto tmpMap = std::make_shared<DOMAIN_INFO_MAP>(); 198020a203aSopenharmony_ci ParseHiSysEventDef(hiSysEventDef, tmpMap); 199020a203aSopenharmony_ci hiSysEventDefMap_ = tmpMap; 200020a203aSopenharmony_ci} 201020a203aSopenharmony_ci} // namespace HiviewDFX 202020a203aSopenharmony_ci} // namespace OHOS 203