package org.neo4j.smack.test.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Map;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.codehaus.jackson.JsonParseException;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
public class RestRequest {
private final URI baseUri;
private final static Client DEFAULT_CLIENT = Client.create();
private final Client client;
public RestRequest(URI baseUri) {
this(baseUri, null, null);
}
public RestRequest(URI baseUri, String username, String password) {
this.baseUri = uriWithoutSlash(baseUri);
if (username != null) {
client = Client.create();
client.addFilter(new HTTPBasicAuthFilter(username, password));
} else {
client = DEFAULT_CLIENT;
}
}
public RestRequest(URI uri, Client client) {
this.baseUri = uriWithoutSlash(uri);
this.client = client;
}
public RestRequest() {
this(null);
}
private URI uriWithoutSlash(URI uri) {
if (uri == null)
return null;
String uriString = uri.toString();
return uriString.endsWith("/") ? uri(uriString.substring(0,
uriString.length() - 1)) : uri;
}
public static String encode(Object value) {
if (value == null)
return "";
try {
return URLEncoder.encode(value.toString(), "utf-8").replaceAll(
"\\+", "%20");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private Builder builder(String path) {
return builder(path, MediaType.APPLICATION_JSON_TYPE);
}
private Builder builder(String path, final MediaType accept) {
WebResource resource = client.resource(uri(pathOrAbsolute(path)));
return resource.accept(accept);
}
private String pathOrAbsolute(String path) {
if (path.startsWith("http://"))
return path;
return baseUri + "/" + path;
}
public JaxRsResponse get(String path) {
return JaxRsResponse.extractFrom(builder(path)
.get(ClientResponse.class));
}
public JaxRsResponse get(String path, String data) {
return get(path, data, MediaType.APPLICATION_JSON_TYPE);
}
public JaxRsResponse get(String path, String data, final MediaType mediaType) {
Builder builder = builder(path);
if (data != null) {
builder = builder.entity(data, mediaType);
} else {
builder = builder.type(mediaType);
}
return JaxRsResponse.extractFrom(builder.get(ClientResponse.class));
}
public JaxRsResponse delete(String path) {
return JaxRsResponse.extractFrom(builder(path).delete(
ClientResponse.class));
}
public JaxRsResponse post(String path, String data) {
return post(path, data, MediaType.APPLICATION_JSON_TYPE);
}
public JaxRsResponse post(String path, String data,
final MediaType mediaType) {
Builder builder = builder(path);
if (data != null) {
builder = builder.entity(data, mediaType);
} else {
builder = builder.type(mediaType);
}
return JaxRsResponse.extractFrom(builder.post(ClientResponse.class));
}
public JaxRsResponse put(String path, String data) {
Builder builder = builder(path);
if (data != null) {
builder = builder.entity(data, MediaType.APPLICATION_JSON_TYPE);
}
return new JaxRsResponse(builder.put(ClientResponse.class));
}
public Object toEntity(JaxRsResponse JaxRsResponse) throws JsonParseException, IOException {
return JsonHelper.jsonToSingleValue(entityString(JaxRsResponse));
}
public Map<?, ?> toMap(JaxRsResponse JaxRsResponse)
throws IOException {
final String json = entityString(JaxRsResponse);
return JsonHelper.jsonToMap(json);
}
private String entityString(JaxRsResponse JaxRsResponse) {
return JaxRsResponse.getEntity();
}
public boolean statusIs(JaxRsResponse JaxRsResponse,
Response.StatusType status) {
return JaxRsResponse.getStatus() == status.getStatusCode();
}
public boolean statusOtherThan(JaxRsResponse JaxRsResponse,
Response.StatusType status) {
return !statusIs(JaxRsResponse, status);
}
public RestRequest with(String uri) {
return new RestRequest(uri(uri), client);
}
private URI uri(String uri) {
try {
return new URI(uri);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public URI getUri() {
return baseUri;
}
public JaxRsResponse get() {
return get("");
}
public JaxRsResponse get(String path, final MediaType acceptType) {
Builder builder = builder(path, acceptType);
return JaxRsResponse.extractFrom(builder.get(ClientResponse.class));
}
public static RestRequest req() {
return new RestRequest();
}
public JaxRsResponse delete(URI location) {
return delete(location.toString());
}
public JaxRsResponse put(URI uri, String data) {
return put(uri.toString(), data);
}
}