• 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 
SetModuleName(const string & moduleName)112 void IResourceCompiler::SetModuleName(const string &moduleName)
113 {
114     moduleName_ = moduleName;
115 }
116 
ConvertToSolidXml(const map<string,vector<FileInfo>> & setsByDirectory)117 uint32_t IResourceCompiler::ConvertToSolidXml(const map<string, vector<FileInfo>> &setsByDirectory)
118 {
119     for (const auto &iter : setsByDirectory) {
120         vector<string> xmlPaths;
121         ListXmlFile(iter.second, xmlPaths);
122         if (xmlPaths.empty()) {
123             continue;
124         }
125 
126         string xmlOutPath = iter.first;
127         if (!ResourceUtil::CreateDirs(xmlOutPath)) {
128             return RESTOOL_ERROR;
129         }
130 
131         sort(xmlPaths.begin(), xmlPaths.end());
132         XmlConverter xmlConverter(xmlPaths, xmlOutPath);
133         if (!xmlConverter.GenerateSolidXml()) {
134             return RESTOOL_ERROR;
135         }
136 
137         if (!xmlConverter.GenerateKey()) {
138             return RESTOOL_ERROR;
139         }
140     }
141     return RESTOOL_SUCCESS;
142 }
143 
CompileSingleFile(const FileInfo & fileInfo)144 uint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo)
145 {
146     return RESTOOL_SUCCESS;
147 }
148 
PostCommit()149 uint32_t IResourceCompiler::PostCommit()
150 {
151     IdWorker &idWorker = IdWorker::GetInstance();
152     for (const auto &nameInfo : nameInfos_) {
153         int32_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second);
154         if (id < 0) {
155             cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='";
156             cerr << nameInfo.first.second << "' id not be defined." << endl;
157             return RESTOOL_ERROR;
158         }
159         resourceInfos_.emplace(id, nameInfo.second);
160     }
161     return RESTOOL_SUCCESS;
162 }
163 
MergeResourceItem(const ResourceItem & resourceItem)164 bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem)
165 {
166     if (previewMode_) {
167         return SqliteDatabase::GetInstance().Insert(resourceItem);
168     }
169     string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType());
170     if (!IdWorker::GetInstance().IsValidName(idName)) {
171         cerr << "Error: in " << resourceItem.GetFilePath() << endl;
172         return false;
173     }
174     auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName));
175     if (item == nameInfos_.end()) {
176         nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
177         return true;
178     }
179 
180     auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) {
181         return resourceItem.GetLimitKey() == iter.GetLimitKey();
182     });
183     if (ret != item->second.end()) {
184         cerr << "Error: resource '" << idName << "' first declared in " << ret->GetFilePath();
185         cerr << ", but declare again in " << resourceItem.GetFilePath() << endl;
186         return false;
187     }
188 
189     nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
190     return true;
191 }
192 
ListXmlFile(const vector<FileInfo> & fileInfos,vector<string> & xmlPaths) const193 void IResourceCompiler::ListXmlFile(const vector<FileInfo> &fileInfos, vector<string> &xmlPaths) const
194 {
195     for (const auto &fileInfo : fileInfos) {
196         if (!IsXmlFile(fileInfo)) {
197             continue;
198         }
199 
200         if (HasConvertedToSolidXml(fileInfo)) {
201             continue;
202         }
203         xmlPaths.push_back(fileInfo.filePath);
204     }
205 }
206 
IsXmlFile(const FileInfo & fileInfo) const207 bool IResourceCompiler::IsXmlFile(const FileInfo &fileInfo) const
208 {
209     if (FileEntry::FilePath(fileInfo.filePath).GetExtension() != ".xml") {
210         return false;
211     }
212     return true;
213 }
214 
HasConvertedToSolidXml(const FileInfo & fileInfo) const215 bool IResourceCompiler::HasConvertedToSolidXml(const FileInfo &fileInfo) const
216 {
217     string solidXmlPath = FileEntry::FilePath(output_).Append(RESOURCES_DIR).Append(fileInfo.limitKey)
218         .Append(fileInfo.fileCluster).Append(fileInfo.filename).ReplaceExtension(".sxml").GetPath();
219     if (ResourceUtil::FileExist(solidXmlPath)) {
220         return true;
221     }
222     return false;
223 }
224 
NeedIfConvertToSolidXml() const225 bool IResourceCompiler::NeedIfConvertToSolidXml() const
226 {
227     return ResourceUtil::NeedConverToSolidXml(type_);
228 }
229 
GetOutputFolder(const DirectoryInfo & directoryInfo) const230 string IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const
231 {
232     string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR)
233         .Append(directoryInfo.limitKey).Append(directoryInfo.fileCluster).GetPath();
234     return outputFolder;
235 }
236 }
237 }
238 }
239