WSO2 ESB / EI / AM 汉化方法
一、参考文章
最近看了文章 WSO2 ESB企业服务总线汉化源码分享和实现原理,想着能不能把 WSO2 EI 6.6.0 也给汉化了,看了这篇博客发现 ESB 和 EI 是一样的。整理了一下代码,重新写了使用百度翻译来翻译 WSO2 EI 6.6.0,同时增加了一些术语和常用词的翻译(原博客的代码使用的是谷歌翻译,该博客原源代码:updjarutils)。
百度翻译 API :百度翻译开放平台,普通版免费,但是 QPS 只有 1,高级版每月前一百万字符免费。
目前验证过使用该方法汉化后的 jar 包,WSO2 ESB 5.0.0、 WSO2 EI 6.6.0 和 WSO2 AM 4.0.0 可以正常运行
二、依赖
commons-codec-1.15.jar
commons-httpclient-3.1.jar
commons-logging-1.1.1.jar
fastjson-1.2.83.jar
log4j-1.2.17.jar
slf4j-api-1.7.30.jar
slf4j-log4j12-1.7.30.jar
三、代码
WSO2 EI 6.6.0 的 ui 包在 WSO2 EI 6.6.0 根目录下的 wso2ei_home\wso2\components\plugins
文件夹下
1、获取名称带有 ui 的 jar 文件列表和请求翻译 API
package com.yoodb.wso2ei;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.yoodb.wso2ei.util.LoadTerminology;
/**
* 解压jar包,读取jar包里的Resource.properties文件,读取到配置文件内容,请求百度翻译API,获取翻译后的内容
* 把翻译后的内容更新到Resource.properties文件,然后再把解压后的文件夹压缩成jar包
*
* @author mrwang
*
*/
public class UpdJarContent {
private static Logger log = LoggerFactory.getLogger(UpdJarContent.class);
public JSONObject updJarContent(SignUtils sign, FileOutputStream logfile, String... proName) throws Exception {
JSONObject tempJsonObject = new JSONObject();
if (!isExists(sign.getJarNewPath())) {
List<String> filePathlist = new ArrayList<String>();
HashMap<String, String> terminology = LoadTerminology.getTerminology();
for (int i = 0; i < proName.length; i++) {
Decompression.uncompress(new File(sign.getJarPath()), new File(sign.getFilePath()));
ArrayList<String> filelist = new ArrayList<String>();
getFiles(sign.getFilePath(), filelist);
for (String string : filelist) {
if (string.contains(proName[i])) {
logfile.write((string).getBytes());
logfile.write("\r\n".getBytes());
filePathlist.add(string);
Properties pro = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream(string));
pro.load(in);
Iterator<String> it = pro.stringPropertyNames().iterator();
FileOutputStream yfile = new FileOutputStream(string);
FileOutputStream originalfile = new FileOutputStream(
string.replace(proName[i], "original_file"));
pro.store(originalfile, "file update...");
while (it.hasNext()) {
String key = it.next();
String value = pro.getProperty(key);
log.info("key-->" + key + " value-->" + value);
String cntext = null;
if (terminology.containsKey(value.toLowerCase())) {
cntext = terminology.get(value.toLowerCase());
}
else {
try {
if (!isEmpty(value)) {
cntext = TranslateByBaiDuUtil.translate(value, TranslateByBaiDuUtil.ENGLISH, TranslateByBaiDuUtil.CHINA);
}
// Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
log.error(e.getMessage());
Thread.sleep(20000);
if (!isEmpty(value)) {
cntext = TranslateByBaiDuUtil.translate(value, TranslateByBaiDuUtil.ENGLISH, TranslateByBaiDuUtil.CHINA);
}
}
}
log.info("key-->" + key + " value-->" + cntext);
if (isEmpty(cntext)) {
pro.put(key, "");
} else {
pro.put(key, cntext);
}
if(!isEmpty(value) && !isEmpty(cntext)) {
tempJsonObject.put(value, cntext);
}
Thread.sleep(10);
}
pro.store(yfile, "file update...");
yfile.close();
originalfile.close();
in.close();
}
}
Compressor zc = new Compressor(sign.getJarNewPath());
zc.setOriginalUrl(sign.getOriginalUrl());
zc.compress(sign.getFilePath());
log.info("恭喜修改压缩文件成功!!!!,修改文件如下:");
for (String string : filePathlist) {
log.info("update file path is [" + string + "]");
}
log.info("翻译后的值:" + tempJsonObject.toJSONString());
}
} else {
log.info("jar包已经存在--->" + sign.getJarNewPath());
}
return tempJsonObject;
}
/**
* 将文件夹下所有文件存储
*
* @param filePath
* @param filelist
*/
public static ArrayList<String> getFiles(String filePath, ArrayList<String> filelist) {
File root = new File(filePath);
File[] files = root.listFiles();
for (File file : files) {
if (file.isDirectory()) {
getFiles(file.getAbsolutePath(), filelist);
} else {
filelist.add(file.getAbsolutePath());
}
}
return filelist;
}
/**
* 判断字符串是否为空
* @param string 输入字符串
* @return 为空返回true,不为空返回false
*/
public boolean isEmpty(String string) {
if (null == string || "".equals(string) || string.isEmpty() || string.length() == 0) {
return true;
} else {
return false;
}
}
/**
* 将文件夹下所有jar存储
*
* @param filePath
*/
public static ArrayList<File> searchJarFiles(String filePath) {
ArrayList<File> filelist = new ArrayList<File>();
File f = new File(filePath);
if (!f.exists()) {
log.info(filePath + " not exists");
return null;
}
File fa[] = f.listFiles();
for (int i = 0; i < fa.length; i++) {
File file = fa[i];
if (file.isDirectory()) {
log.info(file.getName() + " [目录]");
} else {
String path = file.getAbsolutePath();
if (path.contains("ui_") && path.contains(".jar") && !path.contains("_1.jar")) {
filelist.add(file);
}
if (path.indexOf("org.wso2.carbon.i18n") != -1) {
filelist.add(file);
}
}
}
return filelist;
}
public static void createFile(String path, String fileName) {
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
File file = new File(f, fileName);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static boolean isExists(String jarNewPath) {
File file = new File(jarNewPath);
if (file.exists()) {
return true;
} else {
return false;
}
}
}
2、解压 jar包
package com.yoodb.wso2ei;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 解压工具
*
* @author mrwang
*/
public class Decompression {
protected static Logger log = LoggerFactory.getLogger(Decompression.class);
@SuppressWarnings("resource")
public static void uncompress(File jarFile, File tarDir) throws IOException {
JarFile jfInst = new JarFile(jarFile);
Enumeration<JarEntry> enumEntry = jfInst.entries();
while (enumEntry.hasMoreElements()) {
JarEntry jarEntry = enumEntry.nextElement();
File tarFile = new File(tarDir, jarEntry.getName());
/*
* if(jarEntry.getName().contains("META-INF")){ File miFile = new File(tarDir,
* "META-INF"); if(!miFile.exists()){ miFile.mkdirs(); }
*
* }
*/
log.info("原文件路径 -->" + tarFile.getPath());
String path = tarFile.getPath().substring(0, tarFile.getPath().lastIndexOf("\\") + 1);
log.info("原文件所属目录 -->" + tarFile.getPath());
File file = new File(path);
if ((!file.exists() && !file.isDirectory())) {
file.mkdirs();
}
makeFile(jarEntry, tarFile);
if (jarEntry.isDirectory()) {
continue;
}
FileChannel fileChannel = new FileOutputStream(tarFile).getChannel();
InputStream ins = jfInst.getInputStream(jarEntry);
transferStream(ins, fileChannel);
}
}
/**
* 流交换操作
*
* @param ins
* 输入流
* @param channel
* 输出流
*/
private static void transferStream(InputStream ins, FileChannel channel) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 10);
ReadableByteChannel rbcInst = Channels.newChannel(ins);
try {
while (-1 != (rbcInst.read(byteBuffer))) {
byteBuffer.flip();
channel.write(byteBuffer);
byteBuffer.clear();
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (null != rbcInst) {
try {
rbcInst.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != channel) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 打印jar文件内容信息
*
* @param file
* jar文件
*/
public static void printJarEntry(File file) {
JarFile jfInst = null;
;
try {
jfInst = new JarFile(file);
} catch (IOException e) {
e.printStackTrace();
}
Enumeration<JarEntry> enumEntry = jfInst.entries();
while (enumEntry.hasMoreElements()) {
log.info(enumEntry.nextElement().toString());
}
}
/**
* 创建文件
*
* @param jarEntry
* jar实体
* @param fileInst
* 文件实体
* @throws IOException
* 抛出异常
*/
public static void makeFile(JarEntry jarEntry, File fileInst) {
if (!fileInst.exists()) {
if (jarEntry.isDirectory()) {
fileInst.mkdirs();
} else {
try {
fileInst.createNewFile();
} catch (IOException e) {
log.error("创建文件失败>>>".concat(fileInst.getPath()));
}
}
}
}
public static void main(String[] args) {
File jarFile = new File(
"D:\\WSO2 EI 6.6.0\\wso2ei-6.6.0\\wso2\\components\\plugins\\org.wso2.carbon.service.mgt.ui_4.9.15.jar");
File targetDir = new File("D:\\WSO2 EI 6.6.0\\org.wso2.carbon.service.mgt.ui_4.9.15");
try {
Decompression.uncompress(jarFile, targetDir);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、请求百度翻译 API
package com.yoodb.wso2ei;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
/**
* 翻译帮助工具 - 百度
*
* @author wxhntmy
*
*/
public class TranslateByBaiDuUtil {
private static Logger log = LoggerFactory.getLogger(TranslateByBaiDuUtil.class);
protected static final String URL_TEMPLATE = "https://fanyi-api.baidu.com/api/trans/vip/translate";
protected static final String APP_ID = "";
protected static final String APP_KEY = "";
protected static final String ENCODING = "UTF-8";
public static final String AUTO = "auto";
public static final String CHINA = "zh";
public static final String ENGLISH = "en";
public static final String JAPAN = "ja";
/**
* 百度自动判断识别语言体系
*
* @param text
* @param target_lang
* @return
* @throws Exception
*/
public static String translate(final String text, final String target_lang) throws Exception {
return translate(text, AUTO, target_lang);
}
/**
* 获取md5加密的字符串
*
* @param string 输入字符串
* @return 加密后的字符串
*/
private static String getMd5(String string) {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
byte[] md5Bytes = null;
try {
md5Bytes = md5.digest(string.getBytes("UTF8"));
} catch (UnsupportedEncodingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
String md5Str = "";
for (int i = 0; i < md5Bytes.length; i++) {
md5Str += Integer.toHexString(md5Bytes[i] | 0xFFFFFF00).substring(6);
}
return md5Str;
}
/**
* 百度翻译
*
* @param text
* @param src_lang
* @param target_lang
* @return
* @throws Exception
*/
public static String translate(final String text, final String src_lang, final String target_lang)
throws Exception {
String salt = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
String qString = URLEncoder.encode(text, ENCODING).replace("+", "%20");
String sign = APP_ID + text + salt + APP_KEY;
sign = getMd5(sign);
String urlString = "http://api.fanyi.baidu.com/api/trans/vip/translate?q=" + qString + "&from=" + src_lang
+ "&to=" + target_lang + "&appid=" + APP_ID + "&salt=" + salt + "&sign=" + sign;
//log.info("url:---->" + urlString);
String resultJson = RestMock.doGet(urlString);
JSONObject jsonObject = JSONObject.parseObject(resultJson);
//log.info("jsonObject:---->" + jsonObject.toJSONString());
JSONObject trans_result = jsonObject.containsKey("trans_result")?jsonObject.getJSONArray("trans_result").getJSONObject(0):new JSONObject();
String result = trans_result.containsKey("dst")?trans_result.getString("dst"):"";
log.info("dst:---->" + result);
return result;
}
/**
* 百度翻译: 英文-->简体中文
*
* @param text
* @return
* @throws Exception
*/
public static String en2tw(final String text) throws Exception {
return translate(text, ENGLISH, CHINA);
}
/**
* 百度翻译: 简体中文-->英文
*
* @param text
* @return
* @throws Exception
*/
public static String tw2en(final String text) throws Exception {
return translate(text, CHINA, ENGLISH);
}
/**
* 百度翻译: 日文-->简体中文
*
* @param text
* @return
* @throws Exception
*/
public static String jp2tw(final String text) throws Exception {
return translate(text, JAPAN, CHINA);
}
/**
* 百度翻译: 简体中文-->日文
*
* @param text
* @return
* @throws Exception
*/
public static String tw2jp(final String text) throws Exception {
return translate(text, CHINA, JAPAN);
}
}
4、把文件夹压缩成 jar 包
package com.yoodb.wso2ei;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 压缩文件工具
*
* @author mrwang
*
*/
public class Compressor {
private static Logger log = LoggerFactory.getLogger(Compressor.class);
private static final int BUFFER = 8192;
private File fileName;
private String originalUrl;
public Compressor(String pathName) {
fileName = new File(pathName);
}
public void compress(String... pathName) {
ZipOutputStream out = null;
try {
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32());
out = new ZipOutputStream(cos);
String basedir = "";
for (int i = 0; i < pathName.length; i++) {
compress(new File(pathName[i]), out, basedir);
}
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void compress(String srcPathName) {
File file = new File(srcPathName);
if (!file.exists())
throw new RuntimeException(srcPathName + "不存在!");
try {
FileOutputStream fileOutputStream = new FileOutputStream(fileName);
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new CRC32());
ZipOutputStream out = new ZipOutputStream(cos);
String basedir = "";
compress(file, out, basedir);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void compress(File file, ZipOutputStream out, String basedir) {
/* 判断是目录还是文件 */
if (file.isDirectory()) {
this.compressDirectory(file, out, basedir);
} else {
this.compressFile(file, out, basedir);
}
}
/**
* 压缩目录
*
* @param dir
* @param out
* @param basedir
*/
private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
if (!dir.exists())
return;
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
/* 递归 */
compress(files[i], out, basedir + dir.getName() + "/");
}
}
/**
* 压缩文件
*
* @param file
* @param out
* @param basedir
*/
private void compressFile(File file, ZipOutputStream out, String basedir) {
if (!file.exists()) {
return;
}
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
String filePath = (basedir + file.getName()).replaceAll(getOriginalUrl() + "/", "");
//log.info("压缩文件:" + filePath);
ZipEntry entry = new ZipEntry(filePath);
out.putNextEntry(entry);
int count;
byte data[] = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
bis.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
Compressor zc = new Compressor("E:\\org.wso2.carbon.service.mgt.ui_4.7.1.jar");
zc.compress("E:\\org.wso2.carbon.service.mgt.ui_4.7.0");
}
public String getOriginalUrl() {
return originalUrl;
}
public void setOriginalUrl(String originalUrl) {
this.originalUrl = originalUrl;
}
}
5、Main 方法
package com.yoodb.wso2ei;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoodb.wso2ei.util.LoadLog4jProperties;
import com.yoodb.wso2ei.util.LogLevel;
public class Main {
private static Logger log = LoggerFactory.getLogger(Main.class);
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
LoadLog4jProperties.init(false, LogLevel.info);
Long t1 = System.currentTimeMillis();
try {
start();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Long t2 = System.currentTimeMillis();
log.info("汉化成功,耗时:{} 秒", (t2-t1)/1000.00);
}
public static void start() throws Exception {
String infoPath = "D:\\WSO2_ESB\\be assimilated by the Chinese";
String logFilePath = "info.log";
UpdJarContent.createFile(infoPath, logFilePath);
FileOutputStream logfile = new FileOutputStream(infoPath + logFilePath);
String proName = "Resources";
ArrayList<File> filelist = UpdJarContent
.searchJarFiles("D:\\WSO2_ESB\\wso2ei-6.6.0-en\\wso2\\components\\plugins");
log.info("文件列表大小:" + filelist.size());
JSONArray baiduJsonArray = new JSONArray();
for (File file : filelist) {
UpdJarContent ut = new UpdJarContent();
SignUtils ss = new SignUtils();
String path = file.getAbsolutePath();
ss.setJarPath(path);
logfile.write(("------" + path + "------").getBytes());
logfile.write("\r\n".getBytes());
log.info("需要解压的压缩包路径-->" + path);
String fileName = file.getName().replace(".jar", "");
ss.setOriginalUrl(fileName);
log.info("用于压缩包删除前缀目录的名称-->" + fileName);
String filePath = infoPath + "\\file\\" + fileName;
ss.setFilePath(filePath);
log.info("解压后的文件夹目录路径-->" + filePath);
String newFilePath = infoPath + "\\jar\\" + file.getName();
ss.setJarNewPath(newFilePath);
log.info("新打包后的压缩包路径-->" + newFilePath);
JSONObject tempJsonObject = ut.updJarContent(ss, logfile, proName);
logfile.write(("------" + path + "------").getBytes());
logfile.write("\r\n".getBytes());
// DeleteDirectory.deleteDir(new File(filePath));
// log.info("删除临时解压文件 -->" + filePath + "<-- 成功!");
baiduJsonArray.add(tempJsonObject);
}
logfile.close();
JSONObject testJsonObject = new JSONObject();
for (int i = 0; i < baiduJsonArray.size(); i++) {
JSONObject indexJsonObject = baiduJsonArray.getJSONObject(i);
for (String key:indexJsonObject.keySet()) {
testJsonObject.put(key, indexJsonObject.getString(key));
}
}
writeFile(testJsonObject.toJSONString());
}
/**
* 写入文件
*/
public static void writeFile(String content) {
File pathFile = new File("1.txt");
String path = pathFile.getAbsolutePath().replace("1.txt", "");
log.info(path);
File file = new File(path + "src\\com\\yoodb\\blog\\util\\baiduApiTranlate.json");
Writer writer = null;
try {
if (!file.exists()) {
file.createNewFile();
}
writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
writer.write(content + "\r\n");
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
finally {
try {
if (null != writer) {
writer.close();
}
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}
6、完整代码
四、运行测试
把生成的 jar 包全部复制到 WSO2 EI 6.6.0 根目录下的 wso2ei_home\wso2\components\plugins
文件夹下,并覆盖原来的 jar 包。运行 WSO2 EI 6.6.0