com.memetix.mst.MicrosoftTranslatorAPI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of microsoft-translator-java-api Show documentation
Show all versions of microsoft-translator-java-api Show documentation
A Java wrapper for the Microsoft Translator API
/*
* microsoft-translator-java-api
*
* Copyright 2012 Jonathan Griggs .
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.memetix.mst;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
*
* MicrosoftAPI
*
* Makes the generic Microsoft Translator API calls. Different service classes then
* extend this to make the specific service calls.
*
* Uses the AJAX Interface V2 - see: http://msdn.microsoft.com/en-us/library/ff512404.aspx
*
* @author Jonathan Griggs
*/
public abstract class MicrosoftTranslatorAPI {
//Encoding type
protected static final String ENCODING = "UTF-8";
protected static String apiKey;
private static String DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
private static String referrer;
private static String clientId;
private static String clientSecret;
private static String token;
private static long tokenExpiration = 0;
private static String contentType = "text/plain";
protected static final String PARAM_APP_ID = "appId=",
PARAM_TO_LANG = "&to=",
PARAM_FROM_LANG = "&from=",
PARAM_TEXT_SINGLE = "&text=",
PARAM_TEXT_ARRAY = "&texts=",
PARAM_SPOKEN_LANGUAGE = "&language=",
PARAM_SENTENCES_LANGUAGE = "&language=",
PARAM_LOCALE = "&locale=",
PARAM_LANGUAGE_CODES = "&languageCodes=";
/**
* Sets the API key.
*
* Note: Should ONLY be used with API Keys generated prior to March 31, 2012. All new applications should obtain a ClientId and Client Secret by following
* the guide at: http://msdn.microsoft.com/en-us/library/hh454950.aspx
* @param pKey The API key.
*/
public static void setKey(final String pKey) {
apiKey = pKey;
}
/**
* Sets the API key.
*
* Note: Should ONLY be used with API Keys generated prior to March 31, 2012. All new applications should obtain a ClientId and Client Secret by following
* the guide at: http://msdn.microsoft.com/en-us/library/hh454950.aspx
* @param pKey The API key.
*/
public static void setContentType(final String pKey) {
contentType = pKey;
}
/**
* Sets the Client ID.
* All new applications should obtain a ClientId and Client Secret by following
* the guide at: http://msdn.microsoft.com/en-us/library/hh454950.aspx
* @param pKey The Client Id.
*/
public static void setClientId(final String pClientId) {
clientId = pClientId;
}
/**
* Sets the Client Secret.
* All new applications should obtain a ClientId and Client Secret by following
* the guide at: http://msdn.microsoft.com/en-us/library/hh454950.aspx
* @param pKey The Client Secret.
*/
public static void setClientSecret(final String pClientSecret) {
clientSecret = pClientSecret;
}
/**
* Sets the Http Referrer.
* @param pReferrer The HTTP client referrer.
*/
public static void setHttpReferrer(final String pReferrer) {
referrer = pReferrer;
}
/**
* Gets the OAuth access token.
* @param clientId The Client key.
* @param clientSecret The Client Secret
*/
public static String getToken(final String clientId, final String clientSecret) throws Exception {
final String params = "grant_type=client_credentials&scope=http://api.microsofttranslator.com"
+ "&client_id=" + URLEncoder.encode(clientId,ENCODING)
+ "&client_secret=" + URLEncoder.encode(clientSecret,ENCODING) ;
final URL url = new URL(DatamarketAccessUri);
final HttpURLConnection uc = (HttpURLConnection) url.openConnection();
if(referrer!=null)
uc.setRequestProperty("referer", referrer);
uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded; charset=" + ENCODING);
uc.setRequestProperty("Accept-Charset",ENCODING);
uc.setRequestMethod("POST");
uc.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(uc.getOutputStream());
wr.write(params);
wr.flush();
try {
final int responseCode = uc.getResponseCode();
final String result = inputStreamToString(uc.getInputStream());
if(responseCode!=200) {
throw new Exception("Error from Microsoft Translator API: " + result);
}
return result;
} finally {
if(uc!=null) {
uc.disconnect();
}
}
}
/**
* Forms an HTTP request, sends it using GET method and returns the result of the request as a String.
*
* @param url The URL to query for a String response.
* @return The translated String.
* @throws Exception on error.
*/
private static String retrieveResponse(final URL url) throws Exception {
if(clientId!=null&&clientSecret!=null&&System.currentTimeMillis()>tokenExpiration) {
String tokenJson = getToken(clientId,clientSecret);
Integer expiresIn = Integer.parseInt((String)((JSONObject)JSONValue.parse(tokenJson)).get("expires_in"));
tokenExpiration = System.currentTimeMillis()+((expiresIn*1000)-1);
token = "Bearer " + (String)((JSONObject)JSONValue.parse(tokenJson)).get("access_token");
}
final HttpURLConnection uc = (HttpURLConnection) url.openConnection();
if(referrer!=null)
uc.setRequestProperty("referer", referrer);
uc.setRequestProperty("Content-Type",contentType + "; charset=" + ENCODING);
uc.setRequestProperty("Accept-Charset",ENCODING);
if(token!=null) {
uc.setRequestProperty("Authorization",token);
}
uc.setRequestMethod("GET");
uc.setDoOutput(true);
try {
final int responseCode = uc.getResponseCode();
final String result = inputStreamToString(uc.getInputStream());
if(responseCode!=200) {
throw new Exception("Error from Microsoft Translator API: " + result);
}
return result;
} finally {
if(uc!=null) {
uc.disconnect();
}
}
}
/**
* Fetches the JSON response, parses the JSON Response, returns the result of the request as a String.
*
* @param url The URL to query for a String response.
* @return The translated String.
* @throws Exception on error.
*/
protected static String retrieveString(final URL url) throws Exception {
try {
final String response = retrieveResponse(url);
return jsonToString(response);
} catch (Exception ex) {
throw new Exception("[microsoft-translator-api] Error retrieving translation : " + ex.getMessage(), ex);
}
}
/**
* Fetches the JSON response, parses the JSON Response as an Array of JSONObjects,
* retrieves the String value of the specified JSON Property, and returns the result of
* the request as a String Array.
*
* @param url The URL to query for a String response.
* @return The translated String[].
* @throws Exception on error.
*/
protected static String[] retrieveStringArr(final URL url, final String jsonProperty) throws Exception {
try {
final String response = retrieveResponse(url);
return jsonToStringArr(response,jsonProperty);
} catch (Exception ex) {
throw new Exception("[microsoft-translator-api] Error retrieving translation.", ex);
}
}
/**
* Fetches the JSON response, parses the JSON Response as an array of Strings
* and returns the result of the request as a String Array.
*
* Overloaded to pass null as the JSON Property (assume only Strings instead of JSONObjects)
*
* @param url The URL to query for a String response.
* @return The translated String[].
* @throws Exception on error.
*/
protected static String[] retrieveStringArr(final URL url) throws Exception {
return retrieveStringArr(url,null);
}
/**
* Fetches the JSON response, parses the JSON Response, returns the result of the request as an array of integers.
*
* @param url The URL to query for a String response.
* @return The translated String.
* @throws Exception on error.
*/
protected static Integer[] retrieveIntArray(final URL url) throws Exception {
try {
final String response = retrieveResponse(url);
return jsonToIntArr(response);
} catch (Exception ex) {
throw new Exception("[microsoft-translator-api] Error retrieving translation : " + ex.getMessage(), ex);
}
}
private static Integer[] jsonToIntArr(final String inputString) throws Exception {
final JSONArray jsonArr = (JSONArray)JSONValue.parse(inputString);
Integer[] intArr = new Integer[jsonArr.size()];
int i = 0;
for(Object obj : jsonArr) {
intArr[i] = ((Long)obj).intValue();
i++;
}
return intArr;
}
private static String jsonToString(final String inputString) throws Exception {
String json = (String)JSONValue.parse(inputString);
return json.toString();
}
// Helper method to parse a JSONArray. Reads an array of JSONObjects and returns a String Array
// containing the toString() of the desired property. If propertyName is null, just return the String value.
private static String[] jsonToStringArr(final String inputString, final String propertyName) throws Exception {
final JSONArray jsonArr = (JSONArray)JSONValue.parse(inputString);
String[] values = new String[jsonArr.size()];
int i = 0;
for(Object obj : jsonArr) {
if(propertyName!=null&&propertyName.length()!=0) {
final JSONObject json = (JSONObject)obj;
if(json.containsKey(propertyName)) {
values[i] = json.get(propertyName).toString();
}
} else {
values[i] = obj.toString();
}
i++;
}
return values;
}
/**
* Reads an InputStream and returns its contents as a String.
* Also effects rate control.
* @param inputStream The InputStream to read from.
* @return The contents of the InputStream as a String.
* @throws Exception on error.
*/
private static String inputStreamToString(final InputStream inputStream) throws Exception {
final StringBuilder outputBuilder = new StringBuilder();
try {
String string;
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING));
while (null != (string = reader.readLine())) {
// Need to strip the Unicode Zero-width Non-breaking Space. For some reason, the Microsoft AJAX
// services prepend this to every response
outputBuilder.append(string.replaceAll("\uFEFF", ""));
}
}
} catch (Exception ex) {
throw new Exception("[microsoft-translator-api] Error reading translation stream.", ex);
}
return outputBuilder.toString();
}
//Check if ready to make request, if not, throw a RuntimeException
protected static void validateServiceState() throws Exception {
if(apiKey!=null&&apiKey.length()<16) {
throw new RuntimeException("INVALID_API_KEY - Please set the API Key with your Bing Developer's Key");
} else if (apiKey==null&&(clientId==null||clientSecret==null)) {
throw new RuntimeException("Must provide a Windows Azure Marketplace Client Id and Client Secret - Please see http://msdn.microsoft.com/en-us/library/hh454950.aspx for further documentation");
}
}
protected static String buildStringArrayParam(Object[] values) {
StringBuilder targetString = new StringBuilder("[\"");
String value;
for(Object obj : values) {
if(obj!=null) {
value = obj.toString();
if(value.length()!=0) {
if(targetString.length()>2)
targetString.append(",\"");
targetString.append(value);
targetString.append("\"");
}
}
}
targetString.append("]");
return targetString.toString();
}
}