You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
8.1 KiB
Java

package org.etherpad_lite_client;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import com.netsyms.symat.padview.Debug;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
/**
* Connection object for talking to and parsing responses from the Etherpad Lite
* Server.
*/
public class EPLiteConnection {
public static final int CODE_OK = 0;
public static final int CODE_INVALID_PARAMETERS = 1;
public static final int CODE_INTERNAL_ERROR = 2;
public static final int CODE_INVALID_METHOD = 3;
public static final int CODE_INVALID_API_KEY = 4;
/**
* The url of the API
*/
public URI uri;
/**
* The API key
*/
public String apiKey;
/**
* The Etherpad Lite API version
*/
public String apiVersion;
/**
* Initializes a new org.etherpad_lite_client.EPLiteConnection object.
*
* @param url an absolute url, including protocol, to the EPL api
* @param apiKey the API Key
* @param apiVersion the API version
*/
public EPLiteConnection(String url, String apiKey, String apiVersion) {
this.uri = URI.create(url);
this.apiKey = apiKey;
this.apiVersion = apiVersion;
}
/**
* GETs from the HTTP JSON API.
*
* @param apiMethod the name of the API method to call
* @return HashMap
*/
public HashMap get(String apiMethod) {
return this.get(apiMethod, new HashMap());
}
/**
* GETs from the HTTP JSON API.
*
* @param apiMethod the name of the API method to call
* @param apiArgs a HashMap of url/form parameters. apikey will be set
* automatically
* @return HashMap
*/
public HashMap get(String apiMethod, HashMap apiArgs) {
String path = this.apiPath(apiMethod);
String query = this.queryString(apiArgs);
URL url = apiUrl(path, query);
Request request = new GETRequest(url);
return this.call(request);
}
/**
* POSTs to the HTTP JSON API.
*
* @param apiMethod the name of the API method to call
* @return HashMap
*/
public HashMap post(String apiMethod) {
return this.post(apiMethod, new HashMap());
}
/**
* POSTs to the HTTP JSON API.
*
* @param apiMethod the name of the API method to call
* @param apiArgs a HashMap of url/form parameters. apikey will be set
* automatically
* @return HashMap
*/
public HashMap post(String apiMethod, HashMap apiArgs) {
String path = this.apiPath(apiMethod);
String query = this.queryString(apiArgs);
URL url = apiUrl(path, null);
Request request = new POSTRequest(url, query);
return this.call(request);
}
/**
* Calls the HTTP JSON API.
*
* @param request the request object to send
* @return HashMap
*/
private HashMap call(Request request) {
trustServerAndCertificate();
try {
String response = request.send();
return this.handleResponse(response);
} catch (EPLiteException e) {
throw new EPLiteException(e.getMessage());
} catch (Exception e) {
throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage());
}
}
/**
* Converts the API resonse's JSON string into a HashMap.
*
* @param jsonString a valid JSON string
* @return HashMap
*/
private HashMap handleResponse(String jsonString) {
try {
JSONParser parser = new JSONParser();
Map response = (Map) parser.parse(jsonString);
// Act on the response code
if (!response.get("code").equals(null)) {
int code = ((Long) response.get("code")).intValue();
switch (code) {
// Valid code, parse the response
case CODE_OK:
HashMap data = (HashMap) response.get("data");
return data != null ? data : new HashMap();
// Invalid code, throw an exception with the message
case CODE_INVALID_PARAMETERS:
case CODE_INVALID_API_KEY:
case CODE_INVALID_METHOD:
throw new EPLiteException((String) response.get("message"));
default:
throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString);
}
// No response code, something's really wrong
} else {
throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString);
}
} catch (ParseException e) {
System.err.println("Unable to parse JSON response (" + jsonString + "): " + e.getMessage());
return new HashMap();
}
}
/**
* Returns the URL for the api path and query.
*
* @param path the api path
* @param query the query string (may be null)
* @return URL
*/
private URL apiUrl(String path, String query) {
try {
URL url = new URL(new URI(this.uri.getScheme(), null, this.uri.getHost(), this.uri.getPort(), path, query, null).toString());
return url;
} catch (Exception e) {
throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage());
}
}
/**
* Returns a URI path for the API method
*
* @param apiMethod the api method
* @return String
*/
private String apiPath(String apiMethod) {
return this.uri.getPath() + "/api/" + this.apiVersion + "/" + apiMethod;
}
/**
* Returns a query string made from HashMap keys and values
*
* @param apiArgs the api arguments in a HashMap
* @return String
*/
private String queryString(HashMap apiArgs) {
String strArgs = "";
apiArgs.put("apikey", this.apiKey);
Iterator i = apiArgs.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
Object value = e.getValue();
if (value != null) {
try {
strArgs += e.getKey() + "=" + URLEncoder.encode(value.toString(), "utf-8");
} catch (UnsupportedEncodingException ex) {
Debug.stacktrace(ex);
}
if (i.hasNext()) {
strArgs += "&";
}
}
}
return strArgs;
}
/**
* Creates a trust manager to trust all certificates if you open a ssl
* connection
*/
private void trustServerAndCertificate() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
HostnameVerifier hv = new HostnameVerifier() {
//@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
}