mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-06-10 23:59:42 +08:00
android-asset-updates
This commit is contained in:
@@ -425,41 +425,50 @@ public class CodePush {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getNewStatusReport(Promise promise) {
|
||||
if (needToReportRollback) {
|
||||
needToReportRollback = false;
|
||||
JSONArray failedUpdates = getFailedUpdates();
|
||||
if (failedUpdates != null && failedUpdates.length() > 0) {
|
||||
try {
|
||||
JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1);
|
||||
WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON);
|
||||
WritableMap failedStatusReport = codePushTelemetryManager.getRollbackReport(lastFailedPackage);
|
||||
if (failedStatusReport != null) {
|
||||
promise.resolve(failedStatusReport);
|
||||
return;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new CodePushUnknownException("Unable to read failed updates information stored in SharedPreferences.", e);
|
||||
}
|
||||
}
|
||||
} else if (didUpdate) {
|
||||
WritableMap currentPackage = codePushPackage.getCurrentPackage();
|
||||
if (currentPackage != null) {
|
||||
WritableMap newPackageStatusReport = codePushTelemetryManager.getUpdateReport(currentPackage);
|
||||
if (newPackageStatusReport != null) {
|
||||
promise.resolve(newPackageStatusReport);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (isRunningBinaryVersion) {
|
||||
WritableMap newAppVersionStatusReport = codePushTelemetryManager.getBinaryUpdateReport(appVersion);
|
||||
if (newAppVersionStatusReport != null) {
|
||||
promise.resolve(newAppVersionStatusReport);
|
||||
return;
|
||||
}
|
||||
}
|
||||
public void getNewStatusReport(final Promise promise) {
|
||||
|
||||
promise.resolve("");
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
if (needToReportRollback) {
|
||||
needToReportRollback = false;
|
||||
JSONArray failedUpdates = getFailedUpdates();
|
||||
if (failedUpdates != null && failedUpdates.length() > 0) {
|
||||
try {
|
||||
JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1);
|
||||
WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON);
|
||||
WritableMap failedStatusReport = codePushTelemetryManager.getRollbackReport(lastFailedPackage);
|
||||
if (failedStatusReport != null) {
|
||||
promise.resolve(failedStatusReport);
|
||||
return null;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new CodePushUnknownException("Unable to read failed updates information stored in SharedPreferences.", e);
|
||||
}
|
||||
}
|
||||
} else if (didUpdate) {
|
||||
WritableMap currentPackage = codePushPackage.getCurrentPackage();
|
||||
if (currentPackage != null) {
|
||||
WritableMap newPackageStatusReport = codePushTelemetryManager.getUpdateReport(currentPackage);
|
||||
if (newPackageStatusReport != null) {
|
||||
promise.resolve(newPackageStatusReport);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else if (isRunningBinaryVersion) {
|
||||
WritableMap newAppVersionStatusReport = codePushTelemetryManager.getBinaryUpdateReport(appVersion);
|
||||
if (newAppVersionStatusReport != null) {
|
||||
promise.resolve(newAppVersionStatusReport);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
promise.resolve("");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
||||
@@ -69,7 +69,7 @@ public class CodePushPackage {
|
||||
|
||||
public WritableMap getCurrentPackageInfo() {
|
||||
String statusFilePath = getStatusFilePath();
|
||||
if (!CodePushUtils.fileAtPathExists(statusFilePath)) {
|
||||
if (!FileUtils.fileAtPathExists(statusFilePath)) {
|
||||
return new WritableNativeMap();
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ public class CodePushPackage {
|
||||
File downloadFile = null;
|
||||
boolean isZip = false;
|
||||
|
||||
// Download the file while checking if it is a zip and notifying client of progress.
|
||||
try {
|
||||
downloadUrl = new URL(downloadUrlString);
|
||||
connection = (HttpURLConnection) (downloadUrl.openConnection());
|
||||
@@ -216,27 +217,34 @@ public class CodePushPackage {
|
||||
}
|
||||
|
||||
if (isZip) {
|
||||
// Unzip the downloaded file and then delete the zip
|
||||
String unzippedFolderPath = getUnzippedFolderPath();
|
||||
CodePushUtils.unzipFile(downloadFile, unzippedFolderPath);
|
||||
CodePushUtils.deleteFileSilently(downloadFile);
|
||||
FileUtils.unzipFile(downloadFile, unzippedFolderPath);
|
||||
FileUtils.deleteFileSilently(downloadFile);
|
||||
|
||||
// Merge contents with current update based on the manifest
|
||||
String diffManifestFilePath = CodePushUtils.appendPathComponent(unzippedFolderPath,
|
||||
DIFF_MANIFEST_FILE_NAME);
|
||||
File diffManifestFile = new File(unzippedFolderPath, DIFF_MANIFEST_FILE_NAME);
|
||||
if (diffManifestFile.exists()) {
|
||||
String currentPackageFolderPath = getCurrentPackageFolderPath();
|
||||
CodePushUtils.mergeEntriesInFolder(currentPackageFolderPath, newPackageFolderPath);
|
||||
FileUtils.copyDirectoryContents(currentPackageFolderPath, newPackageFolderPath);
|
||||
WritableMap diffManifest = CodePushUtils.getWritableMapFromFile(diffManifestFilePath);
|
||||
ReadableArray deletedFiles = diffManifest.getArray("deletedFiles");
|
||||
for (int i = 0; i < deletedFiles.size(); i++) {
|
||||
String fileNameToDelete = deletedFiles.getString(i);
|
||||
File fileToDelete = new File(newPackageFolderPath, fileNameToDelete);
|
||||
CodePushUtils.deleteFileSilently(fileToDelete);
|
||||
FileUtils.deleteFileSilently(fileToDelete);
|
||||
}
|
||||
}
|
||||
|
||||
CodePushUtils.mergeEntriesInFolder(unzippedFolderPath, newPackageFolderPath);
|
||||
CodePushUtils.deleteFileAtPathSilently(unzippedFolderPath);
|
||||
String relativeBundlePath = findMainBundleInFolder(newPackageFolderPath);
|
||||
// Move merged update contents to a folder with the packageHash as its name
|
||||
FileUtils.copyDirectoryContents(unzippedFolderPath, newPackageFolderPath);
|
||||
FileUtils.deleteFileAtPathSilently(unzippedFolderPath);
|
||||
|
||||
// For zip updates, we need to find the relative path to the jsBundle and save it in the
|
||||
// metadata so that we can find and run it easily the next time.
|
||||
String relativeBundlePath = CodePushUtils.findJSBundleInUpdateContents(newPackageFolderPath);
|
||||
|
||||
if (relativeBundlePath == null) {
|
||||
throw new CodePushInvalidPackageException();
|
||||
@@ -252,46 +260,22 @@ public class CodePushPackage {
|
||||
updatePackage = CodePushUtils.convertJsonObjectToWriteable(updatePackageJSON);
|
||||
}
|
||||
} else {
|
||||
// File is not a zip.
|
||||
// File is a jsBundle, move it to a folder with the packageHash as its name
|
||||
File updateBundleFile = new File(newPackageFolderPath, UPDATE_BUNDLE_FILE_NAME);
|
||||
downloadFile.renameTo(updateBundleFile);
|
||||
}
|
||||
|
||||
// Save metadata to the folder.
|
||||
String bundlePath = CodePushUtils.appendPathComponent(newPackageFolderPath, PACKAGE_FILE_NAME);
|
||||
CodePushUtils.writeReadableMapToFile(updatePackage, bundlePath);
|
||||
}
|
||||
|
||||
public String findMainBundleInFolder(String folderPath) {
|
||||
File folder = new File(folderPath);
|
||||
File[] folderFiles = folder.listFiles();
|
||||
for (File file : folderFiles) {
|
||||
String fullFilePath = CodePushUtils.appendPathComponent(folderPath, file.getName());
|
||||
if (file.isDirectory()) {
|
||||
String mainBundlePathInSubFolder = findMainBundleInFolder(fullFilePath);
|
||||
if (mainBundlePathInSubFolder != null) {
|
||||
return CodePushUtils.appendPathComponent(file.getName(), mainBundlePathInSubFolder);
|
||||
}
|
||||
} else {
|
||||
String fileName = file.getName();
|
||||
int dotIndex = fileName.lastIndexOf(".");
|
||||
if (dotIndex >= 0) {
|
||||
String fileExtension = fileName.substring(dotIndex + 1);
|
||||
if (fileExtension.equals("bundle") || fileExtension.equals("js") || fileExtension.equals("jsbundle")) {
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void installPackage(ReadableMap updatePackage) throws IOException {
|
||||
String packageHash = CodePushUtils.tryGetString(updatePackage, PACKAGE_HASH_KEY);
|
||||
WritableMap info = getCurrentPackageInfo();
|
||||
String previousPackageHash = getPreviousPackageHash();
|
||||
if (previousPackageHash != null && !previousPackageHash.equals(packageHash)) {
|
||||
CodePushUtils.deleteDirectoryAtPath(getPackageFolderPath(previousPackageHash));
|
||||
FileUtils.deleteDirectoryAtPath(getPackageFolderPath(previousPackageHash));
|
||||
}
|
||||
|
||||
info.putString(PREVIOUS_PACKAGE_KEY, CodePushUtils.tryGetString(info, CURRENT_PACKAGE_KEY));
|
||||
@@ -302,7 +286,7 @@ public class CodePushPackage {
|
||||
public void rollbackPackage() {
|
||||
WritableMap info = getCurrentPackageInfo();
|
||||
String currentPackageFolderPath = getCurrentPackageFolderPath();
|
||||
CodePushUtils.deleteDirectoryAtPath(currentPackageFolderPath);
|
||||
FileUtils.deleteDirectoryAtPath(currentPackageFolderPath);
|
||||
info.putString(CURRENT_PACKAGE_KEY, CodePushUtils.tryGetString(info, PREVIOUS_PACKAGE_KEY));
|
||||
info.putNull(PREVIOUS_PACKAGE_KEY);
|
||||
updateCurrentPackageInfo(info);
|
||||
@@ -344,6 +328,6 @@ public class CodePushPackage {
|
||||
public void clearUpdates() {
|
||||
File statusFile = new File(getStatusFilePath());
|
||||
statusFile.delete();
|
||||
CodePushUtils.deleteDirectoryAtPath(getCodePushPath());
|
||||
FileUtils.deleteDirectoryAtPath(getCodePushPath());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,89 +31,41 @@ public class CodePushUtils {
|
||||
|
||||
public static final String CODE_PUSH_TAG = "CodePush";
|
||||
public static final String REACT_NATIVE_LOG_TAG = "ReactNative";
|
||||
public static final int WRITE_BUFFER_SIZE = 1024 * 8;
|
||||
|
||||
public static String appendPathComponent(String basePath, String appendPathComponent) {
|
||||
return new File(basePath, appendPathComponent).getAbsolutePath();
|
||||
}
|
||||
|
||||
public static boolean fileAtPathExists(String filePath) {
|
||||
return new File(filePath).exists();
|
||||
}
|
||||
|
||||
public static String readFileToString(String filePath) throws IOException {
|
||||
FileInputStream fin = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
File fl = new File(filePath);
|
||||
fin = new FileInputStream(fl);
|
||||
reader = new BufferedReader(new InputStreamReader(fin));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line).append("\n");
|
||||
public static WritableArray convertJsonArrayToWriteable(JSONArray jsonArr) {
|
||||
WritableArray arr = Arguments.createArray();
|
||||
for (int i=0; i<jsonArr.length(); i++) {
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = jsonArr.get(i);
|
||||
} catch (JSONException jsonException) {
|
||||
// Should not happen.
|
||||
throw new CodePushUnknownException(i + " should be within bounds of array " + jsonArr.toString(), jsonException);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
} finally {
|
||||
if (reader != null) reader.close();
|
||||
if (fin != null) fin.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeStringToFile(String content, String filePath) throws IOException {
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
out = new PrintWriter(filePath);
|
||||
out.print(content);
|
||||
} finally {
|
||||
if (out != null) out.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteDirectoryAtPath(String directoryPath) {
|
||||
deleteDirectory(new File(directoryPath));
|
||||
}
|
||||
|
||||
public static void deleteDirectory(File directory) {
|
||||
if (directory.exists()) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (int i=0; i<files.length; i++) {
|
||||
if(files[i].isDirectory()) {
|
||||
deleteDirectory(files[i]);
|
||||
}
|
||||
else {
|
||||
files[i].delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
directory.delete();
|
||||
}
|
||||
|
||||
public static boolean createFolderAtPath(String filePath) {
|
||||
File file = new File(filePath);
|
||||
return file.mkdir();
|
||||
}
|
||||
|
||||
public static WritableMap getWritableMapFromFile(String filePath) throws IOException {
|
||||
|
||||
String content = CodePushUtils.readFileToString(filePath);
|
||||
JSONObject json = null;
|
||||
try {
|
||||
json = new JSONObject(content);
|
||||
return convertJsonObjectToWriteable(json);
|
||||
} catch (JSONException jsonException) {
|
||||
throw new CodePushMalformedDataException(filePath, jsonException);
|
||||
if (obj instanceof JSONObject)
|
||||
arr.pushMap(convertJsonObjectToWriteable((JSONObject) obj));
|
||||
else if (obj instanceof JSONArray)
|
||||
arr.pushArray(convertJsonArrayToWriteable((JSONArray) obj));
|
||||
else if (obj instanceof String)
|
||||
arr.pushString((String) obj);
|
||||
else if (obj instanceof Double)
|
||||
arr.pushDouble((Double) obj);
|
||||
else if (obj instanceof Integer)
|
||||
arr.pushInt((Integer) obj);
|
||||
else if (obj instanceof Boolean)
|
||||
arr.pushBoolean((Boolean) obj);
|
||||
else if (obj == null)
|
||||
arr.pushNull();
|
||||
else
|
||||
throw new CodePushUnknownException("Unrecognized object: " + obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void writeReadableMapToFile(ReadableMap map, String filePath) throws IOException {
|
||||
JSONObject json = CodePushUtils.convertReadableToJsonObject(map);
|
||||
String jsonString = json.toString();
|
||||
CodePushUtils.writeStringToFile(jsonString, filePath);
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static WritableMap convertJsonObjectToWriteable(JSONObject jsonObj) {
|
||||
@@ -150,73 +102,9 @@ public class CodePushUtils {
|
||||
return map;
|
||||
}
|
||||
|
||||
public static WritableArray convertJsonArrayToWriteable(JSONArray jsonArr) {
|
||||
WritableArray arr = Arguments.createArray();
|
||||
for (int i=0; i<jsonArr.length(); i++) {
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = jsonArr.get(i);
|
||||
} catch (JSONException jsonException) {
|
||||
// Should not happen.
|
||||
throw new CodePushUnknownException(i + " should be within bounds of array " + jsonArr.toString(), jsonException);
|
||||
}
|
||||
|
||||
if (obj instanceof JSONObject)
|
||||
arr.pushMap(convertJsonObjectToWriteable((JSONObject) obj));
|
||||
else if (obj instanceof JSONArray)
|
||||
arr.pushArray(convertJsonArrayToWriteable((JSONArray) obj));
|
||||
else if (obj instanceof String)
|
||||
arr.pushString((String) obj);
|
||||
else if (obj instanceof Double)
|
||||
arr.pushDouble((Double) obj);
|
||||
else if (obj instanceof Integer)
|
||||
arr.pushInt((Integer) obj);
|
||||
else if (obj instanceof Boolean)
|
||||
arr.pushBoolean((Boolean) obj);
|
||||
else if (obj == null)
|
||||
arr.pushNull();
|
||||
else
|
||||
throw new CodePushUnknownException("Unrecognized object: " + obj);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static JSONObject convertReadableToJsonObject(ReadableMap map) {
|
||||
JSONObject jsonObj = new JSONObject();
|
||||
ReadableMapKeySetIterator it = map.keySetIterator();
|
||||
while (it.hasNextKey()) {
|
||||
String key = it.nextKey();
|
||||
ReadableType type = map.getType(key);
|
||||
try {
|
||||
switch (type) {
|
||||
case Map:
|
||||
jsonObj.put(key, convertReadableToJsonObject(map.getMap(key)));
|
||||
break;
|
||||
case Array:
|
||||
jsonObj.put(key, convertReadableToJsonArray(map.getArray(key)));
|
||||
break;
|
||||
case String:
|
||||
jsonObj.put(key, map.getString(key));
|
||||
break;
|
||||
case Number:
|
||||
jsonObj.put(key, map.getDouble(key));
|
||||
break;
|
||||
case Boolean:
|
||||
jsonObj.put(key, map.getBoolean(key));
|
||||
break;
|
||||
case Null:
|
||||
jsonObj.put(key, null);
|
||||
break;
|
||||
default:
|
||||
throw new CodePushUnknownException("Unrecognized type: " + type + " of key: " + key);
|
||||
}
|
||||
} catch (JSONException jsonException) {
|
||||
throw new CodePushUnknownException("Error setting key: " + key + " in JSONObject", jsonException);
|
||||
}
|
||||
}
|
||||
|
||||
return jsonObj;
|
||||
public static WritableMap convertReadableMapToWritableMap(ReadableMap map) {
|
||||
JSONObject mapJSON = convertReadableToJsonObject(map);
|
||||
return convertJsonObjectToWriteable(mapJSON);
|
||||
}
|
||||
|
||||
public static JSONArray convertReadableToJsonArray(ReadableArray arr) {
|
||||
@@ -258,9 +146,87 @@ public class CodePushUtils {
|
||||
return jsonArr;
|
||||
}
|
||||
|
||||
public static WritableMap convertReadableMapToWritableMap(ReadableMap map) {
|
||||
JSONObject mapJSON = convertReadableToJsonObject(map);
|
||||
return convertJsonObjectToWriteable(mapJSON);
|
||||
public static JSONObject convertReadableToJsonObject(ReadableMap map) {
|
||||
JSONObject jsonObj = new JSONObject();
|
||||
ReadableMapKeySetIterator it = map.keySetIterator();
|
||||
while (it.hasNextKey()) {
|
||||
String key = it.nextKey();
|
||||
ReadableType type = map.getType(key);
|
||||
try {
|
||||
switch (type) {
|
||||
case Map:
|
||||
jsonObj.put(key, convertReadableToJsonObject(map.getMap(key)));
|
||||
break;
|
||||
case Array:
|
||||
jsonObj.put(key, convertReadableToJsonArray(map.getArray(key)));
|
||||
break;
|
||||
case String:
|
||||
jsonObj.put(key, map.getString(key));
|
||||
break;
|
||||
case Number:
|
||||
jsonObj.put(key, map.getDouble(key));
|
||||
break;
|
||||
case Boolean:
|
||||
jsonObj.put(key, map.getBoolean(key));
|
||||
break;
|
||||
case Null:
|
||||
jsonObj.put(key, null);
|
||||
break;
|
||||
default:
|
||||
throw new CodePushUnknownException("Unrecognized type: " + type + " of key: " + key);
|
||||
}
|
||||
} catch (JSONException jsonException) {
|
||||
throw new CodePushUnknownException("Error setting key: " + key + " in JSONObject", jsonException);
|
||||
}
|
||||
}
|
||||
|
||||
return jsonObj;
|
||||
}
|
||||
|
||||
public static String findJSBundleInUpdateContents(String folderPath) {
|
||||
File folder = new File(folderPath);
|
||||
File[] folderFiles = folder.listFiles();
|
||||
for (File file : folderFiles) {
|
||||
String fullFilePath = CodePushUtils.appendPathComponent(folderPath, file.getName());
|
||||
if (file.isDirectory()) {
|
||||
String mainBundlePathInSubFolder = findJSBundleInUpdateContents(fullFilePath);
|
||||
if (mainBundlePathInSubFolder != null) {
|
||||
return CodePushUtils.appendPathComponent(file.getName(), mainBundlePathInSubFolder);
|
||||
}
|
||||
} else {
|
||||
String fileName = file.getName();
|
||||
int dotIndex = fileName.lastIndexOf(".");
|
||||
if (dotIndex >= 0) {
|
||||
String fileExtension = fileName.substring(dotIndex + 1);
|
||||
if (fileExtension.equals("bundle") || fileExtension.equals("js") || fileExtension.equals("jsbundle")) {
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static WritableMap getWritableMapFromFile(String filePath) throws IOException {
|
||||
|
||||
String content = FileUtils.readFileToString(filePath);
|
||||
JSONObject json = null;
|
||||
try {
|
||||
json = new JSONObject(content);
|
||||
return convertJsonObjectToWriteable(json);
|
||||
} catch (JSONException jsonException) {
|
||||
throw new CodePushMalformedDataException(filePath, jsonException);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void log(String message) {
|
||||
Log.d(REACT_NATIVE_LOG_TAG, "[CodePush] " + message);
|
||||
}
|
||||
|
||||
public static void logBundleUrl(String path) {
|
||||
log("Loading JS bundle from \"" + path + "\"");
|
||||
}
|
||||
|
||||
public static String tryGetString(ReadableMap map, String key) {
|
||||
@@ -271,113 +237,9 @@ public class CodePushUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void unzipFile(File zipFile, String destination) throws IOException {
|
||||
FileInputStream fis = null;
|
||||
BufferedInputStream bis = null;
|
||||
ZipInputStream zis = null;
|
||||
try {
|
||||
fis = new FileInputStream(zipFile);
|
||||
bis = new BufferedInputStream(fis);
|
||||
zis = new ZipInputStream(bis);
|
||||
ZipEntry entry;
|
||||
|
||||
File destinationFolder = new File(destination);
|
||||
if (!destinationFolder.exists()) {
|
||||
destinationFolder.mkdirs();
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[WRITE_BUFFER_SIZE];
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
String fileName = entry.getName();
|
||||
File file = new File(destinationFolder, fileName);
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
} else {
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(file);
|
||||
try {
|
||||
int numBytesRead;
|
||||
while ((numBytesRead = zis.read(buffer)) != -1) {
|
||||
fout.write(buffer, 0, numBytesRead);
|
||||
}
|
||||
} finally {
|
||||
fout.close();
|
||||
}
|
||||
}
|
||||
long time = entry.getTime();
|
||||
if (time > 0) {
|
||||
file.setLastModified(time);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (zis != null) zis.close();
|
||||
if (bis != null) bis.close();
|
||||
if (fis != null) fis.close();
|
||||
} catch (IOException e) {
|
||||
throw new CodePushUnknownException("Error closing IO resources.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void mergeEntriesInFolder(String fromPath, String destinationPath) throws IOException {
|
||||
File fromDir = new File(fromPath);
|
||||
File destDir = new File(destinationPath);
|
||||
if (!destDir.exists()) {
|
||||
destDir.mkdir();
|
||||
}
|
||||
|
||||
for (File fromFile : fromDir.listFiles()) {
|
||||
if (fromFile.isDirectory()) {
|
||||
mergeEntriesInFolder(
|
||||
CodePushUtils.appendPathComponent(fromPath, fromFile.getName()),
|
||||
CodePushUtils.appendPathComponent(destinationPath, fromFile.getName()));
|
||||
} else {
|
||||
File destFile = new File(destDir, fromFile.getName());
|
||||
FileInputStream fromFileStream = null;
|
||||
BufferedInputStream fromBufferedStream = null;
|
||||
FileOutputStream destStream = null;
|
||||
byte[] buffer = new byte[WRITE_BUFFER_SIZE];
|
||||
try {
|
||||
fromFileStream = new FileInputStream(fromFile);
|
||||
fromBufferedStream = new BufferedInputStream(fromFileStream);
|
||||
destStream = new FileOutputStream(destFile);
|
||||
int bytesRead;
|
||||
while ((bytesRead = fromBufferedStream.read(buffer)) > 0) {
|
||||
destStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (fromFileStream != null) fromFileStream.close();
|
||||
if (fromBufferedStream != null) fromBufferedStream.close();
|
||||
if (destStream != null) destStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new CodePushUnknownException("Error closing IO resources.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteFileAtPathSilently(String path) {
|
||||
deleteFileSilently(new File(path));
|
||||
}
|
||||
|
||||
public static void deleteFileSilently(File file) {
|
||||
if (!file.delete()) {
|
||||
Log.e(CODE_PUSH_TAG, "Error deleting file " + file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void log(String message) {
|
||||
Log.d(REACT_NATIVE_LOG_TAG, "[CodePush] " + message);
|
||||
}
|
||||
|
||||
public static void logBundleUrl(String path) {
|
||||
log("Loading JS bundle from \"" + path + "\"");
|
||||
public static void writeReadableMapToFile(ReadableMap map, String filePath) throws IOException {
|
||||
JSONObject json = CodePushUtils.convertReadableToJsonObject(map);
|
||||
String jsonString = json.toString();
|
||||
FileUtils.writeStringToFile(jsonString, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.microsoft.codepush.react;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
public static final int WRITE_BUFFER_SIZE = 1024 * 8;
|
||||
|
||||
public static boolean fileAtPathExists(String filePath) {
|
||||
return new File(filePath).exists();
|
||||
}
|
||||
|
||||
public static String readFileToString(String filePath) throws IOException {
|
||||
FileInputStream fin = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
File fl = new File(filePath);
|
||||
fin = new FileInputStream(fl);
|
||||
reader = new BufferedReader(new InputStreamReader(fin));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line).append("\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
} finally {
|
||||
if (reader != null) reader.close();
|
||||
if (fin != null) fin.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeStringToFile(String content, String filePath) throws IOException {
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
out = new PrintWriter(filePath);
|
||||
out.print(content);
|
||||
} finally {
|
||||
if (out != null) out.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteDirectoryAtPath(String directoryPath) {
|
||||
deleteDirectory(new File(directoryPath));
|
||||
}
|
||||
|
||||
public static void deleteDirectory(File directory) {
|
||||
if (directory.exists()) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (int i=0; i<files.length; i++) {
|
||||
if(files[i].isDirectory()) {
|
||||
deleteDirectory(files[i]);
|
||||
}
|
||||
else {
|
||||
files[i].delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
directory.delete();
|
||||
}
|
||||
|
||||
public static boolean createFolderAtPath(String filePath) {
|
||||
File file = new File(filePath);
|
||||
return file.mkdir();
|
||||
}
|
||||
|
||||
public static void unzipFile(File zipFile, String destination) throws IOException {
|
||||
FileInputStream fileStream = null;
|
||||
BufferedInputStream bufferedStream = null;
|
||||
ZipInputStream zipStream = null;
|
||||
try {
|
||||
fileStream = new FileInputStream(zipFile);
|
||||
bufferedStream = new BufferedInputStream(fileStream);
|
||||
zipStream = new ZipInputStream(bufferedStream);
|
||||
ZipEntry entry;
|
||||
|
||||
File destinationFolder = new File(destination);
|
||||
if (!destinationFolder.exists()) {
|
||||
destinationFolder.mkdirs();
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[WRITE_BUFFER_SIZE];
|
||||
while ((entry = zipStream.getNextEntry()) != null) {
|
||||
String fileName = entry.getName();
|
||||
File file = new File(destinationFolder, fileName);
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
} else {
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(file);
|
||||
try {
|
||||
int numBytesRead;
|
||||
while ((numBytesRead = zipStream.read(buffer)) != -1) {
|
||||
fout.write(buffer, 0, numBytesRead);
|
||||
}
|
||||
} finally {
|
||||
fout.close();
|
||||
}
|
||||
}
|
||||
long time = entry.getTime();
|
||||
if (time > 0) {
|
||||
file.setLastModified(time);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (zipStream != null) zipStream.close();
|
||||
if (bufferedStream != null) bufferedStream.close();
|
||||
if (fileStream != null) fileStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new CodePushUnknownException("Error closing IO resources.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyDirectoryContents(String sourceDirectoryPath, String destinationDirectoryPath) throws IOException {
|
||||
File sourceDir = new File(sourceDirectoryPath);
|
||||
File destDir = new File(destinationDirectoryPath);
|
||||
if (!destDir.exists()) {
|
||||
destDir.mkdir();
|
||||
}
|
||||
|
||||
for (File sourceFile : sourceDir.listFiles()) {
|
||||
if (sourceFile.isDirectory()) {
|
||||
copyDirectoryContents(
|
||||
CodePushUtils.appendPathComponent(sourceDirectoryPath, sourceFile.getName()),
|
||||
CodePushUtils.appendPathComponent(destinationDirectoryPath, sourceFile.getName()));
|
||||
} else {
|
||||
File destFile = new File(destDir, sourceFile.getName());
|
||||
FileInputStream fromFileStream = null;
|
||||
BufferedInputStream fromBufferedStream = null;
|
||||
FileOutputStream destStream = null;
|
||||
byte[] buffer = new byte[WRITE_BUFFER_SIZE];
|
||||
try {
|
||||
fromFileStream = new FileInputStream(sourceFile);
|
||||
fromBufferedStream = new BufferedInputStream(fromFileStream);
|
||||
destStream = new FileOutputStream(destFile);
|
||||
int bytesRead;
|
||||
while ((bytesRead = fromBufferedStream.read(buffer)) > 0) {
|
||||
destStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (fromFileStream != null) fromFileStream.close();
|
||||
if (fromBufferedStream != null) fromBufferedStream.close();
|
||||
if (destStream != null) destStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new CodePushUnknownException("Error closing IO resources.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteFileAtPathSilently(String path) {
|
||||
deleteFileSilently(new File(path));
|
||||
}
|
||||
|
||||
public static void deleteFileSilently(File file) {
|
||||
if (!file.delete()) {
|
||||
CodePushUtils.log("Error deleting file " + file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user