Java tutorial
// // ProctorservApi.java // ProctorservApi // // Copyright 2013 ProctorCam, Inc // // 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. // // Created by John Tabone on 6/6/13. // //ProctorCam classes and exceptions package com.proctorcam.proctorserv; import com.proctorcam.proctorserv.exceptions.*; //Standard Java lib import java.util.*; import java.lang.*; import java.io.IOException; import java.io.UnsupportedEncodingException; //Apache libs for HTTP POST/GET import org.apache.commons.io.IOUtils; import org.apache.http.*; //GSON lib for JSON parsing import com.google.gson.*; import com.google.gson.reflect.TypeToken; public class ProctorservApi { private String api_identifier; private String shared_secret; private String service_url = "service.proctorcam.com"; private String service_protocol = "https"; /** * Constructs a new instance of ProctorservApi. If serviceURL and serviceProtocol are not passed in the * constructor method, they are given default values of 'service.proctorcam.com' and 'https' respectively */ public ProctorservApi(String api_identifier, String shared_secret, String service_url, String service_protocol) { this.api_identifier = api_identifier; this.shared_secret = shared_secret; this.service_url = service_url; this.service_protocol = service_protocol; } public ProctorservApi(String api_identifier, String shared_secret) { this.api_identifier = api_identifier; this.shared_secret = shared_secret; } /** * Get a list of schedulable timeslots (represented as Date objects) between two * times for a given test that needs to be scheduled. This API request takes the * provided session_duration into account when comparing Proctorserv business hours. * The timeslots returned are specific for a test of duration provided. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (Date[]): Array of Date objects that represent schedulable timeslots in Proctorserv * for a test of length session_duration between lower_bound and upper_bound * * Parameters: options (HashMap) of key-value pairs for: * Required: * - lower_bound (Date) - earlier of two timestamps to find available timeslots between * - upper_bound (Date) - later of two timestamps to find available timeslots between * - session_duration (int) - length in minutes alloted for this examination */ public Date[] getAvailableTimeslotsBetween(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "lower_bound", "upper_bound", "session_duration" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/scheduling/get_available_timeslots_between"); putTimeAsInteger("lower_bound", options); putTimeAsInteger("upper_bound", options); HttpResponse response = new RestRequestClient().makeGetRequest(url, api_identifier, shared_secret, options); List<String> responseValues = responseToList(response); if (response.getStatusLine().getStatusCode() == 401) raiseExceptionIfNecessaryList(responseValues); return makeDateList(responseValues); } /** * Get a list of schedulable timeslots (represented as Date objects) around the * time for a given test that needs to be scheduled. This API request takes the * provided session_duration into account when comparing Proctorserv business hours. * The timeslots returned are specific for a test of duration provided. At most, 20 * schedulable slots will be returned. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (Date[]): Array (length num_slots or 20) of Date objects that represent schedulable * timeslots in Proctorserv for a test of length session_duration around time * passed in options * * Parameters: options (HashMap) of key-value pairs for: * Required: * - time (Date) - time around which to find slots * - num_slots (Date) - number of slots to return * - session_duration (int) - length in minutes alloted for this examination */ public Date[] getAvailableTimeslotsAround(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "time", "num_slots", "session_duration" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/scheduling/get_available_timeslots_around"); putTimeAsInteger("time", options); HttpResponse response = new RestRequestClient().makeGetRequest(url, api_identifier, shared_secret, options); List<String> responseValues = responseToList(response); if (response.getStatusLine().getStatusCode() == 401) raiseExceptionIfNecessaryList(responseValues); return makeDateList(responseValues); } /** * Makes a reservation for a session if the time passed in options is a schedulable time. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (int): The Proctorserv id (session_id) for the created session. Will return -1 * if time passed is not schedulable. * * Parameters: options (HashMap) of key-value pairs for: * Required: * - time (Date) - Time around which to find slots * - customer_subject_id (String) - Unique identifier in API customer's system * for the person taking this test * - customer_client_subject_id (String) - Unique identifier in API customer's * client's system for the person taking this test * - client_code (String) - Unique identifier for API customer's client * - reservation_id (String) - Unique identifier representing this test instance * in API customer's system * - session_duration (int) - length in minutes alloted for this examination * - exam_code (String) - Unique identifier representing the group of tests this * specific test instance belongs to * Optional: * - complete_url (String) - URL that the candidate is redirected to after exam completion * - first_name (String) - First name of the candidate taking the exam * - last_name (String) - Last name of the candidate taking the exam * * Note: Additional parameters can be passed in options (HashMap) along with the above-mentioned parameters */ public int makeReservation(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "time", "customer_subject_id", "customer_client_subject_id", "client_code", "reservation_id", "session_duration", "exam_code" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/scheduling/make_reservation"); putTimeAsInteger("time", options); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HashMap<String, String> responseValues = responseToMap(response); if (response.getStatusLine().getStatusCode() == 401) raiseExceptionIfNecessaryMap(responseValues); if (response.getStatusLine().getStatusCode() == 404) return -1; return Integer.parseInt(responseValues.get("session_id")); } /** dataDeletions * Will delete all identifying data associated with a set of sessions * that are scoped to the smallest possible set by any of the following parameters * optional parameters: * - ids (only delete from this list) * - customer_subject_id (only delete sessions associated with a customer's subject id) * - customer_client_subject_id (only delete sessions associated with a customer's client's subject id) * - client_code (API identifier for customer client) * - exam_code * - lower_bound (Date Object) (seconds since unix epoch after which to delete sessions by reservation time. Defaults to 0) * - upper_bound (Date Object) (seconds since unix epoch before which to delete sessions by reservation time. Defaults to max 32 bit unsigned int) * * Note that if no parameters are passed, no sessions will be deleted. * * returns a list of session ids that were successfully deleted */ public List<String> dataDeletions(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException { String url = createURL(service_protocol, service_url, "/api/data_deletions/sessions"); // API accepts Date Object so we must convert it to // UTC seconds as that is what is required by the proctorserve api if (options.get("upper_bound") != null) putTimeAsInteger("upper_bound", options); if (options.get("lower_bound") != null) putTimeAsInteger("lower_bound", options); // Obtains reponse content HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HttpEntity entity = response.getEntity(); String responseValues = IOUtils.toString(entity.getContent()); if (response.getStatusLine().getStatusCode() != 201) { Gson gson = new Gson(); HashMap<String, String> responseMap = gson.fromJson(responseValues, new TypeToken<HashMap<String, String>>() { }.getType()); raiseExceptionIfNecessaryMap(responseMap); } // parses response and cast as List Gson json = new Gson(); List<String> sessionList = json.fromJson(responseValues, new TypeToken<List<String>>() { }.getType()); return sessionList; } /** sessions * Will return data associated with a list of sessions. * The information returned is dependant on the elements * provided in the request * * required parameters: * - ids (session id's you would like to obtain data from) - Array of IDs (string) * - elements (the type of data that you would like to retrieve for each session) - Array of elements (string) * * optional elements: Select one or more elements to receive data, if left blank no data will be returned * - review_url (url to proctorcam to review the past session) * - video_url (url to download the sessions video) * - id_photo_url (url to download the photo of the id provided by the sessions test taker) * - headshot_photo_url (url to download the photo of test taker) * - session_activity (an array of all session events associated with the session) * * example: * - $options = array("ids" => array("393", "392"), "elements" => array("id_photo_url", "headshot_photo_url", "session_activity", "video_url")) */ public HashMap<String, Object> dataRetrievals(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "ids", "elements" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/data_retrievals/sessions"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HashMap<String, Object> responseValues = responseToComplexMap(response); if (response.getStatusLine().getStatusCode() != 200) { raiseExceptionIfNecessaryComplexMap(responseValues); } return responseValues; } /** getAccessCode * Will return a object containing access code and its expiration date time based * on a session ID provided in the request * if the session id provided does not exist a error message * will be returned * * required parameters: * - session_id Integer */ public Object getAccessCode(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/access_code/get_access_code"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HashMap<String, Object> responseValues = responseToComplexMap(response); if (response.getStatusLine().getStatusCode() != 200) { raiseExceptionIfNecessaryComplexMap(responseValues); } if (responseValues.get("message") != null) { return responseValues; } else { return responseValues.get("access_code"); } } /** resetAccessCode * Will return a string containing the new access code * if the session id provided does not exist a error message * will be returned * * required parameters: * - session_id Integer */ public Object resetAccessCode(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/access_code/reset_access_code"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HashMap<String, Object> responseValues = responseToComplexMap(response); if (response.getStatusLine().getStatusCode() != 200) { raiseExceptionIfNecessaryComplexMap(responseValues); } if (responseValues.get("message") != null) { return responseValues; } else { return responseValues.get("access_code"); } } /** * Makes a reservation for a session if now is a schedulable time. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (int): The Proctorserv id (session_id) for the created session. Will return null * if time passed is not schedulable. * * Parameters: options (HashMap) of key-value pairs for: * Required: * - customer_subject_id (String) - Unique identifier in API customer's system * for the person taking this test * - customer_client_subject_id (String) - Unique identifier in API customer's * client's system for the person taking this test * - client_code (String) - Unique identifier for API customer's client * - reservation_id (String) - Unique identifier representing this test instance * in API customer's system * - session_duration (int) - length in minutes alloted for this examination * - exam_code (String) - Unique identifier representing the group of tests this * specific test instance belongs to * Optional: * - complete_url (String) - URL that the candidate is redirected to after exam completion * - first_name (String) - First name of the candidate taking the exam * - last_name (String) - Last name of the candidate taking the exam * * Note: Additional parameters can be passed in options (HashMap) along with the above-mentioned parameters */ public int makeImmediateReservation(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "customer_subject_id", "customer_client_subject_id", "client_code", "reservation_id", "session_duration", "exam_code" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/scheduling/make_immediate_reservation"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); HashMap<String, String> responseValues = responseToMap(response); if (response.getStatusLine().getStatusCode() == 401) raiseExceptionIfNecessaryMap(responseValues); if (response.getStatusLine().getStatusCode() == 404) return -1; return Integer.parseInt(responseValues.get("session_id")); } /** * Cancels a reservation for a specific session_id. A session is no longer cancelable if it * has already begun or the scheduled time has passed. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (Boolean): Whether or not the test was successfully canceled. * * Parameters: options (HashMap) of key-value pairs for: * Required: * - session_id (int) - Proctorserve id for the session to be canceled */ public Boolean cancelReservation(HashMap<String, Object> options) throws IOException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/scheduling/cancel_reservation"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); if (response.getStatusLine().getStatusCode() == 204) return true; if (response.getStatusLine().getStatusCode() == 401) { HashMap<String, String> responseValues = responseToMap(response); raiseExceptionIfNecessaryMap(responseValues); } return false; } /** * Generates a secure token that can be used to grant temporary jsonp access to a session for a web browser user to take a session. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException, UnsupportedEncodingException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (String): The JSONP token * * Parameters: options (HashMap) of key-value pairs for: * Required: * - session_id (int) - Proctorserve id for the session to grant access to * Optional: * - duration (int) - Number of minutes to grant access for (defaults to 1 hour, maximum 3 hours) */ public String generateJsonpToken(HashMap<String, Object> options) throws UnsupportedEncodingException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id" }; requiresOf(options, arguments); //Get the current time and convert to int Date time = new Date(); options.put("time", time); putTimeAsInteger("time", options); if ((Integer) options.get("duration") == null) { options.put("duration", 60); } else if ((Integer) options.get("duration") > 180) { options.put("duration", 180); } HashedAuthenticator.applyReverseGuidAndSign(options, api_identifier, shared_secret); String[] token = createTokenArray(options); return combine(token, "%26"); } /** * Generate a secure token that can be used to grant temporary access to a session for a web browser user to review a session. * Can be loaded an iframe or a new window to grant secure access to a single user for a specified period of time. * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException, UnsupportedEncodingException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (String): The secure review URL * * Parameters: options (HashMap) of key-value pairs for: * Required: * - session_id (int) - Proctorserve id for the session to grant access to * - proctor_id (String)- unique identifier representing the user to grant access to. * This will determine the user's display name in Proctorserve interfaces. * Optional: * - duration (int) - Number of minutes to grant access for (defaults to 1 hour, maximum 3 hours) * - time (Date) - Time when session event should be created. If not specified, the session event is * created immediately */ public String generateSecureReviewUrl(HashMap<String, Object> options) throws UnsupportedEncodingException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id", "proctor_id" }; requiresOf(options, arguments); //Get the current time and convert to int Date time = new Date(); options.put("time", time); putTimeAsInteger("time", options); if ((Integer) options.get("duration") == null) { options.put("duration", 5); } else if ((Integer) options.get("duration") > 180) { options.put("duration", 180); } HashedAuthenticator.applyReverseGuidAndSign(options, api_identifier, shared_secret); String[] token = createTokenArray(options); String token_string = combine(token, "%26"); return service_protocol + "://" + service_url + "/review?secure_token=" + token_string + "#watch/" + String.valueOf(options.get("session_id")); } /** * Creates a session event that is specified by session_id (int), event_type (String), severity (int), * and proctor_id (String). * * Returns (Boolean): Whether or not the session event was created * * Parameters: * Required: * - session_id (int) - Proctorserve id for the session to grant access to * - event_type (String) - The type of event which can be found in EventTypes.java * Optional: * - severity (int) - The importance-by-color of the session event (0-> grey (system event),1-> red, * 2-> yellow, and 3-> green * - proctor_id (String) - unique identifier representing the user to grant access to. * This will determine the user's display name in Proctorserve interfaces. */ public Boolean createSessionEvent(HashMap<String, Object> options) throws IOException, UnsupportedEncodingException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id", "event_type" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/session_events/create"); HttpResponse response = new RestRequestClient().makePostRequest(url, api_identifier, shared_secret, options); if (response.getStatusLine().getStatusCode() != 201) { HashMap<String, String> responseValues = responseToMap(response); raiseExceptionIfNecessaryMap(responseValues); return false; } return true; } /** * Retrieves a sessions launch parameters and moves the session into a 'checking_in' state * * This method will raise exceptions related to authentication (InvalidClientException, * InvalidSignatureException, InvalidIpException, UnsupportedEncodingException), not providing required data * (MissingRequiredParameterException), and errors in parsing the request's response * (IOException) * * Returns (String): The JSONP token * * Parameters: options (HashMap) of key-value pairs for: * Required: * - session_id (int) - Proctorserve id for the session to grant access to */ public Object getLaunchParameters(HashMap<String, Object> options) throws IOException, UnsupportedEncodingException, InvalidClientException, InvalidIpException, InvalidSignatureException, MissingRequiredParameterException { String[] arguments = { "session_id" }; requiresOf(options, arguments); String url = createURL(service_protocol, service_url, "/api/sessions/get_launch_parameters"); HttpResponse response = new RestRequestClient().makeGetRequest(url, api_identifier, shared_secret, options); HashMap<String, Object> responseValues = responseToComplexMap(response); if (response.getStatusLine().getStatusCode() != 200) { raiseExceptionIfNecessaryComplexMap(responseValues); } return responseValues.get("launch_parameters"); } /** * Converts Date object provided by time (String) in options (HashMap) to seconds * since epoch. Resulting int replaces corresponding Date object in options. */ protected void putTimeAsInteger(String time, HashMap<String, Object> options) { Date input = (Date) options.get(time); options.put(time, (Integer.toString((int) ((input.getTime()) / 1000)))); } /** * Checks options (HashMap) for required parameters provided in arguments (String[]). * * Iterates through arguments to check if parameters in arguments represent keys in * options. If not found, MissingRequiredParameterException is thrown and an error * message is displayed. */ protected void requiresOf(HashMap<String, Object> options, String[] arguments) throws MissingRequiredParameterException { for (int i = 0; i < (arguments.length) - 1; i++) { if (options.containsKey(arguments[i]) == false) { throw new MissingRequiredParameterException(arguments[i] + " is a required parameter"); } } } /** * Creates method-specific URL (String) used to make a request to Proctorserve. */ protected String createURL(String service_protocol, String service_url, String method) { StringBuilder url = new StringBuilder(); return url.append(service_protocol).append("://").append(service_url).append("/").append(method).toString(); } /** * Raises exceptions if the body of a response has an error message. * * When this function is called, the response (the first String in responseList(List)) * will be evaluated and if it matches any case an exception will be triggered */ protected void raiseExceptionIfNecessaryList(List<String> responseList) throws InvalidClientException, InvalidSignatureException, InvalidIpException { if (responseList.get(0).equals("Not a valid client")) { throw new InvalidClientException("The api_identifier for this instance of ProctorservApi" + " does not match up with any for the service."); } else if (responseList.get(0).equals("Signature hash is invalid")) { throw new InvalidSignatureException("Authentication failed for the ProctorservApi request. " + "It is most likely that the shared_secret does not match up with the Proctorserve record for your API client."); } else if (responseList.get(0).equals("Request coming from invalid IP")) { throw new InvalidIpException("Authentication failed for the ProctorservApi request because " + "the IP address of this machine is not whitelisted for this API client in Proctorserve."); } } /** * Raises exceptions if the body of a response has an error message. * * When this function is called, the response (the first String in responseMap(Map)) * will be evaluated and if it matches any case an exception will be triggered */ protected void raiseExceptionIfNecessaryMap(HashMap<String, String> responseMap) throws InvalidClientException, InvalidSignatureException, InvalidIpException { if (responseMap.get("message").equals("Not a valid client")) { throw new InvalidClientException("The api_identifier for this instance of ProctorservApi" + " does not match up with any for the service."); } else if (responseMap.get("message").equals("Signature hash is invalid")) { throw new InvalidSignatureException("Authentication failed for the ProctorservApi request. " + "It is most likely that the shared_secret does not match up with the Proctorserve record for your API client."); } else if (responseMap.get("message").equals("Request coming from invalid IP")) { throw new InvalidIpException("Authentication failed for the ProctorservApi request because " + "the IP address of this machine is not whitelisted for this API client in Proctorserve."); } } /** * Raises exceptions if the body of a response has an error message. * * When this function is called, the response (the first String in responseMap(Map)) * will be evaluated and if it matches any case an exception will be triggered */ protected void raiseExceptionIfNecessaryComplexMap(HashMap<String, Object> responseMap) throws InvalidClientException, InvalidSignatureException, InvalidIpException { if (responseMap.get("message").equals("Not a valid client")) { throw new InvalidClientException("The api_identifier for this instance of ProctorservApi" + " does not match up with any for the service."); } else if (responseMap.get("message").equals("Signature hash is invalid")) { throw new InvalidSignatureException("Authentication failed for the ProctorservApi request. " + "It is most likely that the shared_secret does not match up with the Proctorserve record for your API client."); } else if (responseMap.get("message").equals("Request coming from invalid IP")) { throw new InvalidIpException("Authentication failed for the ProctorservApi request because " + "the IP address of this machine is not whitelisted for this API client in Proctorserve."); } } /** * Creates array of Date objects that serves as a return value for getAvailableTimeslotsBetween * and getAvailableTimeslotsAround. * * This method iterates through the response (List) and uses function timeStringToDate to convert * the time strings (in seconds since epoch) provided by the response into Date objects which are put in an * array. */ protected Date[] makeDateList(List<String> response) { Date[] dateList = new Date[response.size()]; for (int i = 0; i < response.size(); i++) { Date timeDate = timeStringToDate(response.get(i)); dateList[i] = timeDate; } return dateList; } /** * Converts the time strings (in seconds since epoch) provided by the response into Date objects. * This method is called by makeDateList. */ protected Date timeStringToDate(String time) { int timeInt = (Integer.parseInt(time)); long timeLong = ((long) timeInt) * 1000; Date timeDate = new Date(timeLong); return timeDate; } /** * Creates a List object from the response (HttpResponse) body */ protected List<String> responseToList(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity(); String body = IOUtils.toString(entity.getContent()); Gson gson = new Gson(); List<String> responseValues = gson.fromJson(body, new TypeToken<List<String>>() { }.getType()); return responseValues; } /** * Creates a HashMap object from the response (HttpResponse) body */ protected HashMap<String, String> responseToMap(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity(); String body = IOUtils.toString(entity.getContent()); Gson gson = new Gson(); HashMap<String, String> responseValues = gson.fromJson(body, new TypeToken<HashMap<String, String>>() { }.getType()); return responseValues; } protected HashMap<String, Object> responseToComplexMap(HttpResponse response) throws IOException { HttpEntity entity = response.getEntity(); String body = IOUtils.toString(entity.getContent()); Gson gson = new Gson(); HashMap<String, Object> responseValues = gson.fromJson(body, new TypeToken<HashMap<String, Object>>() { }.getType()); return responseValues; } /** * Acts as a join method for arrays */ protected String combine(String[] array, String glue) { if (array.length == 0) return ""; StringBuilder template = new StringBuilder(); int i; for (i = 0; i < array.length - 1; i++) { template.append(array[i] + glue); } return template.toString() + array[i]; } /** * Takes the passed HashMap and spits out an array that acts * as a token template */ protected String[] createTokenArray(HashMap<String, Object> options) { String[] token = new String[options.size()]; int i = 0; for (String key : options.keySet()) { String value = String.valueOf(options.get(key)); token[i] = key + "%3D" + value; i++; } return token; } }