mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 02:44:50 +00:00
Changed bundled resources to use static base name instead.
Added options menu with selectable language
This commit is contained in:
@@ -158,6 +158,7 @@ public class ResourceLoader {
|
||||
Map<String, BundledResource> bundledResources = new HashMap<>();
|
||||
|
||||
for (File file : files) {
|
||||
boolean skipAdd = false;
|
||||
BaseResource resource = resourceMapper(file, BaseResource.class);
|
||||
switch (resource) {
|
||||
case null -> {
|
||||
@@ -165,13 +166,11 @@ public class ResourceLoader {
|
||||
}
|
||||
case BundledResource br -> {
|
||||
String key = resource.getClass().getName() + ":" + br.getBaseName();
|
||||
if (bundledResources.containsKey(key)) {
|
||||
bundledResources.get(key).loadFile(file);
|
||||
resource = (BaseResource) bundledResources.get(key);
|
||||
} else {
|
||||
br.loadFile(file);
|
||||
bundledResources.put(key, br);
|
||||
}
|
||||
if (!bundledResources.containsKey(key)) {bundledResources.put(key, br);}
|
||||
bundledResources.get(key).loadFile(file);
|
||||
resource = (BaseResource) bundledResources.get(key);
|
||||
assets.add(new ResourceMeta<>(br.getBaseName(), resource));
|
||||
skipAdd = true;
|
||||
}
|
||||
case PreloadResource pr -> pr.load();
|
||||
default -> {
|
||||
@@ -181,7 +180,7 @@ public class ResourceLoader {
|
||||
BaseResource finalResource = resource;
|
||||
boolean alreadyAdded = assets.stream()
|
||||
.anyMatch(a -> a.getResource() == finalResource);
|
||||
if (!alreadyAdded) {
|
||||
if (!alreadyAdded && !skipAdd) {
|
||||
assets.add(new ResourceMeta<>(file.getName(), resource));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,33 +8,90 @@ import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a localization resource asset that loads and manages property files
|
||||
* containing key-value pairs for different locales.
|
||||
* <p>
|
||||
* This class implements {@link LoadableResource} to support loading/unloading
|
||||
* and {@link BundledResource} to represent resources that can contain multiple
|
||||
* localized bundles.
|
||||
* </p>
|
||||
* <p>
|
||||
* Files handled by this class must have the {@code .properties} extension,
|
||||
* optionally with a locale suffix, e.g., {@code messages_en_US.properties}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Example usage:
|
||||
* <pre>{@code
|
||||
* LocalizationAsset asset = new LocalizationAsset(new File("messages_en_US.properties"));
|
||||
* asset.load();
|
||||
* String greeting = asset.getString("hello", Locale.US);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
@FileExtension({"properties"})
|
||||
public class LocalizationAsset extends BaseResource implements LoadableResource, BundledResource {
|
||||
private final Map<Locale, ResourceBundle> bundles = new HashMap<>();
|
||||
private boolean isLoaded = false;
|
||||
private final Locale fallback = Locale.forLanguageTag("");
|
||||
|
||||
/** Map of loaded resource bundles, keyed by locale. */
|
||||
private final Map<Locale, ResourceBundle> bundles = new HashMap<>();
|
||||
|
||||
/** Flag indicating whether this asset has been loaded. */
|
||||
private boolean isLoaded = false;
|
||||
|
||||
/** Basename of the given asset */
|
||||
private final String baseName = "localization";
|
||||
|
||||
/** Fallback locale used when no matching locale is found. */
|
||||
private final Locale fallback = Locale.forLanguageTag("en_US");
|
||||
|
||||
/**
|
||||
* Constructs a new LocalizationAsset for the specified file.
|
||||
*
|
||||
* @param file the property file to load
|
||||
*/
|
||||
public LocalizationAsset(File file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the resource file into memory and prepares localized bundles.
|
||||
*/
|
||||
@Override
|
||||
public void load() {
|
||||
loadFile(getFile());
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads all loaded resource bundles, freeing memory.
|
||||
*/
|
||||
@Override
|
||||
public void unload() {
|
||||
bundles.clear();
|
||||
isLoaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this asset has been loaded.
|
||||
*
|
||||
* @return {@code true} if the asset is loaded, {@code false} otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a localized string for the given key and locale.
|
||||
* If an exact match for the locale is not found, a fallback
|
||||
* matching the language or the default locale will be used.
|
||||
*
|
||||
* @param key the key of the string
|
||||
* @param locale the desired locale
|
||||
* @return the localized string
|
||||
* @throws MissingResourceException if no resource bundle is available for the locale
|
||||
*/
|
||||
public String getString(String key, Locale locale) {
|
||||
Locale target = findBestLocale(locale);
|
||||
ResourceBundle bundle = bundles.get(target);
|
||||
@@ -43,6 +100,13 @@ public class LocalizationAsset extends BaseResource implements LoadableResource,
|
||||
return bundle.getString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the best matching locale among loaded bundles.
|
||||
* Prefers an exact match, then language-only match, then fallback.
|
||||
*
|
||||
* @param locale the desired locale
|
||||
* @return the best matching locale
|
||||
*/
|
||||
private Locale findBestLocale(Locale locale) {
|
||||
if (bundles.containsKey(locale)) return locale;
|
||||
for (Locale l : bundles.keySet()) {
|
||||
@@ -51,13 +115,24 @@ public class LocalizationAsset extends BaseResource implements LoadableResource,
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable set of all locales for which bundles are loaded.
|
||||
*
|
||||
* @return available locales
|
||||
*/
|
||||
public Set<Locale> getAvailableLocales() {
|
||||
return Collections.unmodifiableSet(bundles.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specific property file as a resource bundle.
|
||||
* The locale is extracted from the file name if present.
|
||||
*
|
||||
* @param file the property file to load
|
||||
* @throws RuntimeException if the file cannot be read
|
||||
*/
|
||||
@Override
|
||||
public void loadFile(File file) {
|
||||
String baseName = getBaseName(file.getName());
|
||||
try (InputStreamReader reader =
|
||||
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
|
||||
Locale locale = extractLocale(file.getName(), baseName);
|
||||
@@ -68,20 +143,40 @@ public class LocalizationAsset extends BaseResource implements LoadableResource,
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base name of the underlying file (without locale or extension).
|
||||
*
|
||||
* @return the base name
|
||||
*/
|
||||
@Override
|
||||
public String getBaseName() {
|
||||
return getBaseName(getFile().getName());
|
||||
return this.baseName;
|
||||
}
|
||||
|
||||
private String getBaseName(String fileName) {
|
||||
int underscoreIndex = fileName.indexOf('_');
|
||||
int dotIndex = fileName.lastIndexOf('.');
|
||||
if (underscoreIndex > 0) {
|
||||
return fileName.substring(0, underscoreIndex);
|
||||
}
|
||||
return fileName.substring(0, dotIndex);
|
||||
}
|
||||
// /**
|
||||
// * Extracts the base name from a file name.
|
||||
// *
|
||||
// * @param fileName the file name
|
||||
// * @return base name without locale or extension
|
||||
// */
|
||||
// private String getBaseName(String fileName) {
|
||||
// int dotIndex = fileName.lastIndexOf('.');
|
||||
// String nameWithoutExtension = (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName;
|
||||
//
|
||||
// int underscoreIndex = nameWithoutExtension.indexOf('_');
|
||||
// if (underscoreIndex > 0) {
|
||||
// return nameWithoutExtension.substring(0, underscoreIndex);
|
||||
// }
|
||||
// return nameWithoutExtension;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Extracts a locale from a file name based on the pattern "base_LOCALE.properties".
|
||||
*
|
||||
* @param fileName the file name
|
||||
* @param baseName the base name
|
||||
* @return extracted locale, or fallback if none found
|
||||
*/
|
||||
private Locale extractLocale(String fileName, String baseName) {
|
||||
int underscoreIndex = fileName.indexOf('_');
|
||||
int dotIndex = fileName.lastIndexOf('.');
|
||||
|
||||
@@ -66,4 +66,9 @@ public interface BundledResource {
|
||||
* @return the base name used to identify this bundled resource
|
||||
*/
|
||||
String getBaseName();
|
||||
|
||||
// /**
|
||||
// Returns the name
|
||||
// */
|
||||
// String getDefaultName();
|
||||
}
|
||||
Reference in New Issue
Block a user