first step towards ParameterList refactoring

This commit is contained in:
Pablo Fernandez committed 2011-12-14 13:31:12 -03:00
1 parent 56561acdac
commit ce531cdc38
11 files changed
+318 -123

No files matched your search

@@ -31,12 +31,12 @@ public class BaseStringExtractorImpl implements BaseStringExtractor
private String getSortedAndEncodedParams(OAuthRequest request)
{
Map<String, String> params = new HashMap<String, String>();
MapUtils.decodeAndAppendEntries(request.getQueryStringParams(), params);
MapUtils.decodeAndAppendEntries(request.getBodyParams(), params);
MapUtils.decodeAndAppendEntries(request.getOauthParameters(), params);
params = MapUtils.sort(params);
return URLUtils.percentEncode(MapUtils.concatSortedPercentEncodedParams(params));
ParameterList params = new ParameterList();
params.addAll(request.getQueryStringParams());
params.addAll(request.getBodyParams());
params.addAll(new ParameterList(request.getOauthParameters()));
params.sort();
return params.asOauthBaseString();
}
private void checkPreconditions(OAuthRequest request)
@@ -0,0 +1,50 @@
package org.scribe.model;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.scribe.exceptions.OAuthException;
import org.scribe.utils.OAuthEncoder;
/**
* @author: Pablo Fernandez
*/
public class Parameter implements Comparable<Parameter>
{
private static final String UTF = "UTF8";
private final String key;
private final String value;
public Parameter(String key, String value)
{
this.key = key;
this.value = value;
}
public String asUrlEncodedPair()
{
return OAuthEncoder.encode(key).concat("=").concat(OAuthEncoder.encode(value));
}
public boolean equals(Object other)
{
if(other == null) return false;
if(other == this) return true;
if(!(other instanceof Parameter)) return false;
Parameter otherParam = (Parameter) other;
return otherParam.key.equals(key) && otherParam.value.equals(value);
}
public int hashCode()
{
return key.hashCode() + value.hashCode();
}
public int compareTo(Parameter parameter)
{
int keyDiff = key.compareTo(parameter.key);
return keyDiff != 0 ? keyDiff : value.compareTo(parameter.value);
}
}
@@ -0,0 +1,117 @@
package org.scribe.model;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.scribe.utils.Preconditions;
import org.scribe.utils.URLUtils;
/**
* @author: Pablo Fernandez
*/
public class ParameterList
{
private static final char QUERY_STRING_SEPARATOR = '?';
private static final String PARAM_SEPARATOR = "&";
private static final String PAIR_SEPARATOR = "=";
private static final String EMPTY_STRING = "";
private final List<Parameter> params;
public ParameterList()
{
params = new ArrayList<Parameter>();
}
public ParameterList(Map<String, String> map)
{
this();
for(Map.Entry<String, String> entry : map.entrySet())
{
params.add(new Parameter(entry.getKey(), entry.getValue()));
}
}
public void add(String key, String value)
{
params.add(new Parameter(key, value));
}
public String appendTo(String url)
{
Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = asFormUrlEncodedString();
if (queryString.equals(EMPTY_STRING))
{
return url;
}
else
{
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
}
public String asOauthBaseString()
{
try
{
return URLEncoder.encode(asFormUrlEncodedString(), "UTF8");
}
catch (UnsupportedEncodingException uee)
{
throw new RuntimeException();
}
}
public String asFormUrlEncodedString()
{
if (params.size() == 0) return EMPTY_STRING;
StringBuilder builder = new StringBuilder();
for(Parameter p : params)
{
builder.append('&').append(p.asUrlEncodedPair());
}
return builder.toString().substring(1);
}
public void addAll(ParameterList other)
{
params.addAll(other.params);
}
public void addQuerystring(String queryString)
{
if (queryString != null && queryString.length() > 0)
{
for (String param : queryString.split(PARAM_SEPARATOR))
{
String pair[] = param.split(PAIR_SEPARATOR);
String key = URLUtils.formURLDecode(pair[0]);
String value = pair.length > 1 ? URLUtils.formURLDecode(pair[1]) : EMPTY_STRING;
params.add(new Parameter(key, value));
}
}
}
public boolean contains(Parameter param)
{
return params.contains(param);
}
public int size()
{
return params.size();
}
public void sort()
{
Collections.sort(params);
}
}
+20 -21
View File
@@ -7,7 +7,6 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import org.scribe.exceptions.*;
import org.scribe.utils.*;
/**
* Represents an HTTP Request object
@@ -22,8 +21,8 @@ class Request
private String url;
private Verb verb;
private Map<String, String> querystringParams;
private Map<String, String> bodyParams;
private ParameterList querystringParams;
private ParameterList bodyParams;
private Map<String, String> headers;
private String payload = null;
private HttpURLConnection connection;
@@ -43,8 +42,8 @@ class Request
{
this.verb = verb;
this.url = url;
this.querystringParams = new HashMap<String, String>();
this.bodyParams = new HashMap<String, String>();
this.querystringParams = new ParameterList();
this.bodyParams = new ParameterList();
this.headers = new HashMap<String, String>();
}
@@ -74,7 +73,7 @@ class Request
private void createConnection() throws IOException
{
String effectiveUrl = URLUtils.appendParametersToQueryString(url, querystringParams);
String effectiveUrl = querystringParams.appendTo(url);
if (connection == null)
{
System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false");
@@ -139,7 +138,7 @@ class Request
*/
public void addBodyParameter(String key, String value)
{
this.bodyParams.put(key, value);
this.bodyParams.add(key, value);
}
/**
@@ -150,7 +149,7 @@ class Request
*/
public void addQuerystringParameter(String key, String value)
{
this.querystringParams.put(key, value);
this.querystringParams.add(key, value);
}
/**
@@ -179,20 +178,20 @@ class Request
}
/**
* Get a {@link Map} of the query string parameters.
* Get a {@link ParameterList} with the query string parameters.
*
* @return a map containing the query string parameters
* @throws OAuthException if the URL is not valid
* @return a {@link ParameterList} containing the query string parameters.
* @throws OAuthException if the request URL is not valid.
*/
public Map<String, String> getQueryStringParams()
public ParameterList getQueryStringParams()
{
try
{
Map<String, String> params = new HashMap<String, String>();
ParameterList result = new ParameterList();
String queryString = new URL(url).getQuery();
params.putAll(MapUtils.queryStringToMap(queryString));
params.putAll(this.querystringParams);
return params;
result.addQuerystring(queryString);
result.addAll(querystringParams);
return result;
}
catch (MalformedURLException mue)
{
@@ -201,11 +200,11 @@ class Request
}
/**
* Obtains a {@link Map} of the body parameters.
* Obtains a {@link ParameterList} of the body parameters.
*
* @return a map containing the body parameters.
* @return a {@link ParameterList}containing the body parameters.
*/
public Map<String, String> getBodyParams()
public ParameterList getBodyParams()
{
return bodyParams;
}
@@ -251,7 +250,7 @@ class Request
byte[] getByteBodyContents()
{
if (bytePayload != null) return bytePayload;
String body = (payload != null) ? payload : URLUtils.formURLEncodeMap(bodyParams);
String body = (payload != null) ? payload : bodyParams.asFormUrlEncodedString();
try
{
return body.getBytes(getCharset());
@@ -327,7 +326,7 @@ class Request
}
/**
* Sets wether the underlying Http Connection is persistent or not.
* Sets whether the underlying Http Connection is persistent or not.
*
* @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html
* @param connectionKeepAlive
@@ -69,26 +69,4 @@ public class MapUtils
}
return result.toString().substring(0, result.length() - 1);
}
/**
* Parses and form-urldecodes a querystring-like string into a map
*
* @param queryString querystring-like String
* @return a map with the form-urldecoded parameters
*/
public static Map<String, String> queryStringToMap(String queryString)
{
Map<String, String> result = new HashMap<String, String>();
if (queryString != null && queryString.length() > 0)
{
for (String param : queryString.split(PARAM_SEPARATOR))
{
String pair[] = param.split(PAIR_SEPARATOR);
String key = URLUtils.formURLDecode(pair[0]);
String value = pair.length > 1 ? URLUtils.formURLDecode(pair[1]) : EMPTY_STRING;
result.put(key, value);
}
}
return result;
}
}
@@ -0,0 +1,57 @@
package org.scribe.utils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.scribe.exceptions.OAuthException;
/**
* @author: Pablo Fernandez
*/
public class OAuthEncoder
{
private static String CHARSET = "UTF-8";
private static final Map<String, String> ENCODING_RULES;
static
{
Map<String, String> rules = new HashMap<String, String>();
rules.put("*", "%2A");
rules.put("+", "%20");
rules.put("%7E", "~");
ENCODING_RULES = Collections.unmodifiableMap(rules);
}
public static String encode(String plain)
{
Preconditions.checkNotNull(plain, "Cannot encode null object");
String encoded = "";
try
{
encoded = URLEncoder.encode(plain, CHARSET);
}
catch (UnsupportedEncodingException uee)
{
throw new OAuthException("Charset not found while encoding string: " + CHARSET, uee);
}
for(Map.Entry<String, String> rule : ENCODING_RULES.entrySet())
{
encoded = applyRule(encoded, rule.getKey(), rule.getValue());
}
return encoded;
}
private static String applyRule(String encoded, String toReplace, String replacement)
{
return encoded.replaceAll(Pattern.quote(toReplace), replacement);
}
public static String decode(String encoded)
{
Preconditions.checkNotNull(encoded, "Cannot decode null object");
return encoded;
}
}
@@ -110,29 +110,6 @@ public class URLUtils
}
}
/**
* Append given parameters to the query string of the url
*
* @param url the url to append parameters to
* @param params any map
* @return new url with parameters on query string
*/
public static String appendParametersToQueryString(String url, Map<String, String> params)
{
Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = URLUtils.formURLEncodeMap(params);
if (queryString.equals(EMPTY_STRING))
{
return url;
}
else
{
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
}
private static final class EncodingRule
{
private final String ch;
@@ -9,7 +9,7 @@ import org.scribe.oauth.*;
public class TwitterExample
{
private static final String PROTECTED_RESOURCE_URL = "http://api.twitter.com/1/account/verify_credentials.xml";
private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1/statuses/update.json";
public static void main(String[] args)
{
@@ -45,7 +45,8 @@ public class TwitterExample
// Now let's go and ask for a protected resource!
System.out.println("Now we're going to access a protected resource...");
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL);
request.addBodyParameter("status", "this is sparta! *");
service.signRequest(accessToken, request);
Response response = request.send();
System.out.println("Got it! Lets see what we found...");
@@ -0,0 +1,62 @@
package org.scribe.model;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.scribe.utils.URLUtils;
/**
* @author: Pablo Fernandez
*/
public class ParameterListTest
{
private ParameterList params;
@Before
public void setup()
{
this.params = new ParameterList();
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenAppendingNullMapToQuerystring()
{
String url = null;
params.appendTo(url);
}
@Test
public void shouldAppendNothingToQuerystringIfGivenEmptyMap()
{
String url = "http://www.example.com";
Assert.assertEquals(url, params.appendTo(url));
}
@Test
public void shouldAppendParametersToSimpleUrl()
{
String url = "http://www.example.com";
String expectedUrl = "http://www.example.com?param1=value1&param2=value%20with%20spaces";
params.add("param1", "value1");
params.add("param2", "value with spaces");
url = params.appendTo(url);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldAppendParametersToUrlWithQuerystring()
{
String url = "http://www.example.com?already=present";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value%20with%20spaces";
params.add("param1", "value1");
params.add("param2", "value with spaces");
url = params.appendTo(url);
Assert.assertEquals(url, expectedUrl);
}
}
@@ -34,8 +34,7 @@ public class RequestTest
{
assertEquals(2, getRequest.getQueryStringParams().size());
assertEquals(0, postRequest.getQueryStringParams().size());
assertTrue(getRequest.getQueryStringParams().containsKey("qsparam"));
assertTrue(getRequest.getQueryStringParams().get("qsparam").equals("value"));
assertTrue(getRequest.getQueryStringParams().contains(new Parameter("qsparam", "value")));
}
@Test
@@ -51,7 +50,7 @@ public class RequestTest
@Test
public void shouldSetBodyParamsAndAddContentLength()
{
assertEquals("param=value&param+with+spaces=value+with+spaces", postRequest.getBodyContents());
assertEquals("param=value&param%20with%20spaces=value%20with%20spaces", postRequest.getBodyContents());
postRequest.send();
assertTrue(connection.getHeaders().containsKey("Content-Length"));
}
@@ -77,7 +76,7 @@ public class RequestTest
@Test
public void shouldHandleQueryStringSpaceEncodingProperly()
{
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces"));
assertTrue(getRequest.getQueryStringParams().contains(new Parameter("other param","value with spaces")));
}
@Test
@@ -101,51 +101,6 @@ public class URLUtilsTest
URLUtils.formURLDecode(toDecode);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenAppendingNullMapToQuerystring()
{
String url = "http://www.example.com";
Map<String, String> nullMap = null;
URLUtils.appendParametersToQueryString(url, nullMap);
}
@Test
public void shouldAppendNothingToQuerystringIfGivenEmptyMap()
{
String url = "http://www.example.com";
Map<String, String> emptyMap = new HashMap<String, String>();
String newUrl = URLUtils.appendParametersToQueryString(url, emptyMap);
Assert.assertEquals(url, newUrl);
}
@Test
public void shouldAppendParametersToSimpleUrl()
{
String url = "http://www.example.com";
String expectedUrl = "http://www.example.com?param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
params.put("param2", "value with spaces");
url = URLUtils.appendParametersToQueryString(url, params);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldAppendParametersToUrlWithQuerystring()
{
String url = "http://www.example.com?already=present";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
params.put("param2", "value with spaces");
url = URLUtils.appendParametersToQueryString(url, params);
Assert.assertEquals(url, expectedUrl);
}
@Test
public void shouldPercentEncodePlusSymbol()
{