• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "increment_manager.h"
17 #include<algorithm>
18 #include<iostream>
19 #include "file_entry.h"
20 #include "id_worker.h"
21 #include "key_parser.h"
22 #include "module_combine.h"
23 #include "resource_module_inc.h"
24 #include "restool_errors.h"
25 #include "xml_key_node.h"
26 
27 namespace OHOS {
28 namespace Global {
29 namespace Restool {
30 using namespace std;
31 const string IncrementManager::ID_JSON_FILE = "ids.json";
~IncrementManager()32 IncrementManager::~IncrementManager()
33 {
34 }
35 
Init(const string & cachePath,const vector<std::string> & folder,const string & outputPath,const string & moduleName)36 uint32_t IncrementManager::Init(const string &cachePath, const vector<std::string> &folder,
37     const string &outputPath, const string &moduleName)
38 {
39     cachePath_ = cachePath;
40     folder_ = folder;
41     outputPath_ = outputPath;
42     moduleName_ = moduleName;
43 
44     if (!InitIdJson()) {
45         return RESTOOL_ERROR;
46     }
47 
48     if (!ClearSolidXml()) {
49         return RESTOOL_ERROR;
50     }
51 
52     vector<IncrementList::FileIncrement> dels;
53     if (!InitList(dels)) {
54         return RESTOOL_ERROR;
55     }
56 
57     DeleteRawFile(dels);
58     if (!ScanModules(dels)) {
59         return RESTOOL_ERROR;
60     }
61     enalbe_= true;
62     return RESTOOL_SUCCESS;
63 }
64 
65 // below private
InitIdJson()66 bool IncrementManager::InitIdJson()
67 {
68     string idJsonPath = FileEntry::FilePath(cachePath_).Append(ID_JSON_FILE).GetPath();
69     if (!ResourceUtil::FileExist(idJsonPath)) {
70         return true;
71     }
72     if (!LoadIdJson()) {
73         return false;
74     }
75     firstIncrement_ = false;
76     return true;
77 }
78 
ScanModules(const vector<IncrementList::FileIncrement> & dels)79 bool IncrementManager::ScanModules(const vector<IncrementList::FileIncrement> &dels)
80 {
81     vector<ModuleInfo> moduleInfos;
82     for (const auto &folder : folder_) {
83         ModuleInfo moduleInfo;
84         moduleInfo.rootPath = folder;
85         for_each(dels.begin(), dels.end(), [&moduleInfo](const auto &iter) {
86             if (moduleInfo.rootPath != iter.rootPath) {
87                 return;
88             }
89             moduleInfo.fileIncrements.push_back(iter);
90         });
91         moduleInfos.push_back(moduleInfo);
92     }
93 
94     for (auto &iter : moduleInfos) {
95         string pathHash = ResourceUtil::GenerateHash(iter.rootPath);
96         string moduleCachePath = FileEntry::FilePath(cachePath_).Append(pathHash).GetPath();
97         ResourceModuleInc resourceModuleInc(iter.rootPath, moduleCachePath, moduleName_, folder_);
98         if (FirstIncrement()) {
99             if (resourceModuleInc.ResourceModule::ScanResource() != RESTOOL_SUCCESS) {
100                 return false;
101             }
102         } else {
103             if (resourceModuleInc.ScanResource(iter.fileIncrements) != RESTOOL_SUCCESS) {
104                 return false;
105             }
106         }
107 
108         PushScanDir(resourceModuleInc.GetScanDirectorys());
109         if (ResourceModule::MergeResourceItem(items_, resourceModuleInc.GetOwner()) != RESTOOL_SUCCESS) {
110             return false;
111         }
112         if (resourceModuleInc.SaveIndex() != RESTOOL_SUCCESS) {
113             return false;
114         }
115 
116         ModuleCombine moduleCombine(moduleCachePath, outputPath_);
117         if (!moduleCombine.Combine()) {
118             return false;
119         }
120     }
121     FlushId();
122     SaveIdJson();
123     return true;
124 }
125 
InitList(vector<IncrementList::FileIncrement> & dels) const126 bool IncrementManager::InitList(vector<IncrementList::FileIncrement> &dels) const
127 {
128     string listPath = FileEntry::FilePath(cachePath_).Append(IncrementList::RESTOOL_LIST_FILE).GetPath();
129     if (!ResourceUtil::FileExist(listPath)) {
130         return true;
131     }
132 
133     IncrementList incrementList(listPath, folder_);
134     if (!incrementList.Parse(dels)) {
135         return false;
136     }
137     return true;
138 }
139 
FlushId()140 void IncrementManager::FlushId()
141 {
142     for_each(items_.begin(), items_.end(), [](const auto &iter) {
143         auto &idWorker = IdWorker::GetInstance();
144         ResType resType = iter.second.begin()->GetResType();
145         string name = ResourceUtil::GetIdName(iter.second.begin()->GetName(), resType);
146         idWorker.GenerateId(resType, name);
147     });
148 }
149 
SaveIdJson() const150 bool IncrementManager::SaveIdJson() const
151 {
152     Json::Value root;
153     for (const auto &iter : items_) {
154         Json::Value node;
155         ResType resType = iter.second.begin()->GetResType();
156         node["name"] = ResourceUtil::GetIdName(iter.second.begin()->GetName(), resType);
157         node["type"] = ResourceUtil::ResTypeToString(resType);
158         root[to_string(iter.first)] = node;
159     }
160 
161     string idJsonPath = FileEntry::FilePath(cachePath_).Append(ID_JSON_FILE).GetPath();
162     if (!ResourceUtil::SaveToJsonFile(idJsonPath, root)) {
163         return false;
164     }
165     return true;
166 }
167 
LoadIdJson()168 bool IncrementManager::LoadIdJson()
169 {
170     Json::Value root;
171     string idJsonPath = FileEntry::FilePath(cachePath_).Append(ID_JSON_FILE).GetPath();
172     if (!ResourceUtil::OpenJsonFile(idJsonPath, root)) {
173         return false;
174     }
175 
176     if (!root.isObject()) {
177         cerr << "Error: invalid, not object." << NEW_LINE_PATH << idJsonPath << endl;
178         return false;
179     }
180 
181     auto &idWorker = IdWorker::GetInstance();
182     for (const auto &member : root.getMemberNames()) {
183         int32_t id = strtol(member.c_str(), nullptr, 10);
184         if (id < 0) {
185             cerr << "Error: invalid '" << member << "'." << NEW_LINE_PATH << idJsonPath  << endl;
186             return false;
187         }
188 
189         const auto &node = root[member];
190         if (!node.isObject()) {
191             cerr << "Error: '" << member << "' not object." << NEW_LINE_PATH << idJsonPath  << endl;
192             return false;
193         }
194         if (!node["name"].isString()) {
195             cerr << "Error: '" << member << "' name not string." << NEW_LINE_PATH << idJsonPath << endl;
196             return false;
197         }
198         string name = node["name"].asString();
199 
200         if (!node["type"].isString()) {
201             cerr << "Error: '" << member << "' type not string." << NEW_LINE_PATH << idJsonPath << endl;
202             return false;
203         }
204         ResType resType = ResourceUtil::GetResTypeFromString(node["type"].asString());
205         if (resType == ResType::INVALID_RES_TYPE) {
206             cerr << "Error: '" << member << "' '" << node["type"] << "' invalid.";
207             cerr << NEW_LINE_PATH << idJsonPath << endl;
208             return false;
209         }
210         if (!idWorker.PushCache(resType, name, id)) {
211             return false;
212         }
213     }
214     return true;
215 }
216 
PushScanDir(const map<ResType,vector<DirectoryInfo>> & scanDirs)217 void IncrementManager::PushScanDir(const map<ResType, vector<DirectoryInfo>> &scanDirs)
218 {
219     for (const auto &iter : scanDirs) {
220         for (const auto &directoryInfo : iter.second) {
221             scanDirs_[iter.first].push_back(directoryInfo);
222         }
223     }
224 }
225 
DeleteRawFile(vector<IncrementList::FileIncrement> & dels) const226 void IncrementManager::DeleteRawFile(vector<IncrementList::FileIncrement> &dels) const
227 {
228     for (auto it = dels.begin(); it != dels.end();) {
229         if (it->dirType != ResType::INVALID_RES_TYPE) {
230             it++;
231             continue;
232         }
233         string rawFilePath = FileEntry::FilePath(outputPath_).Append(it->relativePath).GetPath();
234         if (remove(rawFilePath.c_str()) != 0) {
235             cout << "Warning: remove fail '" << rawFilePath << "'" << endl;
236         }
237         it = dels.erase(it);
238     }
239 }
240 
ClearSolidXml() const241 bool IncrementManager::ClearSolidXml() const
242 {
243     string resourceDir = FileEntry::FilePath(outputPath_).Append(RESOURCES_DIR).GetPath();
244     if (!ResourceUtil::FileExist(resourceDir)) {
245         return true;
246     }
247 
248     ResourceDirectory resourceDirectory;
249     if (!resourceDirectory.ScanResources(resourceDir, [](const DirectoryInfo &info) {
250         if (!ResourceUtil::NeedConverToSolidXml(info.dirType)) {
251             return true;
252         }
253 
254         FileEntry f(info.dirPath);
255         if (!f.Init()) {
256             return false;
257         }
258 
259         for (const auto &entry : f.GetChilds()) {
260             if (!entry->IsFile()) {
261                 cerr << "Error: '" << entry->GetFilePath().GetPath() << "' is directroy." << endl;
262                 return false;
263             }
264 
265             string extension = entry->GetFilePath().GetExtension();
266             if (extension != ".sxml" && extension != ".key" && extension != ".json") {
267                 continue;
268             }
269 
270             if (remove(entry->GetFilePath().GetPath().c_str()) != 0) {
271                 cerr << "Error: remove failed '" << entry->GetFilePath().GetPath();
272                 cerr << "', reason: " << strerror(errno) << endl;
273                 return false;
274             }
275         }
276         return true;
277     })) {
278         return false;
279     }
280     return true;
281 }
282 }
283 }
284 }
285