First functional iteration of the .kmp processor.

This commit is contained in:
Joshua A. Horton 2017-12-08 14:53:38 +07:00
parent 4ec82a5acf
commit ba0cbd2d72
3 changed files with 81 additions and 46 deletions

View file

@ -43,6 +43,7 @@ android {
dependencies {
implementation 'com.android.support:support-v4:25.4.0'
implementation 'commons-io:commons-io:2.6'
testImplementation 'junit:junit:4.12'
testImplementation "org.robolectric:robolectric:3.5.1"
}

View file

@ -1,5 +1,8 @@
package com.tavultesoft.kmea.packages;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.tavultesoft.kmea.KMManager;
import com.tavultesoft.kmea.JSONParser;
@ -17,6 +20,7 @@ import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.FileUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -66,22 +70,9 @@ public class PackageProcessor {
}
}
static boolean clearDirectory(File path) {
// Java won't allow deleting non-empty directories, so we need recursion to perform a full delete.
if(path.isDirectory()) {
File[] children = path.listFiles();
for(File child:children) {
boolean resultFlag = clearDirectory(child);
if(!resultFlag) {
return false;
}
}
}
return path.delete();
}
// A default, managed mapping for package installation, handling both temp directory
// and perm directory locations. No need to relocate the downloaded .kmp file itself.
@NonNull
static File constructPath(File path, boolean temp) {
String filename = path.getName();
String kmpBaseName;
@ -149,25 +140,55 @@ public class PackageProcessor {
return json.getJSONObject("system").getString("fileVersion");
}
// Returns 1 if newer, 0 if equal, and -1 if older or invalid. If no prior version exists, returns 1.
public static int comparePackageDirectories(File newPath, File oldPath) throws IOException, JSONException {
JSONObject newInfoJSON = loadPackageInfo(newPath);
String newVersion = getVersion(newInfoJSON);
if(oldPath.exists()) {
JSONObject oldInfoJSON = loadPackageInfo(oldPath);
String originalVersion = getVersion(oldInfoJSON);
if(KMManager.compareVersions(newVersion, originalVersion) == 1) {
return 1;
} else if(KMManager.compareVersions(newVersion, originalVersion) == 0){
return 0;
} else {
return -1;
}
} else {
return 1;
}
}
@Nullable
public static List<Map<String, String>> processKMP(File path) throws IOException, JSONException {
File tempPath = unzipKMP(path);
JSONObject newInfoJSON = loadPackageInfo(tempPath);
String newVersion = getVersion(newInfoJSON);
File permPath = constructPath(path, false);
if(permPath.exists()) {
JSONObject oldInfoJSON = loadPackageInfo(permPath);
String originalVersion = getVersion(oldInfoJSON);
// TODO: Compare versions.
// if(newer) then overwrite
// else cancel package install, erase temp directory
return null;
} else {
// No version conflict! Proceed with the install!
// Is within else 'cause there's no need to overwrite.
if(comparePackageDirectories(tempPath, permPath) != -1) {
// Abort! The current installation is newer or as up-to-date.
FileUtils.deleteDirectory(tempPath);
return null;
} else {
// Out with the old. "In with the new" is identical to a new package installation.
FileUtils.deleteDirectory(permPath);
}
}
// No version conflict! Proceed with the install!
// A nice, recursive method provided by Apache Commons-IO's FileUtils class.
FileUtils.moveDirectory(tempPath, permPath);
// How to retrieve other interesting bits of JSON, with pretty-printing:
// System.out.println("System: " + json.getJSONObject("system").toString(2));
// System.out.println("Options: " + json.getJSONObject("options").toString(2));
// System.out.println("Info: " + json.getJSONObject("info").toString(2));
// System.out.println("Files: " + json.getJSONArray("files").toString(2));
// newInfoJSON holds all the newly downloaded/updated keyboard data.
JSONArray keyboards = newInfoJSON.getJSONArray("keyboards");
ArrayList<Map<String, String>> keyboardSpecs = new ArrayList<>();

View file

@ -2,9 +2,12 @@ package com.tavultesoft.kmea.packages;
import com.tavultesoft.kmea.KMManager;
import org.apache.commons.io.FileUtils;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -23,6 +26,8 @@ public class PackageProcessorTest {
public static final String TEST_GFF_KMP_NAME = "gff_amh_7_test_json";
public static final File TEST_GFF_KMP_FILE = new File(TEST_RESOURCE_ROOT, TEST_GFF_KMP_NAME + ".kmp");
public static final File TEST_GFF_KMP_TARGET = new File(TEST_EXTRACTION_ROOT, "packages" +
File.separator + TEST_GFF_KMP_NAME);
/* TODO: Create an alternate version with a different package version; perform package overwrite tests
* in both directions.
@ -30,8 +35,8 @@ public class PackageProcessorTest {
private static File tempPkg;
@BeforeClass
public static void extractTestPackages() {
@Before
public void extractTestPackages() {
PackageProcessor.initialize(TEST_EXTRACTION_ROOT);
try {
@ -53,20 +58,20 @@ public class PackageProcessorTest {
JSONObject json = PackageProcessor.loadPackageInfo(tempPkg);
Assert.assertNotNull(json);
// Test pretty-print, for visual inspection if desired.
System.out.println();
System.out.println("Package version: " + json.getJSONObject("system").get("fileVersion"));
System.out.println();
System.out.println("System: " + json.getJSONObject("system").toString(2));
System.out.println();
System.out.println("Options: " + json.getJSONObject("options").toString(2));
System.out.println();
System.out.println("Info: " + json.getJSONObject("info").toString(2));
System.out.println();
System.out.println("Files: " + json.getJSONArray("files").toString(2));
System.out.println();
System.out.println("Keyboards: " + json.getJSONArray("keyboards").toString(2));
//
// // Test pretty-print, for visual inspection if desired.
// System.out.println();
// System.out.println("Package version: " + json.getJSONObject("system").get("fileVersion"));
// System.out.println();
// System.out.println("System: " + json.getJSONObject("system").toString(2));
// System.out.println();
// System.out.println("Options: " + json.getJSONObject("options").toString(2));
// System.out.println();
// System.out.println("Info: " + json.getJSONObject("info").toString(2));
// System.out.println();
// System.out.println("Files: " + json.getJSONArray("files").toString(2));
// System.out.println();
// System.out.println("Keyboards: " + json.getJSONArray("keyboards").toString(2));
}
@Test
@ -109,8 +114,16 @@ public class PackageProcessorTest {
Assert.assertNotEquals(new File(permPath), PackageProcessor.constructPath(TEST_GFF_KMP_FILE, true));
}
@AfterClass
public static void eraseTestPackages() {
PackageProcessor.clearDirectory(tempPkg);
@Test
public void test_installKMP() throws Exception {
PackageProcessor.processKMP(TEST_GFF_KMP_FILE);
Assert.assertTrue(TEST_GFF_KMP_TARGET.exists());
}
@After
public void eraseTestPackages() throws IOException {
FileUtils.deleteDirectory(tempPkg);
FileUtils.deleteDirectory(TEST_GFF_KMP_TARGET);
}
}