Java tutorial
/******************************************************************************* * Copyright 2011 The Regents of the University of California * * 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 org.ohmage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.zip.GZIPOutputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.HttpClientParams; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils; import org.ccnx.ccn.config.SystemConfiguration; import org.ccnx.ccn.impl.support.DataUtils; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.ContentObject; import org.ccnx.ccn.protocol.KeyLocator; import org.ccnx.ccn.protocol.MalformedContentNameStringException; import org.ccnx.ccn.protocol.PublisherPublicKeyDigest; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import edu.ucla.cens.pdc.libpdc.core.GlobalConfig; import edu.ucla.cens.pdc.libpdc.core.PDCKeyManager; import edu.ucla.cens.pdc.libpdc.exceptions.PDCEncryptionException; import edu.ucla.cens.systemlog.Log; import org.ohmage.pdc.OhmagePDVManager; import org.ohmage.util.NDNUtils; public class OhmageApi { private static final String TAG = "OhmageApi"; //private static final String SERVER_URL = "https://dev.andwellness.org/"; //private String serverUrl; //private String mBaseServerUrl = "https://dev1.andwellness.org/"; //public static final String BASE_SERVER_URL = "https://dev1.andwellness.org/"; private static final String AUTHENTICATE_PATH = "app/user/auth"; private static final String AUTHENTICATE_TOKEN_PATH = "app/user/auth_token"; private static final String MOBILITY_UPLOAD_PATH = "app/mobility/upload"; private static final String SURVEY_UPLOAD_PATH = "app/survey/upload"; private static final String IMAGE_UPLOAD_PATH = "app/image/upload"; private static final String CAMPAIGN_READ_PATH = "app/campaign/read"; private static final String SURVEYRESPONSE_READ_PATH = "app/survey_response/read"; private static final String IMAGE_READ_PATH = "app/image/read"; private static final int MAX_ATTEMPTS = 5; public OhmageApi(Context context) { SharedPreferencesHelper prefs = new SharedPreferencesHelper(context); // serverUrl = prefs.getServerUrl(); } public static enum Result { SUCCESS, FAILURE, HTTP_ERROR, INTERNAL_ERROR } public static enum Error { } public static abstract class Response { protected Result mResult; protected String[] mErrorCodes; public Response() { // do-nothing constructor so we can create instances via reflection } public Response(Result result, String[] errorCodes) { mResult = result; mErrorCodes = errorCodes; } public void setResponseStatus(Result result, String[] errorCodes) { mResult = result; mErrorCodes = errorCodes; } public Result getResult() { return mResult; } public String[] getErrorCodes() { return mErrorCodes; } public void setResult(Result result) { this.mResult = result; } public void setErrorCodes(String[] errorCodes) { this.mErrorCodes = errorCodes; } public abstract void populateFromJSON(JSONObject rootJson) throws JSONException; } public static class AuthenticateResponse extends Response { private String mHashedPassword; private String mToken; public AuthenticateResponse(Result result, String hashedPassword, String token, String[] errorCodes) { super(result, errorCodes); mHashedPassword = hashedPassword; mToken = token; } public String getHashedPassword() { return mHashedPassword; } public void setHashedPassword(String hashedPassword) { this.mHashedPassword = hashedPassword; } public void setToken(String mToken) { this.mToken = mToken; } public String getToken() { return mToken; } @Override public void populateFromJSON(JSONObject rootJson) throws JSONException { if (rootJson.has("hashed_password")) mHashedPassword = rootJson.getString("hashed_password"); if (rootJson.has("token")) mToken = rootJson.getString("token"); } } public static class UploadResponse extends Response { public UploadResponse(Result result, String[] errorCodes) { super(result, errorCodes); } @Override public void populateFromJSON(JSONObject rootJson) { // does nothing, since we don't use the response } } public static class CampaignReadResponse extends Response { protected JSONObject mData; protected JSONObject mMetadata; public JSONObject getData() { return mData; } public JSONObject getMetadata() { return mMetadata; } public void setData(JSONObject data) { this.mData = data; } public void setMetadata(JSONObject metadata) { this.mMetadata = metadata; } @Override public void populateFromJSON(JSONObject rootJson) throws JSONException { if (rootJson.has("data")) mData = rootJson.getJSONObject("data"); if (rootJson.has("metadata")) mMetadata = rootJson.getJSONObject("metadata"); } } public static class CampaignXmlResponse extends Response { protected String mXml; public String getXml() { return mXml; } public void setXml(String xml) { this.mXml = xml; } @Override public void populateFromJSON(JSONObject rootJson) throws JSONException { // do nothing, b/c there's no json data } } public static class SurveyReadResponse extends Response { protected JSONArray mData; protected JSONObject mMetadata; public JSONArray getData() { return mData; } public JSONObject getMetadata() { return mMetadata; } public void setData(JSONArray data) { this.mData = data; } public void setMetadata(JSONObject metadata) { this.mMetadata = metadata; } @Override public void populateFromJSON(JSONObject rootJson) throws JSONException { if (rootJson.has("data")) mData = rootJson.getJSONArray("data"); if (rootJson.has("metadata")) mMetadata = rootJson.getJSONObject("metadata"); } } public class ImageReadResponse extends Response { private byte[] data; private String type; @Override public void populateFromJSON(JSONObject rootJson) throws JSONException { // do nothing, b/c there's no json data } public void setData(byte[] data) { this.data = data; } public byte[] getData() { return data; } public String getType() { return type; } public void setType(String type) { this.type = type; } } public AuthenticateResponse authenticate(String serverUrl, String username, String password, String client) { final boolean GZIP = false; String url = serverUrl + AUTHENTICATE_PATH; return new AuthenticateResponse(Result.SUCCESS, null, null, null); /* try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", password)); nameValuePairs.add(new BasicNameValuePair("client", client)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return parseAuthenticateResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new AuthenticateResponse(Result.INTERNAL_ERROR, null, null, null); }*/ } public AuthenticateResponse authenticateToken(String serverUrl, String username, String password, String client) { final boolean GZIP = false; String url = serverUrl + AUTHENTICATE_TOKEN_PATH; try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", password)); nameValuePairs.add(new BasicNameValuePair("client", client)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return parseAuthenticateResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new AuthenticateResponse(Result.INTERNAL_ERROR, null, null, null); } } public UploadResponse mobilityUpload(String serverUrl, String username, String hashedPassword, String client, String data) { final boolean GZIP = true; String url = serverUrl + MOBILITY_UPLOAD_PATH; try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("data", data)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return parseUploadResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new UploadResponse(Result.INTERNAL_ERROR, null); } } public UploadResponse surveyUpload(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String campaignCreationTimestamp, String data) { final boolean GZIP = true; String url = serverUrl + SURVEY_UPLOAD_PATH; try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("campaign_urn", campaignUrn)); nameValuePairs.add(new BasicNameValuePair("campaign_creation_timestamp", campaignCreationTimestamp)); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("data", data)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return parseUploadResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new UploadResponse(Result.INTERNAL_ERROR, null); } } public UploadResponse surveyUpload(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String campaignCreationTimestamp, String responseJson, File[] photos) { final boolean GZIP = false; String url = serverUrl + SURVEY_UPLOAD_PATH; try { MultipartEntity multipartEntity = new MultipartEntity(); multipartEntity.addPart("campaign_urn", new StringBody(campaignUrn)); multipartEntity.addPart("campaign_creation_timestamp", new StringBody(campaignCreationTimestamp)); multipartEntity.addPart("user", new StringBody(username)); multipartEntity.addPart("password", new StringBody(hashedPassword)); multipartEntity.addPart("client", new StringBody(client)); multipartEntity.addPart("surveys", new StringBody(responseJson)); if (photos != null) { for (int i = 0; i < photos.length; i++) { multipartEntity.addPart(photos[i].getName().split("\\.")[0], new FileBody(photos[i], "image/jpeg")); } } return parseUploadResponse(doHttpPost(url, multipartEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new UploadResponse(Result.INTERNAL_ERROR, null); } } public UploadResponse mediaUpload(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String campaignCreationTimestamp, String uuid, File data) { final boolean GZIP = false; String url = serverUrl + IMAGE_UPLOAD_PATH; try { MultipartEntity multipartEntity = new MultipartEntity(); multipartEntity.addPart("campaign_urn", new StringBody(campaignUrn)); multipartEntity.addPart("campaign_creation_timestamp", new StringBody(campaignCreationTimestamp)); multipartEntity.addPart("user", new StringBody(username)); multipartEntity.addPart("password", new StringBody(hashedPassword)); multipartEntity.addPart("client", new StringBody(client)); multipartEntity.addPart("id", new StringBody(uuid)); multipartEntity.addPart("data", new FileBody(data, "image/jpeg")); return parseUploadResponse(doHttpPost(url, multipartEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); return new UploadResponse(Result.INTERNAL_ERROR, null); } } public CampaignReadResponse campaignRead(String serverUrl, String username, String hashedPassword, String client, String outputFormat, String campaignUrnList) { final boolean GZIP = false; String url = serverUrl + CAMPAIGN_READ_PATH; if (client == "android") { Result result = Result.HTTP_ERROR; String[] errorCodes = null; Response candidate = new CampaignReadResponse(); if (OhmagePDVManager.getInstance() == null || !OhmagePDVManager.getInstance().isListening()) return null; GlobalConfig config = GlobalConfig.getInstance(); PublisherPublicKeyDigest digest = OhmagePDVManager.getConfigurationDigest(); ContentName keyName = OhmagePDVManager.getInstance().getConfigKeyLocator(); KeyLocator locator = new KeyLocator(keyName, digest); if (hashedPassword == null) Log.e(TAG, "Hashed password is null"); byte[] encrypted_data = NDNUtils.encryptConfigData(locator, username, hashedPassword); if (encrypted_data == null) return null; Log.i(TAG, "Base64encoded string : " + new String(DataUtils.base64Encode(encrypted_data))); try { ContentName campaignReadName = ContentName.fromURI("ccnx:/ndn/ucla.edu/apps/borges/ohmagepdv") .append("manage/campaign/read").append(outputFormat) .append(new String(DataUtils.base64Encode(encrypted_data))) .append(OhmagePDVManager.getHashedDeviceId()); Log.i(TAG, "Campaign Name to be read: " + campaignReadName); ContentObject co = config.getCCNHandle().get(campaignReadName, SystemConfiguration.LONG_TIMEOUT); if (co == null) { Log.e(TAG, "Returned NULL Content Object"); return null; } else { Log.i(TAG, "Content Object: " + co); } JSONObject rootJson = new JSONObject(new String(NDNUtils.decryptConfigData(co.content()))); if (rootJson.getString("result").equals("success")) { result = Result.SUCCESS; // allow the output type to determine how to extract // data from the json collection candidate.populateFromJSON(rootJson); } else { result = Result.FAILURE; JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } Log.i(TAG, rootJson.toString()); candidate.setResponseStatus(result, errorCodes); return (CampaignReadResponse) candidate; } catch (JSONException e) { Log.e(TAG, e.toString()); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return (CampaignReadResponse) candidate; } catch (IOException e) { Log.e(TAG, e.toString()); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return (CampaignReadResponse) candidate; } catch (MalformedContentNameStringException e) { Log.e(TAG, e.toString()); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return (CampaignReadResponse) candidate; } } else { try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("output_format", outputFormat)); if (campaignUrnList != null) { nameValuePairs.add(new BasicNameValuePair("campaign_urn_list", campaignUrnList)); } UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return (CampaignReadResponse) parseReadResponse(doHttpPost(url, formEntity, GZIP), CampaignReadResponse.class); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); CampaignReadResponse candidate = new CampaignReadResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } } } public CampaignXmlResponse campaignXmlRead(String serverUrl, String username, String hashedPassword, String client, String campaignUrn) { final boolean GZIP = false; String url = serverUrl + CAMPAIGN_READ_PATH; if (client.equals("android")) { if (!OhmagePDVManager.getInstance().isListening()) return null; GlobalConfig config = GlobalConfig.getInstance(); PublisherPublicKeyDigest digest = OhmagePDVManager.getConfigurationDigest(); ContentName keyName = OhmagePDVManager.getInstance().getConfigKeyLocator(); KeyLocator locator = new KeyLocator(keyName, digest); if (hashedPassword == null) Log.e(TAG, "Hashed password is null"); byte[] encrypted_data = NDNUtils.encryptConfigData(locator, username, hashedPassword); if (encrypted_data == null) return null; Log.i(TAG, "Base64encoded string : " + new String(DataUtils.base64Encode(encrypted_data))); try { ContentName campaignXMLReadName = ContentName.fromURI("ccnx:/ndn/ucla.edu/apps/borges/ohmagepdv") .append("manage/campaign/read").append("xml").append(campaignUrn) .append(new String(DataUtils.base64Encode(encrypted_data))) .append(OhmagePDVManager.getHashedDeviceId()); Log.i(TAG, "XML Campaign Read Name : " + campaignXMLReadName); ContentObject co = config.getCCNHandle().get(campaignXMLReadName, SystemConfiguration.LONG_TIMEOUT); if (co == null) { return null; } Log.i(TAG, co.toString()); // JSONObject resultJson = new JSONObject(new String(co.content())); byte[] data = NDNUtils.decryptConfigData(co.content()); Log.i(TAG, "Response Text : " + new String(data)); JSONObject returnedObject = new JSONObject(new String(data)); String xml = returnedObject.getString("xml_result"); // String campaignName = returnedObject.getString("campaign_name"); CampaignXmlResponse candidate = new CampaignXmlResponse(); candidate.setXml(xml); candidate.setResponseStatus(Result.SUCCESS, null); return candidate; } catch (MalformedContentNameStringException e) { Log.e(TAG, "MalformedContentNameStringException while creating http entity", e); CampaignXmlResponse candidate = new CampaignXmlResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); CampaignXmlResponse candidate = new CampaignXmlResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("output_format", "xml")); nameValuePairs.add(new BasicNameValuePair("campaign_urn_list", campaignUrn)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return (CampaignXmlResponse) parseXmlResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); CampaignXmlResponse candidate = new CampaignXmlResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } } return null; } private CampaignXmlResponse parseXmlResponse(HttpResponse response) { Result result = Result.HTTP_ERROR; String[] errorCodes = null; CampaignXmlResponse candidate = new CampaignXmlResponse(); if (response != null) { Log.i(TAG, response.getStatusLine().toString()); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { if (responseEntity.getContentType().getValue().equals("text/xml")) { try { String xml = EntityUtils.toString(responseEntity); result = Result.SUCCESS; candidate.setXml(xml); } catch (ParseException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else if (responseEntity.getContentType().getValue().equals("text/html")) { try { String content = EntityUtils.toString(responseEntity); Log.i(TAG, content); JSONObject rootJson; rootJson = new JSONObject(content); if (rootJson.getString("result").equals("success")) { result = Result.INTERNAL_ERROR; Log.e(TAG, "CampaignReadXml should never return json with SUCCESS!"); } else { result = Result.FAILURE; JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } } catch (JSONException e) { Log.e(TAG, "Problem parsing response json", e); result = Result.INTERNAL_ERROR; } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else { result = Result.INTERNAL_ERROR; Log.e(TAG, "Unexpected content type returned for CampaignXmlRead."); } } else { Log.e(TAG, "No response entity in response"); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Returned status code: " + String.valueOf(response.getStatusLine().getStatusCode())); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Response is null"); result = Result.HTTP_ERROR; } candidate.setResponseStatus(result, errorCodes); return candidate; } /** * Returns survey responses for the specified campaign, with a number of parameters to filter the result.<br><br> * * Note that all results are subject to the specified user's permissions; even if results for other * users are requested, they won't be returned if the specified user does not have sufficient permission to view them.<br><br> * * Consult <a href="http://www.lecs.cs.ucla.edu/wikis/andwellness/index.php/AndWellness_Survey_Manipulation_2.4#Survey_Response__Read">the documentation on survey_response_read</a> for more information. * @param serverUrl the url of the server to contact for the list * @param username username of a valid user; will constrain the result in keeping with the user's permissions * @param hashedPassword hashed password of the aforementioned user * @param client the client used to retrieve the results, generally "android" * @param campaignUrn the urn of the campaign for which to retrieve survey results * @param userList a comma-separated list of usernames for which to return responses, or "urn:ohmage:special:all" (if null, "all" is assumed) * @param surveyIdList a comma-separated list of surveys for which to return results, or "urn:ohmage:special:all" (if null, "all" is assumed) * @param columnList a comma-separated lits of column values as specified in the docuemntation, or "urn:ohmage:special:all" (if null, "all" is assumed) * @param outputFormat one of json-rows, json-columns, or csv (FIXME: this method can't handle csv yet) * @param startDate must be present if end_date is present: allows querying against a date range. * @param endDate must be present if start_date is present; allows querying against a date range * @return an instance of type {@link ReadResponse} containing the resulting data; note that the Object returned by getData() is a JSONArray, not a JSONObject */ public SurveyReadResponse surveyResponseRead(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String userList, String surveyIdList, String columnList, String outputFormat, String startDate, String endDate) { final boolean GZIP = false; String url = serverUrl + SURVEYRESPONSE_READ_PATH; try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("campaign_urn", campaignUrn)); nameValuePairs.add( new BasicNameValuePair("user_list", (userList != null) ? userList : "urn:ohmage:special:all")); nameValuePairs.add(new BasicNameValuePair("survey_id_list", (surveyIdList != null) ? surveyIdList : "urn:ohmage:special:all")); nameValuePairs.add(new BasicNameValuePair("column_list", (columnList != null) ? columnList : "urn:ohmage:special:all")); nameValuePairs.add(new BasicNameValuePair("output_format", outputFormat)); if (startDate != null && endDate != null) { nameValuePairs.add(new BasicNameValuePair("start_date", startDate)); nameValuePairs.add(new BasicNameValuePair("end_date", endDate)); } UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return (SurveyReadResponse) parseReadResponse(doHttpPost(url, formEntity, GZIP), SurveyReadResponse.class); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); SurveyReadResponse candidate = new SurveyReadResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } } // same as above, except some parameters are substituted with their default values. // the defaults here retrieve all surveys for any users to whom we have access public SurveyReadResponse surveyResponseRead(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String columnList, String outputFormat) { return surveyResponseRead(serverUrl, username, hashedPassword, client, campaignUrn, null, null, columnList, outputFormat, null, null); } /** * Returns the image data associated with a given image id. * * @param serverUrl the url of the server to contact for the image data * @param username username of a valid user; will constrain the result in keeping with the user's permissions * @param hashedPassword hashed password of the aforementioned user * @param client the client used to retrieve the results, generally "android" * @param campaignUrn the urn of the campaign for which to retrieve survey results * @param owner the owner of the image for which we want the data * @param id the UUID of the image * @param size optional; if specified, must be "small" (if null, not passed) * @return */ public ImageReadResponse imageRead(String serverUrl, String username, String hashedPassword, String client, String campaignUrn, String owner, String id, String size) { final boolean GZIP = false; String url = serverUrl + IMAGE_READ_PATH; try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("user", username)); nameValuePairs.add(new BasicNameValuePair("password", hashedPassword)); nameValuePairs.add(new BasicNameValuePair("client", client)); nameValuePairs.add(new BasicNameValuePair("campaign_urn", campaignUrn)); nameValuePairs.add(new BasicNameValuePair("owner", owner)); nameValuePairs.add(new BasicNameValuePair("id", id)); if (size != null) nameValuePairs.add(new BasicNameValuePair("size", size)); UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairs); return parseImageReadResponse(doHttpPost(url, formEntity, GZIP)); } catch (IOException e) { Log.e(TAG, "IOException while creating http entity", e); ImageReadResponse candidate = new ImageReadResponse(); candidate.setResponseStatus(Result.INTERNAL_ERROR, null); return candidate; } } private HttpResponse doHttpPost(String url, HttpEntity requestEntity, boolean gzip) { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setConnectionTimeout(params, 20 * 1000); HttpConnectionParams.setSoTimeout(params, 20 * 1000); HttpConnectionParams.setSocketBufferSize(params, 8192); HttpClientParams.setRedirecting(params, false); SchemeRegistry schemeRegistry = new SchemeRegistry(); schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager manager = new ThreadSafeClientConnManager(params, schemeRegistry); HttpClient httpClient = new DefaultHttpClient(manager, params); HttpPost httpPost = new HttpPost(url); if (gzip) { try { //InputStream is = requestEntity.getContent(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); //BufferedOutputStream zipper = new BufferedOutputStream(new GZIPOutputStream(baos)); GZIPOutputStream zipper = new GZIPOutputStream(baos); requestEntity.writeTo(zipper); /* byte [] data2 = new byte[(int)formEntity.getContentLength()]; is.read(data2); String testing = new String(data2); Log.i("api", testing); zipper.write(data2);*/ /*int bufferSize = 1024; byte [] buffer = new byte [bufferSize]; int len = 0; String fullString = ""; while ((len = is.read(buffer, 0, bufferSize)) != -1) { zipper.write(buffer, 0, len); //fullString += new String(buffer, 0, len); Log.i("api", new String(buffer, 0, len)); } Log.i("api", fullString); is.close();*/ //zipper.flush(); //zipper.finish(); zipper.close(); ByteArrayEntity byteEntity = new ByteArrayEntity(baos.toByteArray()); //baos.close(); byteEntity.setContentEncoding("gzip"); httpPost.setEntity(byteEntity); } catch (IOException e) { Log.e(TAG, "Unable to gzip entity, using unzipped entity", e); httpPost.setEntity(requestEntity); } } else { httpPost.setEntity(requestEntity); } try { return httpClient.execute(httpPost); } catch (ClientProtocolException e) { Log.e(TAG, "ClientProtocolException while executing httpPost", e); return null; } catch (IOException e) { Log.e(TAG, "IOException while executing httpPost", e); return null; } } private AuthenticateResponse parseAuthenticateResponse(HttpResponse response) { Result result = Result.HTTP_ERROR; String hashedPassword = null; String authToken = null; String[] errorCodes = null; if (response != null) { Log.i(TAG, response.getStatusLine().toString()); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { try { String content = EntityUtils.toString(responseEntity); Log.i(TAG, content); JSONObject rootJson; rootJson = new JSONObject(content); if (rootJson.getString("result").equals("success")) { result = Result.SUCCESS; if (rootJson.has("hashed_password")) { hashedPassword = rootJson.getString("hashed_password"); } if (rootJson.has("token")) { authToken = rootJson.getString("token"); } } else { result = Result.FAILURE; JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } } catch (JSONException e) { Log.e(TAG, "Problem parsing response json", e); result = Result.INTERNAL_ERROR; } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else { Log.e(TAG, "No response entity in response"); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Returned status code: " + String.valueOf(response.getStatusLine().getStatusCode())); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Response is null"); result = Result.HTTP_ERROR; } return new AuthenticateResponse(result, hashedPassword, authToken, errorCodes); } private UploadResponse parseUploadResponse(HttpResponse response) { Result result = Result.HTTP_ERROR; String[] errorCodes = null; if (response != null) { Log.i(TAG, response.getStatusLine().toString()); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { try { String content = EntityUtils.toString(responseEntity); Log.i(TAG, content); JSONObject rootJson; rootJson = new JSONObject(content); if (rootJson.getString("result").equals("success")) { result = Result.SUCCESS; } else { result = Result.FAILURE; JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } } catch (JSONException e) { Log.e(TAG, "Problem parsing response json", e); result = Result.INTERNAL_ERROR; } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else { Log.e(TAG, "No response entity in response"); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Returned status code: " + String.valueOf(response.getStatusLine().getStatusCode())); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Response is null"); result = Result.HTTP_ERROR; } return new UploadResponse(result, errorCodes); } private Response parseReadResponse(HttpResponse response, Class<? extends Response> outputType) { Result result = Result.HTTP_ERROR; String[] errorCodes = null; // the response object that will be returned; its type is decided by outputType // it's also populated by a call to populateFromJSON() which transforms the server response into the Response object Response candidate; try { candidate = outputType.newInstance(); } catch (Exception e) { Log.e(TAG, "Problem instantiating response type", e); return null; } if (response != null) { Log.i(TAG, response.getStatusLine().toString()); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { try { String content = EntityUtils.toString(responseEntity); Log.i(TAG, content); JSONObject rootJson; rootJson = new JSONObject(content); if (rootJson.getString("result").equals("success")) { result = Result.SUCCESS; // allow the output type to determine how to extract data from the json collection candidate.populateFromJSON(rootJson); } else { result = Result.FAILURE; JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } } catch (JSONException e) { Log.e(TAG, "Problem parsing response json", e); result = Result.INTERNAL_ERROR; } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else { Log.e(TAG, "No response entity in response"); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Returned status code: " + String.valueOf(response.getStatusLine().getStatusCode())); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Response is null"); result = Result.HTTP_ERROR; } candidate.setResponseStatus(result, errorCodes); return candidate; } private ImageReadResponse parseImageReadResponse(HttpResponse response) { Result result = Result.HTTP_ERROR; String[] errorCodes = null; ImageReadResponse candidate = new ImageReadResponse(); if (response != null) { Log.i(TAG, response.getStatusLine().toString()); if (response.getStatusLine().getStatusCode() == 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { try { if (responseEntity.getContentType().getValue().startsWith("image/")) { // it's the image data! result = Result.SUCCESS; // dealing with raw image data here. hmm. byte[] content = EntityUtils.toByteArray(responseEntity); candidate.setData(content); candidate.setType(responseEntity.getContentType().getValue()); } else { // it was a JSON error instead result = Result.FAILURE; try { JSONObject rootJson = new JSONObject(EntityUtils.toString(responseEntity)); JSONArray errorsJsonArray = rootJson.getJSONArray("errors"); int errorCount = errorsJsonArray.length(); errorCodes = new String[errorCount]; for (int i = 0; i < errorCount; i++) { errorCodes[i] = errorsJsonArray.getJSONObject(i).getString("code"); } } catch (JSONException e) { Log.e(TAG, "Problem parsing response json", e); result = Result.INTERNAL_ERROR; } } } catch (IOException e) { Log.e(TAG, "Problem reading response body", e); result = Result.INTERNAL_ERROR; } } else { Log.e(TAG, "No response entity in response"); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Returned status code: " + String.valueOf(response.getStatusLine().getStatusCode())); result = Result.HTTP_ERROR; } } else { Log.e(TAG, "Response is null"); result = Result.HTTP_ERROR; } candidate.setResponseStatus(result, errorCodes); return candidate; } }