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