• 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 "i_resource_compiler.h"
17 #include <algorithm>
18 #include <iostream>
19 #include "file_entry.h"
20 #include "id_worker.h"
21 #include "resource_util.h"
22 #include "restool_errors.h"
23 #include "sqlite_database.h"
24 #include "xml_converter.h"
25 
26 namespace OHOS {
27 namespace Global {
28 namespace Restool {
29 using namespace std;
IResourceCompiler(ResType type,const string & output)30 IResourceCompiler::IResourceCompiler(ResType type, const string &output)
31     :type_(type), output_(output)
32 {
33 }
34 
~IResourceCompiler()35 IResourceCompiler::~IResourceCompiler()
36 {
37     nameInfos_.clear();
38     resourceInfos_.clear();
39 }
40 
Compile(const vector<DirectoryInfo> & directoryInfos)41 uint32_t IResourceCompiler::Compile(const vector<DirectoryInfo> &directoryInfos)
42 {
43     vector<FileInfo> fileInfos;
44     map<string, vector<FileInfo>> setsByDirectory;
45     for (const auto &directoryInfo : directoryInfos) {
46         string outputFolder = GetOutputFolder(directoryInfo);
47         FileEntry f(directoryInfo.dirPath);
48         if (!f.Init()) {
49             return RESTOOL_ERROR;
50         }
51         for (const auto &it : f.GetChilds()) {
52             if (ResourceUtil::IsIgnoreFile(it->GetFilePath().GetFilename(), it->IsFile())) {
53                 continue;
54             }
55 
56             if (!it->IsFile()) {
57                 cout << "Error: '" << it->GetFilePath().GetPath() << "' not regular." << endl;
58                 return RESTOOL_ERROR;
59             }
60 
61             FileInfo fileInfo = { directoryInfo, it->GetFilePath().GetPath(), it->GetFilePath().GetFilename() };
62             fileInfos.push_back(fileInfo);
63             setsByDirectory[outputFolder].push_back(fileInfo);
64         }
65     }
66 
67     sort(fileInfos.begin(), fileInfos.end(), [](const auto &a, const auto &b) {
68         return a.filePath < b.filePath;
69     });
70     for (const auto &fileInfo : fileInfos) {
71         if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
72             return RESTOOL_ERROR;
73         }
74     }
75 
76     if (previewMode_) {
77         return RESTOOL_SUCCESS;
78     }
79     if (NeedIfConvertToSolidXml() && ConvertToSolidXml(setsByDirectory) != RESTOOL_SUCCESS) {
80         return RESTOOL_ERROR;
81     }
82     return PostCommit();
83 }
84 
GetResult() const85 const map<int32_t, vector<ResourceItem>> &IResourceCompiler::GetResult() const
86 {
87     return resourceInfos_;
88 }
89 
Compile(const FileInfo & fileInfo)90 uint32_t IResourceCompiler::Compile(const FileInfo &fileInfo)
91 {
92     if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
93         return RESTOOL_ERROR;
94     }
95 
96     if (previewMode_) {
97         return RESTOOL_SUCCESS;
98     }
99     map<string, vector<FileInfo>> setsByDirectory;
100     if (NeedIfConvertToSolidXml()) {
101         string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR)
102             .Append(fileInfo.limitKey).Append(fileInfo.fileCluster).GetPath();
103         setsByDirectory[outputFolder].push_back(fileInfo);
104     }
105 
106     if (ConvertToSolidXml(setsByDirectory) != RESTOOL_SUCCESS) {
107         return RESTOOL_ERROR;
108     }
109     return PostCommit();
110 }
111 
CompileForAppend(const FileInfo & fileInfo)112 uint32_t IResourceCompiler::CompileForAppend(const FileInfo &fileInfo)
113 {
114     return CompileSingleFile(fileInfo);
115 }
116 
GetResourceItems() const117 const map<pair<ResType, string>, vector<ResourceItem>> &IResourceCompiler::GetResourceItems() const
118 {
119     return nameInfos_;
120 }
121 
SetModuleName(const string & moduleName)122 void IResourceCompiler::SetModuleName(const string &moduleName)
123 {
124     moduleName_ = moduleName;
125 }
126 
ConvertToSolidXml(const map<string,vector<FileInfo>> & setsByDirectory)127 uint32_t IResourceCompiler::ConvertToSolidXml(const map<string, vector<FileInfo>> &setsByDirectory)
128 {
129     for (const auto &iter : setsByDirectory) {
130         vector<string> xmlPaths;
131         ListXmlFile(iter.second, xmlPaths);
132         if (xmlPaths.empty()) {
133             continue;
134         }
135 
136         string xmlOutPath = iter.first;
137         if (!ResourceUtil::CreateDirs(xmlOutPath)) {
138             return RESTOOL_ERROR;
139         }
140 
141         sort(xmlPaths.begin(), xmlPaths.end());
142         XmlConverter xmlConverter(xmlPaths, xmlOutPath);
143         if (!xmlConverter.GenerateSolidXml()) {
144             return RESTOOL_ERROR;
145         }
146 
147         if (!xmlConverter.GenerateKey()) {
148             return RESTOOL_ERROR;
149         }
150     }
151     return RESTOOL_SUCCESS;
152 }
153 
CompileSingleFile(const FileInfo & fileInfo)154 uint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo)
155 {
156     return RESTOOL_SUCCESS;
157 }
158 
PostCommit()159 uint32_t IResourceCompiler::PostCommit()
160 {
161     IdWorker &idWorker = IdWorker::GetInstance();
162     for (const auto &nameInfo : nameInfos_) {
163         int32_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second);
164         if (id < 0) {
165             cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='";
166             cerr << nameInfo.first.second << "' id not be defined." << endl;
167             return RESTOOL_ERROR;
168         }
169         resourceInfos_.emplace(id, nameInfo.second);
170     }
171     return RESTOOL_SUCCESS;
172 }
173 
MergeResourceItem(const ResourceItem & resourceItem)174 bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem)
175 {
176     if (previewMode_) {
177         return SqliteDatabase::GetInstance().Insert(resourceItem);
178     }
179     string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType());
180     if (!IdWorker::GetInstance().IsValidName(idName)) {
181         cerr << "Error: invalid idName '" << idName << "'."<< NEW_LINE_PATH <<  resourceItem.GetFilePath() << endl;
182         return false;
183     }
184     auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName));
185     if (item == nameInfos_.end()) {
186         nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
187         return true;
188     }
189 
190     auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) {
191         return resourceItem.GetLimitKey() == iter.GetLimitKey();
192     });
193     if (ret != item->second.end()) {
194         cerr << "Error: resource '" << idName << "' first declared." << NEW_LINE_PATH << ret->GetFilePath() << endl;
195         cerr << "but declare again." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl;
196         return false;
197     }
198 
199     nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
200     return true;
201 }
202 
ListXmlFile(const vector<FileInfo> & fileInfos,vector<string> & xmlPaths) const203 void IResourceCompiler::ListXmlFile(const vector<FileInfo> &fileInfos, vector<string> &xmlPaths) const
204 {
205     for (const auto &fileInfo : fileInfos) {
206         if (!IsXmlFile(fileInfo)) {
207             continue;
208         }
209 
210         if (HasConvertedToSolidXml(fileInfo)) {
211             continue;
212         }
213         xmlPaths.push_back(fileInfo.filePath);
214     }
215 }
216 
IsXmlFile(const FileInfo & fileInfo) const217 bool IResourceCompiler::IsXmlFile(const FileInfo &fileInfo) const
218 {
219     if (FileEntry::FilePath(fileInfo.filePath).GetExtension() != ".xml") {
220         return false;
221     }
222     return true;
223 }
224 
HasConvertedToSolidXml(const FileInfo & fileInfo) const225 bool IResourceCompiler::HasConvertedToSolidXml(const FileInfo &fileInfo) const
226 {
227     string solidXmlPath = FileEntry::FilePath(output_).Append(RESOURCES_DIR).Append(fileInfo.limitKey)
228         .Append(fileInfo.fileCluster).Append(fileInfo.filename).ReplaceExtension(".sxml").GetPath();
229     if (ResourceUtil::FileExist(solidXmlPath)) {
230         return true;
231     }
232     return false;
233 }
234 
NeedIfConvertToSolidXml() const235 bool IResourceCompiler::NeedIfConvertToSolidXml() const
236 {
237     return ResourceUtil::NeedConverToSolidXml(type_);
238 }
239 
GetOutputFolder(const DirectoryInfo & directoryInfo) const240 string IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const
241 {
242     string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR)
243         .Append(directoryInfo.limitKey).Append(directoryInfo.fileCluster).GetPath();
244     return outputFolder;
245 }
246 }
247 }
248 }
249