de.saxsys.mvvmfx.internal.viewloader.ResourceBundleManager Maven / Gradle / Ivy
package de.saxsys.mvvmfx.internal.viewloader;
import eu.lestard.doc.Internal;
import sun.util.ResourceBundleEnumeration;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.Set;
/**
* @author manuel.mauky
*/
@Internal
public class ResourceBundleManager {
private static final ResourceBundleManager SINGLETON = new ResourceBundleManager();
private ResourceBundle globalResourceBundle;
ResourceBundleManager() {
}
public static ResourceBundleManager getInstance() {
return SINGLETON;
}
public void setGlobalResourceBundle(ResourceBundle resourceBundle) {
this.globalResourceBundle = resourceBundle;
}
public ResourceBundle getGlobalResourceBundle() {
return globalResourceBundle;
}
/**
* Merges the provided ResourceBundle with the global one (if any).
*
* The global resourceBundle has a lower priority then the provided one. If there is the same key defined in the
* global and the provided resourceBundle, the value from the provided resourceBundle will be used.
*
* @param resourceBundle
* a resourceBundle that will be merged.
* @return the merged resourceBundle or null, if there is no global resource bundle and not given resource bundle.
*/
public ResourceBundle mergeWithGlobal(ResourceBundle resourceBundle) {
if (globalResourceBundle == null) {
if (resourceBundle == null) {
return createEmptyBundle();
} else {
return new ResourceBundleWrapper(resourceBundle);
}
} else {
if (resourceBundle == null) {
return new ResourceBundleWrapper(globalResourceBundle);
} else {
return merge(resourceBundle, globalResourceBundle);
}
}
}
private ResourceBundle merge(ResourceBundle highPriority, ResourceBundle lowPriority) {
return new MergedResourceBundle(highPriority, lowPriority);
}
private static class MergedResourceBundle extends ResourceBundle {
private ResourceBundle highPriority;
private ResourceBundle lowPriority;
public MergedResourceBundle(ResourceBundle highPriority, ResourceBundle lowPriority) {
Objects.nonNull(highPriority);
Objects.nonNull(lowPriority);
this.highPriority = highPriority;
this.lowPriority = lowPriority;
}
@Override
protected Object handleGetObject(String key) {
if (highPriority.containsKey(key)) {
return highPriority.getObject(key);
}
if (lowPriority.containsKey(key)) {
return lowPriority.getObject(key);
}
return null;
}
@Override
public Enumeration getKeys() {
return new MergedEnumeration(highPriority.keySet(), lowPriority.keySet());
}
}
private static class MergedEnumeration implements Enumeration {
final Iterator iterator;
public MergedEnumeration(Set highPriority, Set lowPriority) {
Set allElements = new HashSet<>();
allElements.addAll(highPriority);
allElements.addAll(lowPriority);
iterator = allElements.iterator();
}
@Override
public boolean hasMoreElements() {
return iterator.hasNext();
}
@Override
public String nextElement() {
return iterator.next();
}
}
/**
* This wrapper is needed due to a bug in FXMLLoader (https://javafx-jira.kenai.com/browse/RT-33764).
*
* With this class we make sure that there is a classLoader defined for this class.
*/
private static class ResourceBundleWrapper extends ResourceBundle {
private final ResourceBundle bundle;
ResourceBundleWrapper(ResourceBundle bundle) {
this.bundle = bundle;
}
@Override
protected Object handleGetObject(String key) {
return bundle.getObject(key);
}
@Override
public Enumeration getKeys() {
return bundle.getKeys();
}
@Override
public boolean containsKey(String key) {
return bundle.containsKey(key);
}
@Override
public Locale getLocale() {
return bundle.getLocale();
}
@Override
public Set keySet() {
return bundle.keySet();
}
}
private ResourceBundle createEmptyBundle() {
return new ListResourceBundle() {
@Override
protected Object[][] getContents() {
return new Object[0][];
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy