Fix ResourceBundle.getBundle in case of .properties resource

This commit is contained in:
Alexey Andreev 2017-11-10 15:49:09 +03:00
parent e2225941f8
commit e1c7acd8a1
2 changed files with 36 additions and 30 deletions

View File

@ -20,6 +20,7 @@ import static org.teavm.metaprogramming.Metaprogramming.exit;
import static org.teavm.metaprogramming.Metaprogramming.findClass; import static org.teavm.metaprogramming.Metaprogramming.findClass;
import static org.teavm.metaprogramming.Metaprogramming.getClassLoader; import static org.teavm.metaprogramming.Metaprogramming.getClassLoader;
import static org.teavm.metaprogramming.Metaprogramming.lazy; import static org.teavm.metaprogramming.Metaprogramming.lazy;
import static org.teavm.metaprogramming.Metaprogramming.lazyFragment;
import static org.teavm.metaprogramming.Metaprogramming.proxy; import static org.teavm.metaprogramming.Metaprogramming.proxy;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
@ -31,12 +32,12 @@ import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.ListResourceBundle;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.teavm.classlib.java.util.TListResourceBundle;
import org.teavm.classlib.java.util.TResourceBundle;
import org.teavm.metaprogramming.CompileTime; import org.teavm.metaprogramming.CompileTime;
import org.teavm.metaprogramming.Meta; import org.teavm.metaprogramming.Meta;
import org.teavm.metaprogramming.ReflectClass; import org.teavm.metaprogramming.ReflectClass;
@ -49,7 +50,7 @@ public class ResourceBundleImpl {
} }
@Meta @Meta
public static native Map<String, Supplier<TResourceBundle>> createBundleMap(boolean b); public static native Map<String, Supplier<ResourceBundle>> createBundleMap(boolean b);
private static void createBundleMap(Value<Boolean> b) throws IOException { private static void createBundleMap(Value<Boolean> b) throws IOException {
ClassLoader loader = getClassLoader(); ClassLoader loader = getClassLoader();
@ -73,26 +74,29 @@ public class ResourceBundleImpl {
} }
} }
Value<Map<String, Supplier<TResourceBundle>>> result = emit(() -> new HashMap<>()); Value<Map<String, Supplier<ResourceBundle>>> result = emit(() -> new HashMap<>());
for (String implementation : implementations) { for (String implementation : implementations) {
String path = implementation.replace('.', '/'); String path = implementation.replace('.', '/');
ReflectClass<?> cls = findClass(implementation); ReflectClass<?> cls = findClass(implementation);
Value<? extends TResourceBundle> lazyResource; Value<? extends ResourceBundle> lazyResource;
if (cls != null) { if (cls != null) {
ReflectMethod constructor = cls.getMethod("<init>"); ReflectMethod constructor = cls.getMethod("<init>");
if (constructor != null) { if (constructor != null) {
lazyResource = lazy(() -> (TResourceBundle) constructor.construct()); lazyResource = lazy(() -> (ResourceBundle) constructor.construct());
} else { } else {
continue; continue;
} }
} else if (loader.getResource(path + ".properties") != null) { } else if (loader.getResource(path + ".properties") != null) {
lazyResource = lazyFragment(() -> {
Properties properties = new Properties(); Properties properties = new Properties();
try (InputStream input = loader.getResourceAsStream(path + ".properties")) { try (InputStream input = loader.getResourceAsStream(path + ".properties")) {
properties.load(input); properties.load(input);
} catch (IOException e) {
// do nothing
} }
lazyResource = lazy(() -> proxy(TListResourceBundle.class, (instance, methodName, args) -> { return proxy(ListResourceBundle.class, (instance, methodName, args) -> {
Value<List<Object[]>> contentsBuilder = emit(() -> new ArrayList<>()); Value<List<Object[]>> contentsBuilder = emit(() -> new ArrayList<>());
for (Object propertyName : properties.keySet()) { for (Object propertyName : properties.keySet()) {
if (!(propertyName instanceof String)) { if (!(propertyName instanceof String)) {
@ -108,7 +112,8 @@ public class ResourceBundleImpl {
} }
exit(() -> contentsBuilder.get().toArray(new Object[0][])); exit(() -> contentsBuilder.get().toArray(new Object[0][]));
}).get()); });
});
} else { } else {
continue; continue;
} }
@ -119,7 +124,7 @@ public class ResourceBundleImpl {
exit(() -> lazyResource.get()); exit(() -> lazyResource.get());
}); });
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Value<Supplier<TResourceBundle>> supplierValue = emit(() -> supplierValueRaw.get()); Value<Supplier<ResourceBundle>> supplierValue = emit(() -> supplierValueRaw.get());
emit(() -> result.get().put(implementation, supplierValue.get())); emit(() -> result.get().put(implementation, supplierValue.get()));
} }

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.teavm.classlib.impl.ResourceBundleImpl; import org.teavm.classlib.impl.ResourceBundleImpl;
@ -47,7 +48,7 @@ public abstract class TResourceBundle {
private static final Map<String, TResourceBundle> cache = new HashMap<>(); private static final Map<String, TResourceBundle> cache = new HashMap<>();
private static final Map<String, Supplier<TResourceBundle>> bundleProviders = private static final Map<String, Supplier<ResourceBundle>> bundleProviders =
ResourceBundleImpl.createBundleMap(false); ResourceBundleImpl.createBundleMap(false);
public TResourceBundle() { public TResourceBundle() {
@ -160,8 +161,8 @@ public abstract class TResourceBundle {
return result; return result;
} }
Supplier<TResourceBundle> provider = bundleProviders.get(bundleName); Supplier<ResourceBundle> provider = bundleProviders.get(bundleName);
bundle = provider != null ? provider.get() : null; bundle = provider != null ? (TResourceBundle) (Object) provider.get() : null;
String extension = strip(locale); String extension = strip(locale);
if (bundle != null) { if (bundle != null) {