package org.holoeverywhere.resbuilder.type.strings;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
public class Grabber {
private static final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
public static Grabber grabber(File resFolder) {
return new Grabber(resFolder);
}
private final Map<String, Map<String, String>> data = new TreeMap<String, Map<String, String>>(
TypeStrings.COMPARATOR);
private final Map<String, File> fileMap = new HashMap<String, File>();
private final File resFolder;
public final Map<File, Map<String, String>> translateCache = new HashMap<File, Map<String, String>>();
private Grabber(File resFolder) {
this.resFolder = resFolder;
fillFileMap();
}
private void fillFileMap() {
for (File file : resFolder.listFiles()) {
if (!file.isDirectory()) {
continue;
}
String locale = null, dirName = file.getName();
if (dirName.contentEquals("values")) {
locale = "en";
} else if (dirName.startsWith("values-")) {
// en-rUS -> en_US
locale = dirName.substring(7).replace("-r", "_");
if (locale.length() == 5) {
if (locale.charAt(2) != '_') {
locale = null; // != en_US
}
} else if (locale.length() != 2) {
locale = null; // != en
}
}
file = new File(file, "strings.xml");
if (locale != null && file.exists()) {
fileMap.put(locale, file);
}
}
}
public Map<String, Map<String, String>> getData() {
return data;
}
public void grab(String name) {
if (name == null || name.length() == 0) {
return;
}
for (Entry<String, File> entry : fileMap.entrySet()) {
final String locale = entry.getKey(), translate = grab(name, entry.getValue());
if (translate != null) {
Map<String, String> map = data.get(locale);
if (map == null) {
map = new TreeMap<String, String>(TypeStrings.COMPARATOR);
data.put(locale, map);
}
map.put(name, translate);
}
}
}
public void grab(String... names) {
for (String name : names) {
grab(name);
}
}
protected String grab(String name, File file) {
Map<String, String> cache = translateCache.get(file);
if (cache == null) {
cache = parse(file);
translateCache.put(file, cache);
}
return cache.get(name);
}
private Map<String, String> parse(File file) {
try {
Map<String, String> map = new HashMap<String, String>();
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(
new FileInputStream(file),
"utf-8");
String name = null;
StringBuilder builder = null;
int type, depth = 0;
while (reader.hasNext()) {
type = reader.next();
switch (type) {
case XMLStreamConstants.START_ELEMENT:
if (builder != null) {
depth++;
}
if (!"string".equals(reader.getLocalName())) {
continue;
}
name = reader.getAttributeValue(null, "name");
if (name == null || name.length() == 0) {
name = null;
continue;
}
builder = new StringBuilder();
depth = 0;
break;
case XMLStreamConstants.CHARACTERS:
if (builder != null) {
builder.append(reader.getText());
}
break;
case XMLStreamConstants.END_ELEMENT:
if (builder != null && depth-- == 0) {
map.put(name, builder.toString());
name = null;
builder = null;
}
break;
}
}
return map;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public synchronized void reset() {
data.clear();
translateCache.clear();
}
}