package cn.yiiguxing.plugin.translate; import cn.yiiguxing.plugin.translate.model.QueryResult; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.io.HttpRequests; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.concurrent.Future; /** * 翻译器 */ @SuppressWarnings("WeakerAccess") public final class Translator { @SuppressWarnings("SpellCheckingInspection") private static final String BASIC_URL = "http://fanyi.youdao.com/openapi.do"; private static final String DEFAULT_API_KEY_NAME = "TranslationPlugin"; private static final String DEFAULT_API_KEY_VALUE = "1473510108"; private static final Logger LOGGER = Logger.getInstance("#" + Translator.class.getCanonicalName()); private final LruCache<String, QueryResult> mCache = new LruCache<String, QueryResult>(200); private Future<?> mCurrentTask; private Translator() { } /** * @return {@link Translator} 的实例 */ public static Translator getInstance() { return ServiceManager.getService(Translator.class); } /** * 获取缓存 */ @Nullable public QueryResult getCache(@NotNull String query) { synchronized (mCache) { return mCache.get(query); } } /** * 查询翻译 * * @param query 目标字符串 * @param callback 回调 */ public void query(String query, Callback callback) { if (Utils.isEmptyOrBlankString(query)) { if (callback != null) { callback.onQuery(query, null); } return; } if (mCurrentTask != null) { mCurrentTask.cancel(true); mCurrentTask = null; } QueryResult cache; synchronized (mCache) { cache = mCache.get(query); } if (cache != null) { if (callback != null) { callback.onQuery(query, cache); } } else { mCurrentTask = ApplicationManager.getApplication().executeOnPooledThread(new QueryRequest(query, callback)); } } static String getQueryUrl(String query) { String encodedQuery = ""; try { encodedQuery = URLEncoder.encode(query, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Settings settings = Settings.getInstance(); String apiKeyName; String apiKeyValue; if (settings.isUseDefaultKey()) { apiKeyName = DEFAULT_API_KEY_NAME; apiKeyValue = DEFAULT_API_KEY_VALUE; } else { apiKeyName = settings.getApiKeyName(); apiKeyValue = settings.getApiKeyValue(); if (Utils.isEmptyOrBlankString(apiKeyName) || Utils.isEmptyOrBlankString(apiKeyValue)) { apiKeyName = DEFAULT_API_KEY_NAME; apiKeyValue = DEFAULT_API_KEY_VALUE; } } return BASIC_URL + "?type=data&doctype=json&version=1.1&keyfrom=" + apiKeyName + "&key=" + apiKeyValue + "&q=" + encodedQuery; } private final class QueryRequest implements Runnable { private final String mQuery; private final Callback mCallback; QueryRequest(String query, Callback callback) { mQuery = query; mCallback = callback; } @Override public void run() { final String query = mQuery; final String url = getQueryUrl(query); QueryResult result = null; try { String json = HttpRequests.request(url).readString(null); LOGGER.info(json); if (!Utils.isEmptyOrBlankString(json)) { result = new Gson().fromJson(json, QueryResult.class); } } catch (IOException e) { LOGGER.warn(e); result = new QueryResult(); result.setErrorCode(QueryResult.ERROR_CODE_FAIL); result.setMessage(e.getMessage()); } catch (JsonSyntaxException e) { LOGGER.warn(e); result = new QueryResult(); result.setErrorCode(QueryResult.ERROR_CODE_RESTRICTED); } if (result != null) { result.checkError(); if (result.getErrorCode() == QueryResult.ERROR_CODE_NONE) { synchronized (mCache) { mCache.put(query, result); } } } System.out.println("query: " + query); System.out.println("result: " + result); if (mCallback != null) { mCallback.onQuery(query, result); } } } /** * 翻译回调接口 */ public interface Callback { /** * 翻译结束后的回调方法 * * @param query 查询字符串 * @param result 翻译结果 */ void onQuery(@Nullable String query, @Nullable QueryResult result); } }