package com.brightgenerous.lang;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Map;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.brightgenerous.commons.ResourceUtils;
import com.brightgenerous.commons.StringUtils;
class ChainPropertyResourceBundle extends PropertyResourceBundle {
public ChainPropertyResourceBundle(InputStream stream, String parentKey) throws IOException {
this(stream, parentKey, null);
}
protected ChainPropertyResourceBundle(InputStream stream, String parentKey, Set<String> parents)
throws IOException {
super(stream);
if (parentKey != null) {
String value = null;
if (containsKey(parentKey)) {
value = getString(parentKey);
}
if (StringUtils.isNotEmpty(value)) {
ResourceBundle parent = createFromPath(value, parentKey, parents);
if (parent != null) {
setParent(parent);
}
}
}
}
public ChainPropertyResourceBundle(Reader reader, String parentKey) throws IOException {
this(reader, parentKey, null);
}
protected ChainPropertyResourceBundle(Reader reader, String parentKey, Set<String> parents)
throws IOException {
super(reader);
if (parentKey != null) {
String value = null;
if (containsKey(parentKey)) {
value = getString(parentKey);
}
if (StringUtils.isNotEmpty(value)) {
ResourceBundle parent = createFromPath(value, parentKey, parents);
if (parent != null) {
setParent(parent);
}
}
}
}
private static final Map<String, WeakReference<ResourceBundle>> cache = new ConcurrentHashMap<>();
protected static ResourceBundle createFromPath(String path, String parentKey,
Set<String> parents) throws IOException {
if (path == null) {
return null;
}
if ((parents != null) && parents.contains(path)) {
return null;
}
ResourceBundle ret = null;
{
WeakReference<ResourceBundle> wr = cache.get(path);
if (wr != null) {
ret = wr.get();
if (ret == null) {
cache.remove(path);
}
}
}
if (ret == null) {
synchronized (cache) {
{
WeakReference<ResourceBundle> wr = cache.get(path);
if (wr != null) {
ret = wr.get();
if (ret == null) {
cache.remove(path);
}
}
}
if (ret == null) {
if (parents == null) {
parents = new HashSet<>();
} else {
parents = new HashSet<>(parents);
}
parents.add(path);
ret = new ChainPropertyResourceBundle(ResourceUtils.getInputStream(path),
parentKey, parents);
cache.put(path, new WeakReference<>(ret));
}
}
}
return ret;
}
}