HTTPCLIENT-1076: initial check-in of the fluent facade API for HttpClient developed by Xu Lilu for the Google summer of code 2011

Contributed by Xu Lilu <cookieme at gmail.com>


git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1157347 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2011-08-13 08:31:50 +00:00
parent bf13db8115
commit da5aebe735
12 changed files with 1931 additions and 0 deletions

133
fluent-hc/pom.xml Normal file
View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
====================================================================
This software consists of voluntary contributions made by many
individuals on behalf of the Apache Software Foundation. For more
information on the Apache Software Foundation, please see
<http://www.apache.org />.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcomponents-client</artifactId>
<version>4.2-alpha1-SNAPSHOT</version>
</parent>
<artifactId>fluent-hc</artifactId>
<name>HttpClient fluent</name>
<description>
HttpComponents Client fluent API
</description>
<url>http://hc.apache.org/httpcomponents-client</url>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compile.source>1.5</maven.compile.source>
<maven.compile.target>1.5</maven.compile.target>
<maven.compile.optimize>true</maven.compile.optimize>
<maven.compile.deprecation>true</maven.compile.deprecation>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compile.source}</source>
<target>${maven.compile.target}</target>
<optimize>${maven.compile.optimize}</optimize>
<showDeprecations>${maven.compile.deprecation}</showDeprecations>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<!-- reduce console output. Can override with -Dquiet=false -->
<quiet>true</quiet>
<source>1.5</source>
<links>
<link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
<link>http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/</link>
<link>http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/</link>
</links>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<artifactId>maven-jxr-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-surefire-report-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,163 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
import java.io.IOException;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
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.scheme.SchemeSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SchemeRegistryFactory;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
public class FluentExecutor {
public static FluentExecutor newInstance() {
FluentExecutor fexe = new FluentExecutor();
return fexe;
}
private ThreadSafeClientConnManager localConnManager;
private SchemeRegistry localSchemeRegistry;
private SchemeSocketFactory localSocketFactory;
private FluentExecutor() {
localSchemeRegistry = SchemeRegistryFactory.createDefault();
localConnManager = new ThreadSafeClientConnManager(localSchemeRegistry);
localSocketFactory = PlainSocketFactory.getSocketFactory();
}
public FluentResponse exec(FluentRequest req)
throws ClientProtocolException, IOException {
DefaultHttpClient client = getClient();
client.setCredentialsProvider(req.credentialsProvider);
client.setParams(req.localParams);
HttpResponse resp = client.execute(req, req.localContext);
FluentResponse fresp = new FluentResponse(resp);
return fresp;
}
public FluentResponse[] exec(final FluentRequest[] reqs)
throws InterruptedException {
if (reqs == null)
throw new NullPointerException("The request array may not be null.");
int length = reqs.length;
if (length == 0)
return new FluentResponse[0];
FluentResponse[] resps = new FluentResponse[length];
MultiRequestThread[] threads = new MultiRequestThread[length];
for (int id = 0; id < length; id++) {
threads[id] = new MultiRequestThread(this, reqs, resps, id);
}
for (int id = 0; id < length; id++) {
threads[id].start();
}
for (int id = 0; id < length; id++) {
threads[id].join();
}
return resps;
}
public DefaultHttpClient getClient() {
DefaultHttpClient client;
client = new DefaultHttpClient(localConnManager);
return client;
}
public int getMaxConnectionsPerRoute() {
return localConnManager.getDefaultMaxPerRoute();
}
public int getMaxTotalConnections() {
return localConnManager.getMaxTotal();
}
public Scheme getScheme(final String name) {
return localSchemeRegistry.getScheme(name);
}
public List<String> getSchemeNames() {
List<String> schemeNames = localSchemeRegistry.getSchemeNames();
return schemeNames;
}
public FluentExecutor registerScheme(final String name, final int port) {
Scheme sch = new Scheme(name, port, localSocketFactory);
localSchemeRegistry.register(sch);
return this;
}
public FluentExecutor setMaxConnectionsPerRoute(final int maxPerRoute) {
localConnManager.setDefaultMaxPerRoute(maxPerRoute);
return this;
}
public FluentExecutor setMaxTotalConnections(final int maxTotal) {
localConnManager.setMaxTotal(maxTotal);
return this;
}
public FluentExecutor unregisterAllSchemes() {
for (String name : getSchemeNames())
localSchemeRegistry.unregister(name);
return this;
}
public FluentExecutor unregisterScheme(final String name) {
localSchemeRegistry.unregister(name);
return this;
}
}
class MultiRequestThread extends Thread {
private FluentExecutor executor;
private FluentRequest[] reqs;
private FluentResponse[] resps;
private int id;
MultiRequestThread(final FluentExecutor executor,
final FluentRequest[] reqs, final FluentResponse[] resps,
final int id) {
this.executor = executor;
this.reqs = reqs;
this.resps = resps;
this.id = id;
}
@Override
public void run() {
FluentRequest req = reqs[id];
try {
FluentResponse resp = executor.exec(req);
resp.loadContent();
resps[id] = resp;
} catch (Exception e) {
req.abort();
}
}
}

