ZipXmlThemeResourceProvider: add method to just scan zip for xml themes (#807)

This commit is contained in:
Emux 2021-02-22 14:06:03 +02:00 committed by GitHub
parent 22ed9653ec
commit ddf94ae2ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 15 deletions

View File

@ -238,10 +238,9 @@ public class MapsforgeActivity extends MapActivity {
return;
try {
Uri uri = data.getData();
final Uri uri = data.getData();
final ZipXmlThemeResourceProvider resourceProvider = new ZipXmlThemeResourceProvider(new ZipInputStream(new BufferedInputStream(getContentResolver().openInputStream(uri))));
final List<String> xmlThemes = resourceProvider.getXmlThemes();
final List<String> xmlThemes = ZipXmlThemeResourceProvider.scanXmlThemes(new ZipInputStream(new BufferedInputStream(getContentResolver().openInputStream(uri))));
if (xmlThemes.isEmpty())
return;
@ -250,13 +249,17 @@ public class MapsforgeActivity extends MapActivity {
builder.setSingleChoiceItems(xmlThemes.toArray(new String[0]), -1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
ThemeFile theme = new ZipRenderTheme(xmlThemes.get(which), resourceProvider);
if (mTheme != null)
mTheme.dispose();
mTheme = mMap.setTheme(theme);
mapsforgeTheme(mTheme);
mMenu.findItem(R.id.theme_external_archive).setChecked(true);
try {
dialog.dismiss();
ThemeFile theme = new ZipRenderTheme(xmlThemes.get(which), new ZipXmlThemeResourceProvider(new ZipInputStream(new BufferedInputStream(getContentResolver().openInputStream(uri)))));
if (mTheme != null)
mTheme.dispose();
mTheme = mMap.setTheme(theme);
mapsforgeTheme(mTheme);
mMenu.findItem(R.id.theme_external_archive).setChecked(true);
} catch (IOException e) {
e.printStackTrace();
}
}
});
builder.show();

View File

@ -83,4 +83,18 @@ public class ZipXmlThemeResourceProviderTest {
public void openEmpty() throws IOException {
Assert.assertTrue(new ZipXmlThemeResourceProvider(null).getXmlThemes().isEmpty());
}
@Test
public void scanZipForXmlThemes() throws IOException {
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(ZipXmlThemeResourceProviderTest.class.getResourceAsStream("/xmlthemetest.zip")));
Assert.assertNotNull(zis);
List<String> xmlThemes = ZipXmlThemeResourceProvider.scanXmlThemes(zis);
Assert.assertEquals(4, xmlThemes.size());
Assert.assertTrue(xmlThemes.contains("one.xml"));
Assert.assertTrue(xmlThemes.contains("two.xml"));
Assert.assertTrue(xmlThemes.contains("res/three.xml"));
Assert.assertTrue(xmlThemes.contains("res/sub/four.xml"));
}
}

View File

@ -60,12 +60,9 @@ public class ZipXmlThemeResourceProvider implements XmlThemeResourceProvider {
continue;
}
byte[] entry = streamToBytes(zipInputStream, (int) zipEntry.getSize());
String fileName = zipEntry.getName();
if (fileName.startsWith("/")) {
fileName = fileName.substring(1);
}
String fileName = zipEntryName(zipEntry.getName());
files.put(fileName, entry);
if (fileName.toLowerCase(Locale.ROOT).endsWith(".xml")) {
if (isXmlTheme(fileName)) {
xmlThemes.add(fileName);
}
}
@ -112,6 +109,45 @@ public class ZipXmlThemeResourceProvider implements XmlThemeResourceProvider {
return xmlThemes;
}
private static boolean isXmlTheme(String fileName) {
return fileName.toLowerCase(Locale.ROOT).endsWith(".xml");
}
/**
* Scans a given zip stream for contained xml themes without actually reading and storing its content in memory.
* <p>
* This method is useful to find out which xml themes are available across multiple zip files
* without actually have to read them all into memory.
*
* @param zipInputStream zip stream to read resources from
* @return the XML theme paths in the archive
* @throws IOException if a problem occurs reading the stream
*/
public static List<String> scanXmlThemes(ZipInputStream zipInputStream) throws IOException {
if (zipInputStream == null) {
return Collections.emptyList();
}
List<String> xmlThemes = new ArrayList<>();
try {
ZipEntry zipEntry;
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
if (zipEntry.isDirectory()) {
continue;
}
String fileName = zipEntryName(zipEntry.getName());
if (isXmlTheme(fileName)) {
xmlThemes.add(fileName);
}
}
} finally {
IOUtils.closeQuietly(zipInputStream);
}
return xmlThemes;
}
private static byte[] streamToBytes(InputStream in, int size) throws IOException {
byte[] bytes = new byte[size];
int count, offset = 0;
@ -121,4 +157,11 @@ public class ZipXmlThemeResourceProvider implements XmlThemeResourceProvider {
}
return bytes;
}
private static String zipEntryName(String name) {
if (name.startsWith("/")) {
return name.substring(1);
}
return name;
}
}