1
0
Fork 0

added an AssetFile class for easier asset management

This commit is contained in:
sspanak 2024-11-13 10:51:46 +02:00 committed by Dimo Karaivanov
parent d20ca80de4
commit 9c9dd489fc
6 changed files with 96 additions and 61 deletions

View file

@ -18,14 +18,13 @@ import java.util.zip.ZipInputStream;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.AssetFile;
import io.github.sspanak.tt9.util.Logger;
public class WordFile {
public class WordFile extends AssetFile {
private static final String LOG_TAG = WordFile.class.getSimpleName();
private final AssetManager assets;
private final Context context;
private final String path;
private int lastCharCode;
private BufferedReader reader;
@ -38,9 +37,8 @@ public class WordFile {
public WordFile(Context context, String path, AssetManager assets) {
this.assets = assets;
super(assets, path);
this.context = context;
this.path = path;
lastCharCode = 0;
reader = null;
@ -64,16 +62,6 @@ public class WordFile {
}
public boolean exists() {
try {
assets.open(path).close();
return true;
} catch (IOException e) {
return false;
}
}
public InputStream getRemoteStream() throws IOException {
URLConnection connection = new URL(getDownloadUrl()).openConnection();
connection.setConnectTimeout(SettingsStore.DICTIONARY_DOWNLOAD_CONNECTION_TIMEOUT);
@ -87,7 +75,7 @@ public class WordFile {
return reader;
}
InputStream stream = exists() ? assets.open(path) : getRemoteStream();
InputStream stream = exists() ? getStream() : getRemoteStream();
ZipInputStream zipStream = new ZipInputStream(stream);
ZipEntry entry = zipStream.getNextEntry();
if (entry == null) {

View file

@ -7,15 +7,14 @@ import androidx.annotation.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import io.github.sspanak.tt9.BuildConfig;
import io.github.sspanak.tt9.util.AssetFile;
import io.github.sspanak.tt9.util.Logger;
public class LanguageDefinition {
public class LanguageDefinition extends AssetFile {
private static final String languagesDir = "languages";
private static final String definitionsDir = languagesDir + "/definitions";
@ -28,6 +27,11 @@ public class LanguageDefinition {
public String name = "";
public LanguageDefinition(AssetManager assets, String name) {
super(assets, definitionsDir + "/" + name);
}
/**
* getAllFiles
* Returns a list of the paths of all language definition files in the assets folder or an empty list on error.
@ -35,10 +39,7 @@ public class LanguageDefinition {
public static ArrayList<String> getAllFiles(AssetManager assets) {
ArrayList<String> files = new ArrayList<>();
try {
for (String file : assets.list(definitionsDir)) {
files.add(definitionsDir + "/" + file);
}
files.addAll(Arrays.asList(assets.list(definitionsDir)));
Logger.d("LanguageDefinition", "Found: " + files.size() + " languages.");
} catch (IOException | NullPointerException e) {
Logger.e("tt9.LanguageDefinition", "Failed reading language definitions from: '" + definitionsDir + "'. " + e.getMessage());
@ -54,7 +55,9 @@ public class LanguageDefinition {
* or throws an IOException on error.
*/
public static LanguageDefinition fromFile(AssetManager assetManager, String definitionFile) throws IOException {
return parse(load(assetManager, definitionFile));
LanguageDefinition definition = new LanguageDefinition(assetManager, definitionFile);
definition.parse(definition.load(definition));
return definition;
}
@ -62,8 +65,8 @@ public class LanguageDefinition {
* load
* Loads a language definition file from the assets folder into a String or throws an IOException on error.
*/
private static ArrayList<String> load(AssetManager assetManager, String definitionFile) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(assetManager.open(definitionFile), StandardCharsets.UTF_8));
private ArrayList<String> load(LanguageDefinition definitionFile) throws IOException {
BufferedReader reader = definitionFile.getReader();
ArrayList<String> fileContents = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
@ -78,26 +81,25 @@ public class LanguageDefinition {
* parse
* Converts "yaml" to a LanguageDefinition object. All properties in the YAML are considered optional,
* so the LanguageDefinition defaults will be used when some property is omitted.
*
* Had to write all this, because the only usable library, SnakeYAML, works fine on Android 10+,
* but causes crashes on older devices.
*/
@NonNull
private static LanguageDefinition parse(ArrayList<String> yaml) {
LanguageDefinition definition = new LanguageDefinition();
definition.abcString = getPropertyFromYaml(yaml, "abcString", definition.abcString);
definition.dictionaryFile = getPropertyFromYaml(yaml, "dictionaryFile", definition.dictionaryFile);
definition.hasSpaceBetweenWords = getPropertyFromYaml(yaml, "hasSpaceBetweenWords", definition.hasSpaceBetweenWords);
definition.hasUpperCase = getPropertyFromYaml(yaml, "hasUpperCase", definition.hasUpperCase);
definition.layout = getLayoutFromYaml(yaml);
definition.locale = getPropertyFromYaml(yaml, "locale", definition.locale);
definition.name = getPropertyFromYaml(yaml, "name", definition.name);
private void parse(ArrayList<String> yaml) {
abcString = getPropertyFromYaml(yaml, "abcString", abcString);
if (definition.dictionaryFile != null) {
definition.dictionaryFile = definition.dictionaryFile.replaceFirst("\\.\\w+$", "." + BuildConfig.DICTIONARY_EXTENSION);
dictionaryFile = getPropertyFromYaml(yaml, "dictionaryFile", dictionaryFile);
if (dictionaryFile != null) {
dictionaryFile = dictionaryFile.replaceFirst("\\.\\w+$", "." + BuildConfig.DICTIONARY_EXTENSION);
}
return definition;
hasSpaceBetweenWords = getPropertyFromYaml(yaml, "hasSpaceBetweenWords", hasSpaceBetweenWords);
hasUpperCase = getPropertyFromYaml(yaml, "hasUpperCase", hasUpperCase);
layout = getLayoutFromYaml(yaml);
locale = getPropertyFromYaml(yaml, "locale", locale);
name = getPropertyFromYaml(yaml, "name", name);
}
@ -107,7 +109,7 @@ public class LanguageDefinition {
* Optional properties are allowed. If the property is not found, "defaultValue" will be returned.
*/
@Nullable
private static String getPropertyFromYaml(ArrayList<String> yaml, String property, String defaultValue) {
private String getPropertyFromYaml(ArrayList<String> yaml, String property, String defaultValue) {
for (String line : yaml) {
line = line.replaceAll("#.+$", "").trim();
String[] parts = line.split(":");
@ -128,7 +130,7 @@ public class LanguageDefinition {
* The boolean variant of getPropertyFromYaml. It returns true if the property is found and is:
* "true", "on", "yes" or "y".
*/
private static boolean getPropertyFromYaml(ArrayList<String> yaml, String property, boolean defaultValue) {
private boolean getPropertyFromYaml(ArrayList<String> yaml, String property, boolean defaultValue) {
String value = getPropertyFromYaml(yaml, property, null);
if (value == null) {
return defaultValue;
@ -144,7 +146,7 @@ public class LanguageDefinition {
* Finds and extracts the keypad layout. Less than 10 keys are accepted allowed leaving the ones up to 9-key empty.
*/
@NonNull
private static ArrayList<ArrayList<String>> getLayoutFromYaml(ArrayList<String> yaml) {
private ArrayList<ArrayList<String>> getLayoutFromYaml(ArrayList<String> yaml) {
ArrayList<ArrayList<String>> layout = new ArrayList<>();
boolean inLayout = false;
@ -174,7 +176,7 @@ public class LanguageDefinition {
* If the YAML line is invalid, NULL will be returned.
*/
@Nullable
private static ArrayList<String> getLayoutEntryFromYamlLine(String yamlLine) {
private ArrayList<String> getLayoutEntryFromYamlLine(String yamlLine) {
if (!yamlLine.contains("[") || !yamlLine.contains("]")) {
return null;
}

View file

@ -1,12 +1,7 @@
package io.github.sspanak.tt9.preferences;
import android.content.res.AssetManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import io.github.sspanak.tt9.ui.WebViewActivity;
import io.github.sspanak.tt9.util.Logger;
@ -21,8 +16,7 @@ public class HelpActivity extends WebViewActivity {
@Override
protected String getText() {
try {
InputStream stream = getHelpFileStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
BufferedReader reader = getHelpFileReader();
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
@ -35,14 +29,10 @@ public class HelpActivity extends WebViewActivity {
}
}
private InputStream getHelpFileStream() throws IOException {
AssetManager assets = getAssets();
private BufferedReader getHelpFileReader() throws IOException {
String systemLanguage = SystemSettings.getLocale().replaceFirst("_\\w+$", "");
try {
return assets.open("help/help." + systemLanguage + ".html");
} catch (IOException ignored) {
return assets.open("help/help.en.html");
}
HelpFile file = new HelpFile(this, systemLanguage);
file = file.exists() ? file : new HelpFile(this);
return file.getReader();
}
}

View file

@ -0,0 +1,17 @@
package io.github.sspanak.tt9.preferences;
import android.content.Context;
import androidx.annotation.NonNull;
import io.github.sspanak.tt9.util.AssetFile;
public class HelpFile extends AssetFile {
public HelpFile(@NonNull Context context, String language) {
super(context.getAssets(), "help/help." + language + ".html");
}
public HelpFile(@NonNull Context context) {
super(context.getAssets(), "help/help.en.html");
}
}

View file

@ -4,9 +4,9 @@ import androidx.preference.Preference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.HelpFile;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.screens.BaseScreenFragment;
import io.github.sspanak.tt9.util.SystemSettings;
@ -53,7 +53,7 @@ public class MainSettingsScreen extends BaseScreenFragment {
}
String systemLanguage = SystemSettings.getLocale().replaceAll("_\\w+$", "");
help.setSummary(Set.of("de", "en", "es", "it", "ru", "tr").contains(systemLanguage) ? "" : "English only");
help.setSummary(new HelpFile(activity, systemLanguage).exists() ? "" : "English only");
}

View file

@ -0,0 +1,38 @@
package io.github.sspanak.tt9.util;
import android.content.res.AssetManager;
import androidx.annotation.NonNull;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class AssetFile {
protected final AssetManager assets;
protected final String path;
public AssetFile(@NonNull AssetManager assets, String path) {
this.assets = assets;
this.path = path;
}
public boolean exists() {
try {
assets.open(path).close();
return true;
} catch (IOException e) {
return false;
}
}
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getStream(), StandardCharsets.UTF_8));
}
protected InputStream getStream() throws IOException {
return assets.open(path);
}
}