swap: skip writing index.xml, output straight to index.jar

This makes the index generation noticeably faster.  This also converts
IndexXmlBuilder to a singleton, since that's how it is used.
This commit is contained in:
Hans-Christoph Steiner 2016-05-18 16:15:41 +02:00
parent 3ec206b152
commit 944d355e29

View File

@ -14,12 +14,10 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Hasher;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.App;
@ -28,20 +26,16 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.security.cert.CertificateEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@ -69,14 +63,13 @@ public final class LocalRepoManager {
private final String fdroidPackageName;
private static final String[] WEB_ROOT_ASSET_FILES = {
"swap-icon.png",
"swap-tick-done.png",
"swap-tick-not-done.png",
"swap-icon.png",
"swap-tick-done.png",
"swap-tick-not-done.png",
};
private final Map<String, App> apps = new HashMap<>();
private final SanitizedFile xmlIndex;
private final SanitizedFile xmlIndexJar;
private final SanitizedFile xmlIndexJarUnsigned;
private final SanitizedFile webRoot;
@ -110,7 +103,6 @@ public final class LocalRepoManager {
repoDir = new SanitizedFile(fdroidDir, "repo");
repoDirCaps = new SanitizedFile(fdroidDirCaps, "REPO");
iconsDir = new SanitizedFile(repoDir, "icons");
xmlIndex = new SanitizedFile(repoDir, "index.xml");
xmlIndexJar = new SanitizedFile(repoDir, "index.jar");
xmlIndexJarUnsigned = new SanitizedFile(repoDir, "index.unsigned.jar");
@ -322,32 +314,30 @@ public final class LocalRepoManager {
/**
* Helper class to aid in constructing index.xml file.
* It uses the PullParser API, because the DOM api is only able to be serialized from
* API 8 upwards, but we support 7 at time of implementation.
*/
public static class IndexXmlBuilder {
public static final class IndexXmlBuilder {
private static IndexXmlBuilder indexXmlBuilder;
public static IndexXmlBuilder get() throws XmlPullParserException {
if (indexXmlBuilder == null) {
indexXmlBuilder = new IndexXmlBuilder();
}
return indexXmlBuilder;
}
@NonNull
private final XmlSerializer serializer;
@NonNull
private final Map<String, App> apps;
@NonNull
private final Context context;
@NonNull
private final DateFormat dateToStr = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
public IndexXmlBuilder(@NonNull Context context, @NonNull Map<String, App> apps) throws XmlPullParserException, IOException {
this.context = context;
this.apps = apps;
private IndexXmlBuilder() throws XmlPullParserException {
serializer = XmlPullParserFactory.newInstance().newSerializer();
}
public void build(File file) throws IOException, LocalRepoKeyStore.InitException {
Writer output = new FileWriter(file);
serializer.setOutput(output);
public void build(Context context, Map<String, App> apps, OutputStream output) throws IOException, LocalRepoKeyStore.InitException {
serializer.setOutput(output, "UTF-8");
serializer.startDocument(null, null);
serializer.startTag("", "fdroid");
@ -383,6 +373,7 @@ public final class LocalRepoManager {
/**
* Alias for {@link org.fdroid.fdroid.localrepo.LocalRepoManager.IndexXmlBuilder#tag(String, String)}
* That accepts a number instead of string.
*
* @see IndexXmlBuilder#tag(String, String)
*/
private void tag(String name, long number) throws IOException {
@ -392,6 +383,7 @@ public final class LocalRepoManager {
/**
* Alias for {@link org.fdroid.fdroid.localrepo.LocalRepoManager.IndexXmlBuilder#tag(String, String)}
* that accepts a date instead of a string.
*
* @see IndexXmlBuilder#tag(String, String)
*/
private void tag(String name, Date date) throws IOException {
@ -487,32 +479,12 @@ public final class LocalRepoManager {
}
}
public void writeIndexJar() throws IOException {
try {
new IndexXmlBuilder(context, apps).build(xmlIndex);
} catch (Exception e) {
Log.e(TAG, "Could not write index jar", e);
Toast.makeText(context, R.string.failed_to_create_index, Toast.LENGTH_LONG).show();
return;
}
public void writeIndexJar() throws IOException, XmlPullParserException, LocalRepoKeyStore.InitException {
BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(xmlIndexJarUnsigned));
JarOutputStream jo = new JarOutputStream(bo);
BufferedInputStream bi = new BufferedInputStream(new FileInputStream(xmlIndex));
JarEntry je = new JarEntry("index.xml");
jo.putNextEntry(je);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = bi.read(buf)) != -1) {
jo.write(buf, 0, bytesRead);
}
bi.close();
IndexXmlBuilder.get().build(context, apps, jo);
jo.close();
bo.close();