View File

@ -0,0 +1,33 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
public class FluentHttp {
public static final int GET_METHOD = 0;
public static final int POST_METHOD = 1;
public static final int DELETE_METHOD = 2;
public static final int PUT_METHOD = 3;
public static final int OPTION_METHOD = 4;
public static final int TRACE_METHOD = 5;
public static final String REQUEST_INTERCEPTORS = "httpclinet.request.interceptors";
public static final String RESPONSE_INTERCEPTORS = "httpclinet.response.interceptors";
}

View File

@ -0,0 +1,26 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
public enum FluentHttpMethod {
GET_METHOD, POST_METHOD, DELETE_METHOD, OPTIONS_METHOD, PUT_METHOD, HEAD_METHOD, TRACE_METHOD;
}

View File

@ -0,0 +1,571 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.fluent.header.DateUtils;
import org.apache.http.client.fluent.header.HttpHeader;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
public class FluentRequest implements HttpUriRequest {
static FluentRequest build(final URI uri, final FluentHttpMethod method) {
FluentRequest req = new FluentRequest();
req.by(method, uri);
req.init();
return req;
}
HttpParams localParams;
HttpContext localContext;
CredentialsProvider credentialsProvider;
private HttpUriRequest request;
private FluentHttpMethod method;
private HttpHost localProxy;
protected static final Log log = LogFactory.getLog(FluentRequest.class);
private FluentRequest() {
// DO NOTHING
}
public FluentRequest(final HttpUriRequest req) {
this.request = req;
String methodName = request.getMethod().toUpperCase();
if (methodName.equals("GET"))
this.method = FluentHttpMethod.GET_METHOD;
else if (methodName.equals("POST"))
this.method = FluentHttpMethod.POST_METHOD;
else if (methodName.equals("OPTIONS"))
this.method = FluentHttpMethod.OPTIONS_METHOD;
else if (methodName.equals("DELETE"))
this.method = FluentHttpMethod.DELETE_METHOD;
else if (methodName.equals("HEAD"))
this.method = FluentHttpMethod.HEAD_METHOD;
else if (methodName.equals("PUT"))
this.method = FluentHttpMethod.PUT_METHOD;
else if (methodName.equals("TRACE"))
this.method = FluentHttpMethod.TRACE_METHOD;
else
this.method = FluentHttpMethod.GET_METHOD;
init();
}
public FluentRequest(final String uri) {
copyFrom(RequestBuilder.build(uri));
}
public FluentRequest(final String uri, final FluentHttpMethod method) {
copyFrom(RequestBuilder.build(uri, method));
}
public FluentRequest(final URI uri) {
copyFrom(RequestBuilder.build(uri));
}
public FluentRequest(final URI uri, final FluentHttpMethod method) {
copyFrom(RequestBuilder.build(uri, method));
}
public void abort() throws UnsupportedOperationException {
this.request.abort();
}
public void addHeader(final Header header) {
this.request.addHeader(header);
}
public void addHeader(final String name, final String value) {
this.request.addHeader(name, value);
}
/**
* Change the HTTP method used within this request.
*
* @param method
* which indicates the HTTP method need to use
* @return modified request
*/
private FluentRequest by(final FluentHttpMethod method, final URI uri) {
switch (method) {
case GET_METHOD:
this.request = new HttpGet(uri);
break;
case POST_METHOD:
this.request = new HttpPost(uri);
break;
case OPTIONS_METHOD:
this.request = new HttpOptions(uri);
break;
case DELETE_METHOD:
this.request = new HttpDelete(uri);
break;
case HEAD_METHOD:
this.request = new HttpHead(uri);
break;
case PUT_METHOD:
this.request = new HttpPut(uri);
break;
case TRACE_METHOD:
this.request = new HttpTrace(uri);
break;
}
this.method = method;
return this;
}
public boolean containsHeader(final String name) {
return this.request.containsHeader(name);
}
private void copyFrom(FluentRequest other) {
this.request = other.request;
this.method = other.method;
this.localContext = other.localContext;
this.localParams = other.localParams;
this.localProxy = other.localProxy;
this.credentialsProvider = other.credentialsProvider;
}
/**
*
* @return a <code>FluentResponse</code> instance referring to the response
* of this request
* @throws ClientProtocolException
* @throws IOException
*/
public FluentResponse exec() throws ClientProtocolException, IOException {
DefaultHttpClient client = new DefaultHttpClient();
return new FluentResponse(client.execute(request));
}
public Header[] getAllHeaders() {
return this.request.getAllHeaders();
}
public String getCacheControl() {
return getValueOfHeader(HttpHeader.CACHE_CONTROL);
}
public int getConnectionTimeout() {
return HttpConnectionParams.getConnectionTimeout(localParams);
}
public String getContentCharset() {
return (String) localParams
.getParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET);
}
public long getContentLength() {
String value = getValueOfHeader(HttpHeader.CONTENT_LENGTH);
if (value == null)
return -1;
else {
long contentLength = Long.parseLong(value);
return contentLength;
}
}
public String getContentType() {
return getValueOfHeader(HttpHeader.CONTENT_TYPE);
}
public CredentialsProvider getCredentialProvider() {
return credentialsProvider;
}
public String getDate() {
return getValueOfHeader(HttpHeader.DATE);
}
public String getElementCharset() {
return (String) localParams
.getParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET);
}
public Header getFirstHeader(final String name) {
return this.request.getFirstHeader(name);
}
public Header[] getHeaders(final String name) {
return this.request.getHeaders(name);
}
/**
* Returns the HTTP method as a field of <code><a
* href="FunHttpMethod.html">FunHttpMethod</a></code> enumeration, such as
* <code>GET</code>, <code>PUT</code>, <code>POST</code>, or other.
*
* @return a field of <a href="FunHttpMethod.html">FunHttpMethod</a>
* enumeration indicates the name of HTTP method
*/
public FluentHttpMethod getHttpMethod() {
return method;
}
public String getIfModifiedSince() {
return getValueOfHeader(HttpHeader.IF_MODIFIED_SINCE);
}
public String getIfUnmodifiedSince() {
return getValueOfHeader(HttpHeader.IF_UNMODIFIED_SINCE);
}
public Header getLastHeader(final String name) {
return this.request.getLastHeader(name);
}
public String getMethod() {
return this.request.getMethod();
}
public HttpParams getParams() {
return this.request.getParams();
}
public ProtocolVersion getProtocolVersion() {
return this.request.getProtocolVersion();
}
public RequestLine getRequestLine() {
return this.request.getRequestLine();
}
public int getSocketTimeout() {
return HttpConnectionParams.getSoTimeout(localParams);
}
public boolean isStrictTransferEncoding() {
return (Boolean) localParams
.getParameter(CoreProtocolPNames.STRICT_TRANSFER_ENCODING);
}
public URI getURI() {
return this.request.getURI();
}
public boolean isUseExpectContinue() {
return (Boolean) localParams
.getParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE);
}
public String getUserAgent() {
return (String) localParams.getParameter(CoreProtocolPNames.USER_AGENT);
}
private String getValueOfHeader(final String headerName) {
Header header = request.getFirstHeader(headerName);
if (header != null)
return header.getValue();
else
return null;
}
public int getWaitForContinue() {
return (Integer) localParams
.getParameter(CoreProtocolPNames.WAIT_FOR_CONTINUE);
}
public HeaderIterator headerIterator() {
return this.request.headerIterator();
}
public HeaderIterator headerIterator(final String name) {
return this.request.headerIterator(name);
}
private void init() {
localParams = request.getParams();
localContext = new BasicHttpContext();
credentialsProvider = new BasicCredentialsProvider();
localProxy = null;
}
public boolean isAborted() {
return this.request.isAborted();
}
public FluentRequest removeAuth() {
return setAuth(null);
}
public void removeHeader(final Header header) {
this.request.removeHeader(header);
}
public void removeHeaders(final String name) {
this.request.removeHeaders(name);
}
public FluentRequest removeProxy() {
setProxyAuth(null);
localParams.removeParameter(ConnRoutePNames.DEFAULT_PROXY);
localProxy = null;
return this;
}
public FluentRequest setAuth(final Credentials cred) {
String hostAddr = request.getURI().getHost();
credentialsProvider.setCredentials(new AuthScope(hostAddr,
AuthScope.ANY_PORT), cred);
AuthCache authCache = new BasicAuthCache();
HttpHost authHost = new HttpHost(hostAddr);
authCache.put(authHost, new BasicScheme());
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
return this;
}
public FluentRequest setAuth(final String username, final String password) {
return setAuth(new UsernamePasswordCredentials(username, password));
}
public FluentRequest setAuth(final String username, final String password,
final String workstation, final String domain) {
return setAuth(new NTCredentials(username, password, workstation,
domain));
}
public FluentRequest setCacheControl(String cacheControl) {
request.setHeader(HttpHeader.CACHE_CONTROL, cacheControl);
return this;
}
public FluentRequest setConnectionTimeout(final int connectionTimeoutMillis) {
HttpConnectionParams.setConnectionTimeout(localParams,
connectionTimeoutMillis);
return this;
}
public FluentRequest setContentCharset(final String charset) {
localParams.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET,
charset);
return this;
}
public FluentRequest setContentLength(final long contentLength) {
request.setHeader(HttpHeader.CONTENT_LENGTH,
String.valueOf(contentLength));
return this;
}
public FluentRequest setContentType(final String contentType) {
request.setHeader(HttpHeader.CONTENT_TYPE, contentType);
return this;
}
public FluentRequest setCredentialProvider(
final CredentialsProvider credProvider) {
credentialsProvider = credProvider;
return this;
}
public FluentRequest setDate(final Date date) {
String formattedDate = DateUtils.format(date);
request.setHeader(HttpHeader.DATE, formattedDate);
return this;
}
public FluentRequest setElementCharset(final String charset) {
localParams.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET,
charset);
return this;
}
public FluentRequest setEntity(final HttpEntity entity) {
log.warn("");
this.by(FluentHttpMethod.POST_METHOD, this.request.getURI());
HttpPost post = (HttpPost) this.request;
post.setEntity(entity);
return this;
}
public FluentRequest setHTMLFormEntity(final Map<String, String> form,
final String encoding) throws UnsupportedEncodingException {
List<NameValuePair> formparams = new ArrayList<NameValuePair>(
form.size());
for (String name : form.keySet()) {
formparams.add(new BasicNameValuePair(name, form.get("name")));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams,
encoding);
return setEntity(entity);
}
public void setHeader(final Header header) {
this.request.setHeader(header);
}
public void setHeader(final String name, final String value) {
this.request.setHeader(name, value);
}
public void setHeaders(final Header[] headers) {
this.request.setHeaders(headers);
}
public FluentRequest setIfModifiedSince(final Date date) {
String formattedDate = DateUtils.format(date);
request.setHeader(HttpHeader.IF_MODIFIED_SINCE, formattedDate);
return this;
}
public FluentRequest setIfUnmodifiedSince(final Date date) {
String formattedDate = DateUtils.format(date);
request.setHeader(HttpHeader.IF_UNMODIFIED_SINCE, formattedDate);
return this;
}
public void setParams(final HttpParams params) {
this.request.setParams(params);
}
public FluentRequest setProtocolVersion(HttpVersion version) {
localParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, version);
return this;
}
public FluentRequest setProxy(final String proxyAddr, final int proxyPort) {
return setProxy(proxyAddr, proxyPort, null, null);
}
public FluentRequest setProxy(final String proxyAddr, final int proxyPort,
final String username, final String password) {
localProxy = new HttpHost(proxyAddr, proxyPort);
localParams.setParameter(ConnRoutePNames.DEFAULT_PROXY, localProxy);
if (username != null) {
setProxyAuth(username, password);
}
return this;
}
public FluentRequest setProxyAuth(final Credentials proxyAuth) {
if (localProxy == null)
throw new IllegalStateException("HTTP proxy is not used.");
credentialsProvider.setCredentials(
new AuthScope(localProxy.getHostName(), localProxy.getPort()),
proxyAuth);
return this;
}
public FluentRequest setProxyAuth(final String username,
final String password) {
return setProxyAuth(new UsernamePasswordCredentials(username, password));
}
public FluentRequest setProxyAuth(final String username,
final String password, final String workstation, final String domain) {
return setProxyAuth(new NTCredentials(username, password, workstation,
domain));
}
public FluentRequest setSocketTimeout(int socketTimeoutMillis) {
HttpConnectionParams.setSoTimeout(localParams, socketTimeoutMillis);
return this;
}
public FluentRequest setStrictTransferEncoding(final boolean bool) {
localParams.setBooleanParameter(
CoreProtocolPNames.STRICT_TRANSFER_ENCODING, bool);
return this;
}
public FluentRequest setUseExpectContinue(Boolean bool) {
localParams.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,
bool);
return this;
}
public FluentRequest setUserAgent(final String agent) {
localParams.setParameter(CoreProtocolPNames.USER_AGENT, agent);
return this;
}
public FluentRequest setWaitForContinue(final int waitMillis) {
localParams.setIntParameter(CoreProtocolPNames.WAIT_FOR_CONTINUE,
waitMillis);
return this;
}
}

