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
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);
|
|
}
|
|
}
|