package org.dodgybits.shuffle.android.synchronisation.tracks;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
/**
* Handles communication to the REST service
*
* @author Morten Nielsen
*/
public class WebClient {
private String sUserAgent;
private byte[] sBuffer = new byte[512];
private final String tracksUser;
private final String tracksPassword;
private final String cTag = "WebClient";
public WebClient(Context context, String tracksUser, String tracksPassword) throws ApiException {
this.tracksUser = tracksUser;
this.tracksPassword = tracksPassword;
PackageManager manager = context.getPackageManager();
PackageInfo info = null;
try {
info = manager.getPackageInfo(context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException ignored) {
}
if (info != null) {
sUserAgent = String.format("%1$s %2$s",
info.packageName, info.versionName);
}
}
protected synchronized boolean deleteUrl(String url) throws ApiException {
if (sUserAgent == null) {
throw new ApiException("User-Agent string must be prepared");
}
// Create client and set our specific user-agent string
HttpClient client = CreateClient();
java.net.URI uri = URI.create(url);
HttpHost host = GetHost(uri);
HttpDelete request = new HttpDelete(uri.getPath());
request.setHeader("User-Agent", sUserAgent);
try {
HttpResponse response = client.execute(host, request);
// Check if server response is valid
StatusLine status = response.getStatusLine();
Log.i(cTag, "delete with response " + status.toString());
return status.getStatusCode() == HttpStatus.SC_OK;
} catch (IOException e) {
throw new ApiException("Problem communicating with API", e);
}
}
private HttpClient CreateClient() {
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(tracksUser, tracksPassword));
return client;
}
public synchronized String getUrlContent(String url) throws ApiException {
if (sUserAgent == null) {
throw new ApiException("User-Agent string must be prepared");
}
// Create client and set our specific user-agent string
HttpClient client = CreateClient();
java.net.URI uri = URI.create(url);
HttpHost host = GetHost(uri);
HttpGet request = new HttpGet(uri.getPath());
request.setHeader("User-Agent", sUserAgent);
try {
HttpResponse response = client.execute(host, request);
// Check if server response is valid
StatusLine status = response.getStatusLine();
Log.i(cTag, "get with response " + status.toString());
if (status.getStatusCode() != HttpStatus.SC_OK) {
throw new ApiException("Invalid response from server: " +
status.toString());
}
// Pull content stream from response
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
ByteArrayOutputStream content = new ByteArrayOutputStream();
// Read response into a buffered stream
int readBytes;
while ((readBytes = inputStream.read(sBuffer)) != -1) {
content.write(sBuffer, 0, readBytes);
}
return new String(content.toByteArray());
} catch (IOException e) {
throw new ApiException("Problem communicating with API", e);
}
}
private HttpHost GetHost(URI uri) {
HttpHost host;
int port = uri.getPort();
if (port == -1) {
port = uri.getScheme().equalsIgnoreCase("https") ? 443 : 80;
}
host = new HttpHost(uri.getHost(), port, uri.getScheme());
return host;
}
protected synchronized String postContentToUrl(String url, String content) throws ApiException {
if (sUserAgent == null) {
throw new ApiException("User-Agent string must be prepared");
}
// Create client and set our specific user-agent string
HttpClient client = CreateClient();
java.net.URI uri = URI.create(url);
HttpHost host = GetHost(uri);
HttpPost request = new HttpPost(uri.getPath());
request.setHeader("User-Agent", sUserAgent);
request.setHeader("Content-Type", "text/xml");
HttpEntity ent;
try {
ent = new StringEntity(content, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new ApiException("unsupported encoding set", e);
}
request.setEntity(ent);
try {
HttpResponse response = client.execute(host, request);
// Check if server response is valid
StatusLine status = response.getStatusLine();
Log.i(cTag, "post with response " + status.toString());
if (status.getStatusCode() != HttpStatus.SC_CREATED) {
throw new ApiException("Invalid response from server: " +
status.toString() + " for content: " + content);
}
Header[] header = response.getHeaders("Location");
if (header.length != 0) return header[0].getValue();
else return null;
} catch (IOException e) {
throw new ApiException("Problem communicating with API", e);
}
}
protected synchronized String putContentToUrl(String url, String content) throws ApiException {
if (sUserAgent == null) {
throw new ApiException("User-Agent string must be prepared");
}
// Create client and set our specific user-agent string
HttpClient client = CreateClient();
java.net.URI uri = URI.create(url);
HttpHost host = GetHost(uri);
HttpPut request = new HttpPut(uri.getPath());
request.setHeader("User-Agent", sUserAgent);
request.setHeader("Content-Type", "text/xml");
HttpEntity ent;
try {
ent = new StringEntity(content, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new ApiException("unsupported encoding", e);
}
request.setEntity(ent);
try {
HttpResponse response = client.execute(host, request);
// Check if server response is valid
StatusLine status = response.getStatusLine();
Log.i(cTag, "put with response " + status.toString());
if (status.getStatusCode() != HttpStatus.SC_OK) {
throw new ApiException("Invalid response from server: " +
status.toString());
}
// Pull returnContent stream from response
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
ByteArrayOutputStream returnContent = new ByteArrayOutputStream();
// Read response into a buffered stream
int readBytes;
while ((readBytes = inputStream.read(sBuffer)) != -1) {
returnContent.write(sBuffer, 0, readBytes);
}
return new String(returnContent.toByteArray());
} catch (IOException e) {
throw new ApiException("Problem communicating with API", e);
}
}
@SuppressWarnings("serial")
public class ApiException extends Exception {
public ApiException(String reason) {
super(reason);
}
public ApiException(String reason, Exception e) {
super(reason, e);
}
}
}