package org.openxdm.xcap.client;
import java.io.IOException;
import java.util.List;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openxdm.xcap.common.http.HttpConstant;
import org.openxdm.xcap.common.key.XcapUriKey;
public class XCAPClientImpl implements XCAPClient {
private static final Log log = LogFactory.getLog(XCAPClientImpl.class);
private HttpClient client;
private String xcapRoot;
private boolean doAuthentication = false;
public XCAPClientImpl(String host,int port,String xcapRoot) throws InterruptedException {
this.xcapRoot = xcapRoot;
// create http client
client = new HttpClient(new MultiThreadedHttpConnectionManager());
// configure for relative path requests
client.getHostConfiguration().setHost(host, port, "http");
// set params
client.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
//client.getParams().setParameter("http.socket.timeout", new Integer(10000));
client.getParams().setParameter("http.protocol.content-charset", "UTF-8");
}
// CLIENT MANAGEMENT
public boolean getDoAuthentication() {
return doAuthentication;
}
public void setDoAuthentication(boolean value) {
this.doAuthentication = value;
}
public void setAuthenticationCredentials(String userName, String password) {
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName,password));
}
public void shutdown() {
log.info("shutdown()");
if(client != null) {
((MultiThreadedHttpConnectionManager)client.getHttpConnectionManager()).shutdown();
}
}
// CLIENT OPERATIONS
private String addXcapRoot(String path) {
return xcapRoot + path;
}
private Response getResponse(XcapUriKey key, HttpMethod method) throws IOException {
// get status code
int statusCode = method.getStatusCode();
// get headers
Header[] headers = method.getResponseHeaders();
String content = null;
String eTag = null;
if(statusCode == 200 || statusCode == 201) {
// sucessful response
// get content as string
content = method.getResponseBodyAsString();
// get etag
Header eTagHeader = method.getResponseHeader(HttpConstant.HEADER_ETAG);
if(eTagHeader != null) {
eTag = eTagHeader.getValue();
}
}
else if (statusCode == 409) {
content = method.getResponseBodyAsString();
}
Response response = new Response(statusCode,eTag,headers,content);
if (log.isDebugEnabled()) {
log.debug("Received:\n--BEGIN--\n"+response.toString()+"\n--END--");
}
return response;
}
private void addAdditionalRequestHeaders(HttpMethodBase request, List<RequestHeader> additionalRequestHeaders) {
if (additionalRequestHeaders != null) {
for(RequestHeader header : additionalRequestHeaders) {
request.addRequestHeader(header.getName(),header.getValue());
}
}
}
public Response get(XcapUriKey key, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("get(key="+key+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
GetMethod get = new GetMethod(addXcapRoot(key.toString()));
get.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(get, additionalRequestHeaders);
try {
// execute method
client.executeMethod(get);
// get response
response = getResponse(key,get);
}
finally {
// be sure the connection is released back to the connection manager
get.releaseConnection();
}
return response;
}
public Response put(XcapUriKey key, String mimetype, String content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("put(key="+key+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set content
put.setRequestEntity(new StringRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response putIfMatch(XcapUriKey key, String eTag, String mimetype, String content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("putIfMatch(key="+key+", eTag="+eTag+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set if match
put.setRequestHeader(HttpConstant.HEADER_IF_MATCH,eTag);
// set content
put.setRequestEntity(new StringRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response putIfNoneMatch(XcapUriKey key, String eTag, String mimetype, String content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("putIfNoneMatch(key="+key+", eTag="+eTag+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set if match
put.setRequestHeader(HttpConstant.HEADER_IF_NONE_MATCH,eTag);
// set content
put.setRequestEntity(new StringRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response put(XcapUriKey key, String mimetype, byte[] content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("put(key="+key+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set content
put.setRequestEntity(new ByteArrayRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response putIfMatch(XcapUriKey key, String eTag, String mimetype, byte[] content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("putIfMatch(key="+key+", eTag="+eTag+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set if match
put.setRequestHeader(HttpConstant.HEADER_IF_MATCH,eTag);
// set content
put.setRequestEntity(new ByteArrayRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response putIfNoneMatch(XcapUriKey key, String eTag, String mimetype, byte[] content, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("putIfNoneMatch(key="+key+", eTag="+eTag+", mimetype="+mimetype+", content="+content+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
PutMethod put = new PutMethod(addXcapRoot(key.toString()));
put.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(put, additionalRequestHeaders);
// set mimetype
put.setRequestHeader(HttpConstant.HEADER_CONTENT_TYPE,mimetype);
// set if match
put.setRequestHeader(HttpConstant.HEADER_IF_NONE_MATCH,eTag);
// set content
put.setRequestEntity(new ByteArrayRequestEntity(content));
try {
// execute method
client.executeMethod(put);
// get response
response = getResponse(key,put);
}
finally {
// be sure the connection is released back to the connection manager
put.releaseConnection();
}
return response;
}
public Response delete(XcapUriKey key, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("delete(key="+key+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
DeleteMethod delete = new DeleteMethod(addXcapRoot(key.toString()));
delete.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(delete, additionalRequestHeaders);
try {
// execute method
client.executeMethod(delete);
// get response
response = getResponse(key,delete);
}
finally {
// be sure the connection is released back to the connection manager
delete.releaseConnection();
}
return response;
}
public Response deleteIfMatch(XcapUriKey key, String eTag, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("deleteIfMatch(key="+key+", eTag="+eTag+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
DeleteMethod delete = new DeleteMethod(addXcapRoot(key.toString()));
delete.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(delete, additionalRequestHeaders);
try {
// set if match
delete.setRequestHeader(HttpConstant.HEADER_IF_MATCH,eTag);
// execute method
client.executeMethod(delete);
// get response
response = getResponse(key,delete);
}
finally {
// be sure the connection is released back to the connection manager
delete.releaseConnection();
}
return response;
}
public Response deleteIfNoneMatch(XcapUriKey key, String eTag, List<RequestHeader> additionalRequestHeaders) throws HttpException, IOException {
if (log.isDebugEnabled()) {
log.debug("deleteIfNoneMatch( key = "+key+" , eTag = "+eTag+" , additionalRequestHeaders = ( "+additionalRequestHeaders+" ) )");
}
Response response = null;
// create method with key uri
DeleteMethod delete = new DeleteMethod(addXcapRoot(key.toString()));
delete.setDoAuthentication(doAuthentication);
// add additional headers
addAdditionalRequestHeaders(delete, additionalRequestHeaders);
try {
// set if match
delete.setRequestHeader(HttpConstant.HEADER_IF_NONE_MATCH,eTag);
// execute method
client.executeMethod(delete);
// get response
response = getResponse(key,delete);
}
finally {
// be sure the connection is released back to the connection manager
delete.releaseConnection();
}
return response;
}
}