• 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 package ohos;
17 
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.RandomAccessFile;
21 import java.util.ArrayList;
22 import java.util.LinkedList;
23 import java.util.Optional;
24 import java.util.Queue;
25 import com.alibaba.fastjson.JSONObject;
26 
27 /**
28  * generate binary file
29  *
30  */
31 public class BinaryTool {
32     private static final String JSON_FILE_NAME = "config.json";
33     private static final String PROFILE_KEY = "app";
34     private static final String PACKAGE_KEY = "bundleName";
35     private static final Log LOG = new Log(BinaryTool.class.toString());
36 
37     /**
38      * generate binary file
39      *
40      * @param filePath absolute project path
41      * @param binaryFilePath absolute binaryFilePath
42      * @return true: success, false: fail
43      */
generateBinaryFile(final String filePath, final String binaryFilePath)44     public static boolean generateBinaryFile(final String filePath, final String binaryFilePath) {
45         Optional<String> absPath = FileUtils.getFormatedPath(filePath);
46         if (!absPath.isPresent()) {
47             return false;
48         }
49         Optional<String> absBinaryFilePath = FileUtils.getFormatedPath(binaryFilePath);
50         if (!absBinaryFilePath.isPresent()) {
51             return false;
52         }
53 
54         boolean isSuccess = false;
55         RandomAccessFile appStream = null;
56         try {
57             appStream = new RandomAccessFile(absBinaryFilePath.get(), "rwd");
58             if (!writePackageInfo(absPath.get(), appStream)) {
59                 return false;
60             }
61             ArrayList<String> fileList = new ArrayList<>();
62             FileUtils.getFileList(absPath.get(), fileList);
63             ArrayList<String> writeFileList = new ArrayList<>();
64             boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("win");
65             writeFileInfo(absPath.get(), absPath.get(), isWindows, writeFileList, appStream);
66             if (fileList.size() != writeFileList.size()) {
67                 return false;
68             }
69             isSuccess = true;
70             return true;
71         } catch (IOException msg) {
72             LOG.error("IOException, msg is: " + msg.getMessage());
73             return false;
74         } finally {
75             FileUtils.closeStream(appStream);
76             if (!isSuccess) {
77                 LOG.error("build binary file failed!");
78                 FileUtils.deleteFile(absBinaryFilePath.get());
79             }
80         }
81     }
82 
83     /**
84      * write package Info in binary file
85      *
86      * @param filePath the file path which need to be written
87      * @param appStream file stream
88      * @return true: success, false: fail
89      */
writePackageInfo(final String filePath, RandomAccessFile appStream)90     private static boolean writePackageInfo(final String filePath, RandomAccessFile appStream) {
91         Optional<String> packageName = getValueFromJsonFileContent(PROFILE_KEY, PACKAGE_KEY,
92                 JSON_FILE_NAME, filePath);
93         if (!packageName.isPresent()) {
94             LOG.error("have no config.json or have no key of package!");
95             return false;
96         }
97         try {
98             appStream.write(0xbe);
99             // add packageName
100             int strLen = packageName.get().length();
101             appStream.writeInt(strLen);
102             appStream.writeBytes(packageName.get());
103         } catch (IOException msg) {
104             LOG.error("write packageInfo fail, msg is " + msg.getMessage());
105             return false;
106         }
107         return true;
108     }
109 
110     /**
111      * write file Info in binary file
112      *
113      * @param filePath project file path
114      * @param directory project dir path
115      * @param isWindows flag which is for windows system or linux system
116      * @param fileList the file path in directory
117      * @param appStream file stream
118      */
writeFileInfo(final String filePath, final String directory, boolean isWindows, ArrayList<String> fileList, RandomAccessFile appStream)119     private static void writeFileInfo(final String filePath, final String directory, boolean isWindows,
120         ArrayList<String> fileList, RandomAccessFile appStream) {
121         File file = new File(filePath);
122         if (!file.exists()) {
123             return;
124         }
125 
126         Queue<File> fileDirList = new LinkedList<>();
127         fileDirList.add(file);
128         while (!fileDirList.isEmpty()) {
129             File dirFile = fileDirList.poll();
130             File[] files = dirFile.listFiles();
131             for (File f : files) {
132                 try {
133                     if (f.isFile()) {
134                         // write name length
135                         String name = f.getName();
136                         appStream.writeInt(name.length());
137                         // write name
138                         appStream.writeBytes(name);
139                         // write relative path length, 4Bytes
140                         String relativePath = f.getParent().replace(directory, "");
141                         if (isWindows) {
142                             relativePath = relativePath.replace("\\", "/");
143                         }
144                         appStream.writeInt(relativePath.length());
145                         // write relative path
146                         appStream.writeBytes(relativePath);
147                         // write file length, 8Bytes
148                         appStream.writeLong(f.length());
149                         // write file data
150                         String absolutePath = f.getCanonicalPath();
151                         appStream.write(FileUtils.getFileData(absolutePath));
152                         fileList.add(absolutePath);
153                     } else {
154                         fileDirList.add(f);
155                     }
156                 } catch (IOException msg) {
157                     LOG.error("write fail, msg is: " + msg.getMessage());
158                 }
159             }
160         }
161     }
162 
163     /**
164      * get special value from JSON String
165      *
166      * @param key json main key
167      * @param subKey json sub key
168      * @param jsonFileName json file name
169      * @param filePath path which will be searched
170      * @return value
171      */
getValueFromJsonFileContent(final String key, final String subKey, final String jsonFileName, final String filePath)172     public static Optional<String> getValueFromJsonFileContent(final String key, final String subKey,
173                                                                final String jsonFileName, final String filePath) {
174         Optional<String> jsonFilePath = FileUtils.searchFile(jsonFileName, filePath);
175         if (!jsonFilePath.isPresent()) {
176             return Optional.empty();
177         }
178 
179         Optional<String> jsonStr = FileUtils.getFileContent(jsonFilePath.get());
180         if (!jsonStr.isPresent()) {
181             return Optional.empty();
182         }
183 
184         JSONObject jsonObject = JSONObject.parseObject(jsonStr.get());
185         if (jsonObject == null) {
186             return Optional.empty();
187         }
188 
189         if (!jsonObject.containsKey(key)) {
190             return Optional.empty();
191         }
192 
193         JSONObject subObject = jsonObject.getJSONObject(key);
194         String value = subObject.getString(subKey);
195         return Optional.of(value);
196     }
197 }