View File

@ -0,0 +1,322 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Scanner;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.fluent.header.HttpHeader;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
public class FluentResponse implements HttpResponse {
protected static final Log log = LogFactory.getLog(FluentResponse.class);
private HttpResponse response;
private byte[] content;
private String contentString;
private boolean consumed;
FluentResponse(HttpResponse response) {
this.response = response;
consumed = false;
}
public int getStatusCode() {
return this.getStatusLine().getStatusCode();
}
public FluentResponse loadContent() throws IOException {
if (getEntity() == null)
content = null;
else {
content = EntityUtils.toByteArray(getEntity());
EntityUtils.consume(getEntity());
}
consumed = true;
return this;
}
public void addHeader(Header header) {
this.response.addHeader(header);
}
public void addHeader(String name, String value) {
this.response.addHeader(name, value);
}
public FluentResponse cacheControl(String cacheControl) {
response.setHeader(HttpHeader.CACHE_CONTROL, cacheControl);
return this;
}
public boolean containsHeader(String name) {
return this.response.containsHeader(name);
}
public Header[] getAllHeaders() {
return this.response.getAllHeaders();
}
public String getCacheControl() {
return getValueOfHeader(HttpHeader.CACHE_CONTROL);
}
public InputStream getContent() throws IllegalStateException, IOException {
return this.response.getEntity().getContent();
}
public byte[] getContentByteArray() throws IllegalStateException,
IOException {
if (!consumed)
loadContent();
return content;
}
public String getContentCharset() {
// if (this.getEntity() == null)
// throw new IllegalStateException("Response does not contain data");
// Header contentType = this.getEntity().getContentType();
// if (contentType == null)
// throw new IllegalStateException(
// "Reponse does not contain Content-Type header");
// NameValuePair charset = contentType.getElements()[0]
// .getParameterByName("charset");
// if (charset == null || charset.getValue().trim().equals("")) {
// log.warn("Charset could not be found in response");
// return Charset.defaultCharset().name();
// } else
// return charset.getValue();
return EntityUtils.getContentCharSet(getEntity());
}
public String getContentEncoding() {
if (this.getEntity() == null)
throw new IllegalStateException("Response does not contain data");
Header contentEncoding = this.getEntity().getContentEncoding();
if (contentEncoding == null) {
log.warn("Response does not contain Content-Encoding header");
return System.getProperty("file.encoding");
} else
return contentEncoding.getValue();
}
public long getContentLength() {
String value = getValueOfHeader(HttpHeader.CONTENT_LENGTH);
if (value == null)
return -1;
else {
long contentLength = Long.parseLong(value);
return contentLength;
}
}
public String getContentString() throws IOException {
if (contentString != null)
return contentString;
if (this.getEntity() == null)
return null;
String contentCharset = this.getContentCharset();
return getContentString(contentCharset);
}
public String getContentString(String encoding) throws IOException {
if (contentString != null)
return contentString;
if (getContentByteArray() == null)
return null;
if (encoding == null)
contentString = new String(content);
else
contentString = new String(content, encoding);
return contentString;
}
public String getContentType() {
if (this.getEntity() == null)
throw new IllegalStateException("Response does not contain data");
Header contentType = this.getEntity().getContentType();
if (contentType == null)
throw new IllegalStateException(
"Reponse does not contain Content-Type header");
return contentType.getElements()[0].getName();
}
public HttpEntity getEntity() {
return this.response.getEntity();
}
public Header getFirstHeader(String name) {
return this.response.getFirstHeader(name);
}
public Header[] getHeaders(String name) {
return this.response.getHeaders(name);
}
public Header getLastHeader(String name) {
return this.response.getLastHeader(name);
}
public Locale getLocale() {
return this.response.getLocale();
}
public HttpParams getParams() {
return this.response.getParams();
}
public ProtocolVersion getProtocolVersion() {
return this.response.getProtocolVersion();
}
public StatusLine getStatusLine() {
return this.response.getStatusLine();
}
private String getValueOfHeader(String headerName) {
Header header = response.getFirstHeader(headerName);
if (header != null)
return header.getValue();
else
return null;
}
public HeaderIterator headerIterator() {
return this.response.headerIterator();
}
public HeaderIterator headerIterator(String name) {
return this.response.headerIterator(name);
}
public void removeHeader(Header header) {
this.response.removeHeader(header);
}
public void removeHeaders(String name) {
this.response.removeHeaders(name);
}
public void setEntity(HttpEntity entity) {
this.response.setEntity(entity);
}
public void setHeader(Header header) {
this.response.setHeader(header);
}
public void setHeader(String name, String value) {
this.response.setHeader(name, value);
}
public void setHeaders(Header[] headers) {
this.response.setHeaders(headers);
}
public void setLocale(Locale loc) {
this.response.setLocale(loc);
}
public void setParams(HttpParams params) {
this.response.setParams(params);
}
public void setReasonPhrase(String reason) throws IllegalStateException {
this.response.setReasonPhrase(reason);
}
public void setStatusCode(int code) throws IllegalStateException {
this.response.setStatusCode(code);
}
public void setStatusLine(ProtocolVersion ver, int code) {
this.response.setStatusLine(ver, code);
}
public void setStatusLine(ProtocolVersion ver, int code, String reason) {
this.response.setStatusLine(ver, code, reason);
}
public void setStatusLine(StatusLine statusline) {
this.response.setStatusLine(statusline);
}
public FluentResponse assertStatus(int expected) {
assertNotNull(this.getStatusLine().toString(), this.getStatusLine());
int actual = this.getStatusCode();
assertEquals(this + ": expecting status " + expected, expected, actual);
return this;
}
public FluentResponse assertContentType(String expected) {
try {
String actual = this.getContentType();
assertEquals(this + ": expecting content type " + expected,
expected, actual);
} catch (Exception e) {
fail(this + ": " + e.getMessage());
}
return this;
}
public FluentResponse assertContentRegexp(String encoding, String... regexp) {
try {
String content = encoding == null ? getContentString()
: getContentString(encoding);
assertNotNull(this.toString(), content);
nextPattern: for (String expr : regexp) {
final Pattern p = Pattern.compile(".*" + expr + ".*");
final Scanner scan = new Scanner(content);
while (scan.hasNext()) {
final String line = scan.nextLine();
if (p.matcher(line).matches()) {
continue nextPattern;
}
}
fail(this + ": no match for regexp '" + expr + "', content=\n"
+ content);
}
} catch (IOException e) {
fail(this + ": " + e.getMessage());
}
return this;
}
public FluentResponse assertContentRegexp(String... regexp) {
return assertContentRegexp(null, regexp);
}
}

