114cf0368Sopenharmony_ci/* 214cf0368Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License. 514cf0368Sopenharmony_ci * You may obtain a copy of the License at 614cf0368Sopenharmony_ci * 714cf0368Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 814cf0368Sopenharmony_ci * 914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and 1314cf0368Sopenharmony_ci * limitations under the License. 1414cf0368Sopenharmony_ci */ 1514cf0368Sopenharmony_ci#define LOG_TAG "UtdCfgsChecker" 1614cf0368Sopenharmony_ci#include "utd_cfgs_checker.h" 1714cf0368Sopenharmony_ci 1814cf0368Sopenharmony_ci#include <regex> 1914cf0368Sopenharmony_ci#include "utd_graph.h" 2014cf0368Sopenharmony_ci#include "logger.h" 2114cf0368Sopenharmony_ci 2214cf0368Sopenharmony_cinamespace OHOS { 2314cf0368Sopenharmony_cinamespace UDMF { 2414cf0368Sopenharmony_ciconstexpr const char *TYPE_ID_REGEX = "[a-zA-Z0-9/.-]+$"; 2514cf0368Sopenharmony_ciconstexpr const char FILE_EXTENSION_PREFIX = '.'; 2614cf0368Sopenharmony_ciconstexpr const int32_t MAX_UTD_SIZE = 50; 2714cf0368Sopenharmony_ci 2814cf0368Sopenharmony_ciUtdCfgsChecker::UtdCfgsChecker() 2914cf0368Sopenharmony_ci{ 3014cf0368Sopenharmony_ci} 3114cf0368Sopenharmony_ci 3214cf0368Sopenharmony_ciUtdCfgsChecker::~UtdCfgsChecker() 3314cf0368Sopenharmony_ci{ 3414cf0368Sopenharmony_ci} 3514cf0368Sopenharmony_ci 3614cf0368Sopenharmony_ciUtdCfgsChecker &UtdCfgsChecker::GetInstance() 3714cf0368Sopenharmony_ci{ 3814cf0368Sopenharmony_ci static auto instance = new UtdCfgsChecker(); 3914cf0368Sopenharmony_ci return *instance; 4014cf0368Sopenharmony_ci} 4114cf0368Sopenharmony_ci 4214cf0368Sopenharmony_cibool UtdCfgsChecker::CheckTypeDescriptors(CustomUtdCfgs &typeCfgs, const std::vector<TypeDescriptorCfg> &presetCfgs, 4314cf0368Sopenharmony_ci const std::vector<TypeDescriptorCfg> &customCfgs, const std::string &bundleName) 4414cf0368Sopenharmony_ci{ 4514cf0368Sopenharmony_ci if (!CheckTypesFormat(typeCfgs, bundleName)) { 4614cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "CheckTypesFormat not pass, bundleName: %{public}s.", bundleName.c_str()); 4714cf0368Sopenharmony_ci return false; 4814cf0368Sopenharmony_ci } 4914cf0368Sopenharmony_ci if (!CheckTypesRelation(typeCfgs, presetCfgs, customCfgs)) { 5014cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "CheckTypesRelation not pass, bundleName: %{public}s.", bundleName.c_str()); 5114cf0368Sopenharmony_ci return false; 5214cf0368Sopenharmony_ci } 5314cf0368Sopenharmony_ci return true; 5414cf0368Sopenharmony_ci} 5514cf0368Sopenharmony_ci 5614cf0368Sopenharmony_cibool UtdCfgsChecker::CheckTypesFormat(CustomUtdCfgs &typeCfgs, const std::string &bundleName) 5714cf0368Sopenharmony_ci{ 5814cf0368Sopenharmony_ci for (auto declarationType: typeCfgs.first) { 5914cf0368Sopenharmony_ci if (!std::regex_match(declarationType.typeId, std::regex(bundleName + TYPE_ID_REGEX))) { 6014cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Declaration typeId check failed, id: %{public}s, bundleName: %{public}s.", 6114cf0368Sopenharmony_ci declarationType.typeId.c_str(), bundleName.c_str()); 6214cf0368Sopenharmony_ci return false; 6314cf0368Sopenharmony_ci } 6414cf0368Sopenharmony_ci } 6514cf0368Sopenharmony_ci for (auto referenceTypes: typeCfgs.second) { 6614cf0368Sopenharmony_ci if (!std::regex_match(referenceTypes.typeId, std::regex(TYPE_ID_REGEX))) { 6714cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Reference typeId check failed, id: %{public}s, bundleName: %{public}s.", 6814cf0368Sopenharmony_ci referenceTypes.typeId.c_str(), bundleName.c_str()); 6914cf0368Sopenharmony_ci return false; 7014cf0368Sopenharmony_ci } 7114cf0368Sopenharmony_ci } 7214cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> inputTypeCfgs; 7314cf0368Sopenharmony_ci if (!typeCfgs.first.empty()) { 7414cf0368Sopenharmony_ci inputTypeCfgs.insert(inputTypeCfgs.end(), typeCfgs.first.begin(), typeCfgs.first.end()); 7514cf0368Sopenharmony_ci } 7614cf0368Sopenharmony_ci if (!typeCfgs.second.empty()) { 7714cf0368Sopenharmony_ci inputTypeCfgs.insert(inputTypeCfgs.end(), typeCfgs.second.begin(), typeCfgs.second.end()); 7814cf0368Sopenharmony_ci } 7914cf0368Sopenharmony_ci for (TypeDescriptorCfg &typeCfg : inputTypeCfgs) { 8014cf0368Sopenharmony_ci for (std::string filenames : typeCfg.filenameExtensions) { 8114cf0368Sopenharmony_ci if (filenames.size() <= 1 || filenames[0] != FILE_EXTENSION_PREFIX) { 8214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Extension not valid, extension: %{public}s, bundleName: %{public}s.", 8314cf0368Sopenharmony_ci filenames.c_str(), bundleName.c_str()); 8414cf0368Sopenharmony_ci return false; 8514cf0368Sopenharmony_ci } 8614cf0368Sopenharmony_ci } 8714cf0368Sopenharmony_ci if (typeCfg.belongingToTypes.empty()) { 8814cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "BelongingToTypes can not be empty, bundleName: %{public}s.", bundleName.c_str()); 8914cf0368Sopenharmony_ci return false; 9014cf0368Sopenharmony_ci } 9114cf0368Sopenharmony_ci for (std::string mimeType : typeCfg.mimeTypes) { 9214cf0368Sopenharmony_ci if (mimeType.empty()) { 9314cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "mimeType can not be an empty string, typeId: %{public}s.", 9414cf0368Sopenharmony_ci typeCfg.typeId.c_str()); 9514cf0368Sopenharmony_ci return false; 9614cf0368Sopenharmony_ci } 9714cf0368Sopenharmony_ci } 9814cf0368Sopenharmony_ci } 9914cf0368Sopenharmony_ci return true; 10014cf0368Sopenharmony_ci} 10114cf0368Sopenharmony_ci 10214cf0368Sopenharmony_cibool UtdCfgsChecker::CheckTypesRelation(CustomUtdCfgs &typeCfgs, const std::vector<TypeDescriptorCfg> &presetCfgs, 10314cf0368Sopenharmony_ci const std::vector<TypeDescriptorCfg> &customCfgs) 10414cf0368Sopenharmony_ci{ 10514cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> inputTypeCfgs; 10614cf0368Sopenharmony_ci if (!typeCfgs.first.empty()) { 10714cf0368Sopenharmony_ci inputTypeCfgs.insert(inputTypeCfgs.end(), typeCfgs.first.begin(), typeCfgs.first.end()); 10814cf0368Sopenharmony_ci } 10914cf0368Sopenharmony_ci if (!typeCfgs.second.empty()) { 11014cf0368Sopenharmony_ci inputTypeCfgs.insert(inputTypeCfgs.end(), typeCfgs.second.begin(), typeCfgs.second.end()); 11114cf0368Sopenharmony_ci } 11214cf0368Sopenharmony_ci std::vector<std::string> typeIds; 11314cf0368Sopenharmony_ci for (auto &inputTypeCfg: inputTypeCfgs) { 11414cf0368Sopenharmony_ci typeIds.push_back(inputTypeCfg.typeId); 11514cf0368Sopenharmony_ci } 11614cf0368Sopenharmony_ci if (typeIds.size() > MAX_UTD_SIZE) { 11714cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Create more UTDs than limit."); 11814cf0368Sopenharmony_ci return false; 11914cf0368Sopenharmony_ci } 12014cf0368Sopenharmony_ci for (auto &presetCfg: presetCfgs) { 12114cf0368Sopenharmony_ci typeIds.push_back(presetCfg.typeId); 12214cf0368Sopenharmony_ci } 12314cf0368Sopenharmony_ci if (std::set<std::string>(typeIds.begin(), typeIds.end()).size() != typeIds.size()) { 12414cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Find duplicated typeIds."); 12514cf0368Sopenharmony_ci return false; 12614cf0368Sopenharmony_ci } 12714cf0368Sopenharmony_ci if (!CheckBelongingToTypes(inputTypeCfgs, presetCfgs)) { 12814cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "BelongingToType check failed."); 12914cf0368Sopenharmony_ci return false; 13014cf0368Sopenharmony_ci } 13114cf0368Sopenharmony_ci if (!CanConstructDAG(typeCfgs, presetCfgs, customCfgs)) { 13214cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Can not construct DAG."); 13314cf0368Sopenharmony_ci return false; 13414cf0368Sopenharmony_ci } 13514cf0368Sopenharmony_ci return true; 13614cf0368Sopenharmony_ci} 13714cf0368Sopenharmony_ci 13814cf0368Sopenharmony_cibool UtdCfgsChecker::CheckBelongingToTypes(const std::vector<TypeDescriptorCfg> &typeCfgs, 13914cf0368Sopenharmony_ci const std::vector<TypeDescriptorCfg> &presetCfgs) 14014cf0368Sopenharmony_ci{ 14114cf0368Sopenharmony_ci std::vector<std::string> typeIds; 14214cf0368Sopenharmony_ci for (auto &typeCfg: typeCfgs) { 14314cf0368Sopenharmony_ci typeIds.push_back(typeCfg.typeId); 14414cf0368Sopenharmony_ci } 14514cf0368Sopenharmony_ci for (auto &presetCfg: presetCfgs) { 14614cf0368Sopenharmony_ci typeIds.push_back(presetCfg.typeId); 14714cf0368Sopenharmony_ci } 14814cf0368Sopenharmony_ci for (auto &inputCfg : typeCfgs) { 14914cf0368Sopenharmony_ci for (std::string belongingToType : inputCfg.belongingToTypes) { 15014cf0368Sopenharmony_ci if (belongingToType.empty()) { 15114cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "BelongingToType can not be an empty string, typeId: %{public}s.", 15214cf0368Sopenharmony_ci inputCfg.typeId.c_str()); 15314cf0368Sopenharmony_ci return false; 15414cf0368Sopenharmony_ci } 15514cf0368Sopenharmony_ci if (inputCfg.typeId == belongingToType) { 15614cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "TypeId cannot equals belongingToType, typeId: %{public}s.", 15714cf0368Sopenharmony_ci inputCfg.typeId.c_str()); 15814cf0368Sopenharmony_ci return false; 15914cf0368Sopenharmony_ci } 16014cf0368Sopenharmony_ci if (find(typeIds.begin(), typeIds.end(), belongingToType) == typeIds.end()) { 16114cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "BelongingToType can not find in typeids, belongingToType: %{public}s.", 16214cf0368Sopenharmony_ci belongingToType.c_str()); 16314cf0368Sopenharmony_ci return false; 16414cf0368Sopenharmony_ci } 16514cf0368Sopenharmony_ci } 16614cf0368Sopenharmony_ci } 16714cf0368Sopenharmony_ci return true; 16814cf0368Sopenharmony_ci} 16914cf0368Sopenharmony_ci 17014cf0368Sopenharmony_cibool UtdCfgsChecker::CanConstructDAG(CustomUtdCfgs &typeCfgs, const std::vector<TypeDescriptorCfg> &presetCfgs, 17114cf0368Sopenharmony_ci const std::vector<TypeDescriptorCfg> &customCfgs) 17214cf0368Sopenharmony_ci{ 17314cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> allTypeCfgs; 17414cf0368Sopenharmony_ci if (!customCfgs.empty()) { 17514cf0368Sopenharmony_ci allTypeCfgs.insert(allTypeCfgs.end(), customCfgs.begin(), customCfgs.end()); 17614cf0368Sopenharmony_ci } 17714cf0368Sopenharmony_ci for (TypeDescriptorCfg &declarationType : typeCfgs.first) { 17814cf0368Sopenharmony_ci for (auto iter = allTypeCfgs.begin(); iter != allTypeCfgs.end();) { 17914cf0368Sopenharmony_ci if (iter->typeId == declarationType.typeId) { 18014cf0368Sopenharmony_ci iter = allTypeCfgs.erase(iter); 18114cf0368Sopenharmony_ci } else { 18214cf0368Sopenharmony_ci iter ++; 18314cf0368Sopenharmony_ci } 18414cf0368Sopenharmony_ci } 18514cf0368Sopenharmony_ci allTypeCfgs.push_back(declarationType); 18614cf0368Sopenharmony_ci } 18714cf0368Sopenharmony_ci for (TypeDescriptorCfg &referenceTypes : typeCfgs.second) { 18814cf0368Sopenharmony_ci bool found = false; 18914cf0368Sopenharmony_ci for (auto &typeCfg : allTypeCfgs) { 19014cf0368Sopenharmony_ci if (typeCfg.typeId == referenceTypes.typeId) { 19114cf0368Sopenharmony_ci found = true; 19214cf0368Sopenharmony_ci break; 19314cf0368Sopenharmony_ci } 19414cf0368Sopenharmony_ci } 19514cf0368Sopenharmony_ci if (!found) { 19614cf0368Sopenharmony_ci allTypeCfgs.push_back(referenceTypes); 19714cf0368Sopenharmony_ci } 19814cf0368Sopenharmony_ci } 19914cf0368Sopenharmony_ci if (!presetCfgs.empty()) { 20014cf0368Sopenharmony_ci allTypeCfgs.insert(allTypeCfgs.end(), presetCfgs.begin(), presetCfgs.end()); 20114cf0368Sopenharmony_ci } 20214cf0368Sopenharmony_ci if (!allTypeCfgs.empty()) { 20314cf0368Sopenharmony_ci auto graph = UtdGraph::GetInstance().ConstructNewGraph(allTypeCfgs); 20414cf0368Sopenharmony_ci if (graph->IsDAG()) { 20514cf0368Sopenharmony_ci return true; 20614cf0368Sopenharmony_ci } 20714cf0368Sopenharmony_ci } 20814cf0368Sopenharmony_ci return false; 20914cf0368Sopenharmony_ci} 21014cf0368Sopenharmony_ci} // namespace UDMF 21114cf0368Sopenharmony_ci} // namespace OHOS 212