there is a boring task, boss let me check multiple strings.xml files to find the differences compare to res/values/strings.xml. Jesus christ! It's 33 kinds of languages in android. I do not want work like a idiot. so, I wrote a program to solve that stupid task.
here is my code.
package com.jack.filter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*********************************V_I_2016-4-19 12:06:35************************************************************
* 不能在安卓項目中使用!!!!
* 思路:
* 給定一個res路徑,遍歷讀取以values-開頭的目錄存到集合中
* 讀取目錄下的strings.xml文件,將數據轉爲鍵值對HashMap<String,String> source---("XXX","<string name="XXX">ZZZZ</string>");
* 遍歷values/strings.xml默認文件,逐行讀取String readLine,同時聲明一個List<String> tem;
* 如果該行爲<string name="XXX">ZZZZ</string>則提取鍵XXX,如果匹配到source則tem.add(source.get(key));
* 如果該行沒有key(註釋)或者XML文件頭,或者沒有匹配的則直接tem.add(readLine);
*
* 注意事項:
* 不能在安卓項目中使用! 需要新建一個Java project運行,導入的包全爲java.nio.* 下的子類
* 如果報錯則添加JRE Library
*
*****************************V_II_2016-5-10 9:45:04****************************************************************
*
* V_II : 修改BUG(1.string有多行) 新加非匹配型(有些其他語言不需要,只使用一個默認即可)
*
*
* ****************************V_III_2016-8-9 10:26:04****************************************************************
* V_III : 修改BUG(1.註釋的順序放錯了)
*
* @author jack
* last-modify : 2016-8-9 10:26:04
*/
public class StringsFileUtil {
/**
* @param resFileDir = E:\\workspace\\TimeSheet\\res
* @param defaultFilePath = E:\\workspace\\TimeSheet\\res\\values\\strings.xml
* @param unchangeKey 不需要多語言的項
* @throws IOException
*/
public void tidyFiles(String resFileDir, String defaultFilePath, final List<String> unchangeKey) throws IOException {
final Path path = Paths.get(resFileDir);
final Path dataPath = Paths.get(defaultFilePath);
final List<String> sequence = new ArrayList<>();
final Map<String, Item> data = prepareData(dataPath, sequence);
Path absPath = path.toAbsolutePath();
Files.walkFileTree(absPath, new FileVisitor<Path>() {
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (dir.getName(dir.getNameCount() - 1).toString().startsWith("values-")) {
return FileVisitResult.CONTINUE;
} else if (dir.equals(path)) {
return FileVisitResult.CONTINUE;
}
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.toString().endsWith("strings.xml")) {
new TransferThread(sequence, data, file, unchangeKey).start();
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
public Map<String, Item> prepareData(Path path, List<String> sequence) throws IOException {
List<String> lines = Files.readAllLines(path, Charset.forName("utf-8"));
String key = null;
Item value = null;
int i = 1;
List<String> values = null;
Map<String, Item> result = new HashMap<>();
for (String line : lines) {
boolean isStart = line.contains("<string name=");
boolean isEnd = line.contains("</string>");
if (!isStart && !isEnd) {
if (values != null) {
values.add(line);
continue;
} else {
key = "jack" + i++;
value = new Item();
value.value = line;
}
} else if (isStart && isEnd) {
key = line.split("\"")[1];
value = new Item();
value.value = line;
} else if (isStart && !isEnd) {
key = line.split("\"")[1];
value = new Item();
values = new ArrayList<>();
values.add(line);
continue;
} else if (!isStart && isEnd) {
if (value != null && key != null) {
values.add(line);
value.values = values;
}
}
if(sequence!=null) sequence.add(key);
result.put(key, value);
key = null;
value = null;
values = null;
}
return result;
}
class Item {
String value; //single line
List<String> values; //multiply lines
public Item() {
value = null;
values = null;
}
}
class TransferThread extends Thread {
private List<String> sequence;
private Map<String, Item> data;
private Path path;
private List<String> unchangeKey;
public TransferThread(List<String> sequence, Map<String, Item> data, Path path, List<String> unchangeKey) {
this.sequence = sequence;
this.data = data;
this.path = path;
this.unchangeKey = unchangeKey;
}
@Override
public void run() {
Map<String, Item> source;
try {
source = prepareData(path, null);
List<String> tem = new ArrayList<>();
for (int i=0;i<sequence.size();i++){
String key = sequence.get(i);
if(unchangeKey!=null && unchangeKey.contains(key)) continue;
if(key.startsWith("jack")) addToList(tem, data.get(key));
else addToList(tem, source.get(key));
}
Files.write(path, tem, Charset.forName("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("------finish-----" + path);
}
private void addToList(List<String> tem, Item item) {
if (item.value != null ) {
tem.add(item.value);
} else if(item.values!=null){
tem.addAll(item.values);
}
}
}
public static void main(String[] args) throws IOException {
String resFileDir = "E:\\workspace_temp\\WnOPOS_V1\\app\\src\\main\\res";
String defaultFilePath = "E:\\workspace_temp\\WnOPOS_V1\\app\\src\\main\\res\\values\\strings.xml";
List<String> unchangeKey = new ArrayList<>();
unchangeKey.add("app_name");
unchangeKey.add("admin");
new StringsFileUtil().tidyFiles(resFileDir, defaultFilePath,unchangeKey);
}
}
I'm fish, I'm on.