View File

@ -0,0 +1,153 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.http.HttpEntity;
public class RequestBuilder {
private FluentHttpMethod method;
private URI uri;
private HttpEntity entity;
/**
* Build an instance of
* <code><a href="FunRequest.html">FunRequest</a></code>
*
* @param uri
* the URI of the request
* @return an instance of
* <code><a href="FunRequest.html">FunRequest</a></code>
* @throws IllegalArgumentException
* if the uri is invalid.
*/
@Deprecated
public static FluentRequest request(final String uri) {
URI uriObj;
try {
uriObj = new URI(uri);
return request(uriObj);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
/**
* Build an instance of
* <code><a href="FunRequest.html">FunRequest</a></code>
*
* @param uri
* the URI of the request
* @return an instance of
* <code><a href="FunRequest.html">FunRequest</a></code>
*/
@Deprecated
public static FluentRequest request(final URI uri) {
return FluentRequest.build(uri, FluentHttpMethod.GET_METHOD);
}
public RequestBuilder() {
method = FluentHttpMethod.GET_METHOD;
}
public FluentRequest build() {
if (uri != null) {
FluentRequest req = FluentRequest.build(uri, method);
if (entity != null)
req.setEntity(entity);
return req;
} else
throw new IllegalStateException(
"too less information provided to build FluentRequest");
}
public static FluentRequest build(final String uri) {
return build(uri, FluentHttpMethod.GET_METHOD);
}
public static FluentRequest build(final String uri,
final FluentHttpMethod method) {
try {
URI uriObj;
uriObj = new URI(uri);
return build(uriObj, method);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}
public static FluentRequest build(final URI uri) {
return build(uri, FluentHttpMethod.GET_METHOD);
}
public static FluentRequest build(final URI uri,
final FluentHttpMethod method) {
return FluentRequest.build(uri, method);
}
public RequestBuilder by(final FluentHttpMethod method) {
this.method = method;
return this;
}
public RequestBuilder req(final String uri) throws URISyntaxException {
URI uriObj = new URI(uri);
req(uriObj);
return this;
}
public RequestBuilder req(final URI uri) {
this.uri = uri;
return this;
}
public RequestBuilder with(final HttpEntity entity) {
this.entity = entity;
return this;
}
public RequestBuilder removeEntity() {
this.entity = null;
return this;
}
public RequestBuilder set(final Object obj) throws IllegalArgumentException {
try {
if (obj instanceof String)
return this.req((String) obj);
if (obj instanceof URI)
return this.req((URI) obj);
if (obj instanceof FluentHttpMethod)
return this.by((FluentHttpMethod) obj);
if (obj instanceof HttpEntity)
return this.with((HttpEntity) obj);
} catch (URISyntaxException e) {
throw new IllegalArgumentException(obj.toString()
+ " is an illegal URI value");
}
throw new IllegalArgumentException(obj.toString()
+ " is an illegal parameter");
}
}

View File

@ -0,0 +1,61 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent.header;
public class CacheControl {
public static final String NAME = "Cache-Control";
/*
* cache-request-directive
*/
public static final String NO_CACHE = "no-cache";
public static final String NO_STORE = "no-store";
public static final String MAX_STALE = "max-stale";
public static final String NO_TRANSFORM = "no-transform";
public static final String ONLY_IF_CACHED = "only-if-cached";
public static String MAX_AGE(final long deltaSeconds) {
return "max-age=" + deltaSeconds;
}
public static String MAX_STALE(final long deltaSeconds) {
return MAX_STALE + "=" + deltaSeconds;
}
public static String MIN_FRESH(final long deltaSeconds) {
return "min-fresh=" + deltaSeconds;
}
/*
* cache-response-directive
*/
public static final String PUBLIC = "public";
public static final String PRIVATE = "private";
public static final String MUST_REVALIDATE = "must-revalidate";
public static final String PROXY_REVALIDATE = "proxy-revalidate";
public static String S_MAXAGE(final long deltaSeconds) {
return "s-maxage=" + deltaSeconds;
}
}

View File

@ -0,0 +1,33 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent.header;
public class ContentType {
public static final String NAME = "Content-Type";
public static final String HTML = "text/html";
public static final String JPEG = "image/jpeg";
public static final String PNG = "image/png";
public static final String GIF = "image/gif";
public static final String TEXT = "text/plain";
public static final String XML = "application/xml";
public static final String JSON = "application/json";
}

View File

@ -0,0 +1,44 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent.header;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class DateUtils {
public static final String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
public static final Locale DATE_LOCALE = Locale.US;
public static final TimeZone TIME_ZONE = TimeZone.getTimeZone("GMT");
public static String format(Date d) {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT, DATE_LOCALE);
format.setTimeZone(TIME_ZONE);
return format.format(d);
}
public static String currentTime() {
Date d = new Date();
return format(d);
}
}

View File

@ -0,0 +1,31 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.fluent.header;
public class HttpHeader {
public static final String CONTENT_LENGTH = "Content-Length";
public static final String DATE = "Date";
public static final String CACHE_CONTROL = CacheControl.NAME;
public static final String CONTENT_TYPE = ContentType.NAME;
public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
}

View File

@ -0,0 +1,361 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.http.client.utils;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Set;
public class UriBuilder {
private String scheme;
private String schemeSpecificPart;
private String authority;
private String userInfo;
private String host;
private int port;
private String path;
private String query;
private String fragment;
private URI uri;
private String enc;
private boolean encOn;
private static Set<String> supportedEncoding;
public UriBuilder() {
init();
}
public UriBuilder(String string) throws URISyntaxException {
init();
URI uri = new URI(string);
from(uri);
}
public UriBuilder(URI uri) {
this.init();
from(uri);
}
public UriBuilder addParameter(String param, Object value)
throws URISyntaxException {
return this.addParameter(param, value.toString());
}
/**
* add a parameter-value pair into URI query
*
* @param param
* @param value
* @throws URISyntaxException
*/
public UriBuilder addParameter(String param, String value)
throws URISyntaxException {
StringBuffer sb = this.query == null ? new StringBuffer()
: new StringBuffer(this.query);
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '&')
sb.append('&');
sb.append(encode(param)).append('=').append(encode(value));
return setQuery(sb.toString());
}
/**
* build a URI instance from pre-provided information
*
* @throws RuntimeException
*/
public URI build() throws RuntimeException {
if (uri != null)
return uri;
else
throw new RuntimeException(
"too less information provided to build URI");
}
private void digestURI(URI uri, boolean raw) {
scheme = uri.getScheme();
host = uri.getHost();
port = uri.getPort();
if (raw) {
schemeSpecificPart = uri.getRawSchemeSpecificPart();
authority = uri.getRawAuthority();
userInfo = uri.getRawUserInfo();
path = uri.getRawPath();
query = uri.getRawQuery();
fragment = uri.getRawFragment();
} else {
schemeSpecificPart = uri.getSchemeSpecificPart();
authority = uri.getAuthority();
userInfo = uri.getUserInfo();
path = uri.getPath();
query = uri.getQuery();
fragment = uri.getFragment();
}
}
public UriBuilder encodingOff() {
this.encOn = false;
return this;
}
public UriBuilder encodingOn() {
try {
encodingOn(enc);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return this;
}
public UriBuilder encodingOn(String enc)
throws UnsupportedEncodingException {
if (enc == null)
throw new IllegalArgumentException(
"Encoding scheme cannot be null.");
// check encoding is supported
if (!supportedEncoding.contains(enc))
throw new UnsupportedEncodingException();
this.enc = enc;
this.encOn = true;
return this;
}
/**
* copy the uri into builder
*
* @param uri
* String value of a URI instance
* @throws URISyntaxException
* if uri is invalid
*/
public UriBuilder from(final String uri) throws URISyntaxException {
URI u = new URI(uri);
from(u);
return this;
}
/**
* copy uri into builder
*
* @param uri
* the URI source to clone
*/
public UriBuilder from(final URI uri) {
digestURI(uri, false);
this.uri = uri;
return this;
}
private void init() {
port = -1;
encOn = false;
enc = "UTF-8";
supportedEncoding = Charset.availableCharsets().keySet();
}
/**
* set URI fragment
*
* @param fragment
* @throws URISyntaxException
*/
public UriBuilder setFragment(final String fragment)
throws URISyntaxException {
this.fragment = encode(fragment);
update();
return this;
}
private String encode(String string) {
try {
if (encOn) {
String encodedString = URLEncoder.encode(string, enc);
return encodedString;
} else {
return URLDecoder.decode(string, enc);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return string;
}
/**
* set URI host
*
* @param host
* @throws URISyntaxException
* if uri is invalid
*/
public UriBuilder setHost(final String host) throws URISyntaxException {
this.host = encode(host);
update();
return this;
}
/**
* set URI path
*
* @param path
* a String represent the path of a URI, e.g., "/path"
* @throws URISyntaxException
*/
public UriBuilder setPath(final String path) throws URISyntaxException {
this.path = encode(path);
update();
return this;
}
/**
* set URI port
*
* @param port
* @throws URISyntaxException
*/
public UriBuilder setPort(final int port) throws URISyntaxException {
this.port = port < 0 ? -1 : port;
update();
return this;
}
/**
* set URI query by parameter-value pairs
*
* @param paramMap
* @throws URISyntaxException
*/
public UriBuilder setQuery(final Map<String, String> paramMap)
throws URISyntaxException {
StringBuffer sb = new StringBuffer();
for (String key : paramMap.keySet())
sb.append(encode(key)).append('=')
.append(encode(paramMap.get(key))).append('&');
if (sb.charAt(sb.length() - 1) == '&')
sb.deleteCharAt(sb.length() - 1);
return setQuery(sb.toString());
}
/**
* set URI query
*
* @param query
* @throws URISyntaxException
*/
public UriBuilder setQuery(final String query) throws URISyntaxException {
this.query = query;
update();
return this;
}
/**
* set URI scheme
*
* @param scheme
* @throws URISyntaxException
* if uri is invalid
*/
public UriBuilder setScheme(final String scheme) throws URISyntaxException {
this.scheme = encode(scheme);
update();
return this;
}
/**
* set URI user-info
*
* @param userInfo
* a String represents the user-info, e.g., "username:password"
* @throws URISyntaxException
*/
public UriBuilder setUserInfo(final String userInfo)
throws URISyntaxException {
this.userInfo = userInfo;
update();
return this;
}
/**
* set URI user-info
*
* @param username
* @param password
* @throws URISyntaxException
*/
public UriBuilder setUserInfo(final String username, final String password)
throws URISyntaxException {
return setUserInfo(username + ':' + password);
}
public UriBuilder removeQuery() {
this.query = null;
return this;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
URI uri = build();
sb.append(uri.toString()).append('\n');
sb.append("scheme : ").append(scheme).append('\n');
sb.append("sspart : ").append(schemeSpecificPart).append('\n');
sb.append("authority: ").append(authority).append('\n');
sb.append("user-info: ").append(userInfo).append('\n');
sb.append("host : ").append(host).append('\n');
sb.append("port : ").append(port).append('\n');
sb.append("path : ").append(path).append('\n');
sb.append("query : ").append(query).append('\n');
sb.append("fragment : ").append(fragment);
return sb.toString();
}
private void update() throws URISyntaxException {
if (scheme != null && host != null)
try {
uri = new URI(scheme, userInfo, host, port, path, query,
fragment);
// StringBuffer sb = new StringBuffer();
// sb.append(scheme).append("://");
// if(userInfo != null)
// sb.append(userInfo).append("@");
// sb.append(host);
// if(path != null)
// sb.append(path);
// if(query != null)
// sb.append('?').append(query);
// if(fragment != null)
// sb.append('#').append(fragment);
// uri = new URI(sb.toString());
digestURI(uri, false);
} catch (URISyntaxException e) {
// roll back
digestURI(uri, false);
throw e;
}
}
}