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 }