/*
Copyright (C) 2010 maik.jablonski@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package jfix.util;
import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class I18N {
private static ResourceBundle bundle;
static {
load(Locale.getDefault());
}
public static void load(Locale locale) {
bundle = new MessageBundle("META-INF.i18n.msg", locale);
}
public static String get(String key) {
if (key != null && bundle.containsKey(key)) {
return bundle.getString(key);
} else {
return key.replace("_", " ");
}
}
static private class MessageBundle extends ResourceBundle {
private String baseName;
private String packageName;
private Map<String, Object> messages;
protected MessageBundle(String resource, Locale locale) {
int idx = resource.lastIndexOf(".");
this.baseName = resource.substring(idx + 1);
this.packageName = resource.substring(0, idx);
loadBundles(locale);
}
public Object handleGetObject(String key) {
if (key == null) {
throw new NullPointerException();
}
return messages.get(key);
}
public Enumeration<String> getKeys() {
ResourceBundle parent = this.parent;
return new ResourceBundleEnumeration(messages.keySet(),
(parent != null) ? parent.getKeys() : null);
}
private void loadBundles(Locale locale) {
messages = new HashMap<String, Object>();
for (String bundleName : getBundleNames(baseName)) {
ResourceBundle bundle = ResourceBundle.getBundle(bundleName,
locale);
Enumeration<String> keys = bundle.getKeys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
messages.put(key, bundle.getObject(key));
}
}
}
private List<String> getBundleNames(String baseName) {
List<String> bundleNames = new ArrayList<String>();
try {
String baseFileName = baseName + ".properties";
String resourcePath = getResourcePath();
String resourceName = resourcePath + baseFileName;
Enumeration<URL> names = Thread.currentThread()
.getContextClassLoader().getResources(resourceName);
while (names.hasMoreElements()) {
URL jarUrl = names.nextElement();
String jarFile = URLDecoder.decode(jarUrl.getFile(), "UTF-8");
if ("jar".equals(jarUrl.getProtocol())) {
String filename = jarFile.substring(0, jarFile.length()
- resourceName.length() - 2);
if (filename.startsWith("file:")) {
filename = filename.substring(5);
}
JarFile jar = new JarFile(filename);
for (Enumeration<JarEntry> entries = jar.entries(); entries
.hasMoreElements();) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
addMatch("", baseName, bundleNames, baseFileName,
name);
}
} else {
File jarDirectory = new File(jarFile).getParentFile();
if (jarDirectory.isDirectory()) {
for (String name : jarDirectory.list()) {
addMatch(resourcePath, baseName, bundleNames,
baseFileName, name);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return bundleNames;
}
private String getResourcePath() {
String result = "";
if (packageName != null) {
result = packageName.replaceAll("\\.", "/") + "/";
}
return result;
}
private void addMatch(String resourcePath, String baseName,
List<String> bundleNames, String baseFileName, String name) {
int prefixed = name.indexOf(baseName);
if (prefixed > -1 && name.endsWith(baseFileName)) {
String toAdd = resourcePath + name.substring(0, prefixed)
+ baseName;
if (!bundleNames.contains(toAdd)) {
bundleNames.add(toAdd);
}
}
}
static private class ResourceBundleEnumeration implements
Enumeration<String> {
private Set<String> set;
private Iterator<String> iterator;
private Enumeration<String> enumeration;
private String next = null;
ResourceBundleEnumeration(Set<String> set,
Enumeration<String> enumeration) {
this.set = set;
this.iterator = set.iterator();
this.enumeration = enumeration;
}
public boolean hasMoreElements() {
if (next == null) {
if (iterator.hasNext()) {
next = iterator.next();
} else if (enumeration != null) {
while (next == null && enumeration.hasMoreElements()) {
next = enumeration.nextElement();
if (set.contains(next)) {
next = null;
}
}
}
}
return next != null;
}
public String nextElement() {
if (hasMoreElements()) {
String result = next;
next = null;
return result;
} else {
throw new NoSuchElementException();
}
}
}
}
}