1 Commits
Author SHA1 Message Date
Pablo Fernandez 450a3382cc Added multiparameter functionallity 2010-09-13 19:47:17 -03:00
15 changed files with 104 additions and 121 deletions

No files matched your search

-21
View File
@@ -1,21 +0,0 @@
The MIT License
Copyright (c) 2010 Pablo Fenandez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId> <groupId>org.scribe</groupId>
<artifactId>scribe</artifactId> <artifactId>scribe</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0.5</version> <version>1.0.1</version>
<name>OAuth Library</name> <name>OAuth Library</name>
<dependencies> <dependencies>
@@ -5,12 +5,12 @@ public class GoogleApi extends DefaultApi10a
@Override @Override
public String getAccessTokenEndpoint() public String getAccessTokenEndpoint()
{ {
return "https://www.google.com/accounts/OAuthGetAccessToken"; return "https://www.google.com/accounts/OAuthGetRequestToken";
} }
@Override @Override
public String getRequestTokenEndpoint() public String getRequestTokenEndpoint()
{ {
return "https://www.google.com/accounts/OAuthGetRequestToken"; return "https://www.google.com/accounts/OAuthGetAccessToken";
} }
} }
@@ -1,16 +0,0 @@
package org.scribe.builder.api;
public class VimeoApi extends DefaultApi10a
{
@Override
public String getAccessTokenEndpoint()
{
return "http://vimeo.com/oauth/access_token";
}
@Override
public String getRequestTokenEndpoint()
{
return "http://vimeo.com/oauth/request_token";
}
}
@@ -22,10 +22,10 @@ public class BaseStringExtractorImpl implements BaseStringExtractor
private String getSortedAndEncodedParams(OAuthRequest request) private String getSortedAndEncodedParams(OAuthRequest request)
{ {
Map<String, String> params = new HashMap<String, String>(); Map<String, List<String>> params = new HashMap<String, List<String>>();
params.putAll(request.getQueryStringParams()); params.putAll(request.getQueryStringParams());
params.putAll(request.getBodyParams()); params.putAll(request.getBodyParams());
params.putAll(request.getOauthParameters()); params.putAll(MapUtils.toListMap(request.getOauthParameters()));
params = MapUtils.sort(params); params = MapUtils.sort(params);
return URLUtils.percentEncode(URLUtils.formURLEncodeMap(params)); return URLUtils.percentEncode(URLUtils.formURLEncodeMap(params));
} }
@@ -8,24 +8,20 @@ import org.scribe.utils.*;
public class HeaderExtractorImpl implements HeaderExtractor public class HeaderExtractorImpl implements HeaderExtractor
{ {
private static final String PARAM_SEPARATOR = ", ";
private static final String PREAMBLE = "OAuth "; private static final String PREAMBLE = "OAuth ";
public String extract(OAuthRequest request) public String extract(OAuthRequest request)
{ {
checkPreconditions(request); checkPreconditions(request);
Map<String, String> parameters = request.getOauthParameters(); Map<String, String> parameters = request.getOauthParameters();
StringBuffer header = new StringBuffer(parameters.size() * 20); StringBuffer header = new StringBuffer();
header.append(PREAMBLE); header.append(PREAMBLE);
for (String key : parameters.keySet()) for (String key : parameters.keySet())
{ {
if(header.length() > PREAMBLE.length()) addToHeader(header, key, parameters.get(key));
{
header.append(PARAM_SEPARATOR);
}
header.append(String.format("%s=\"%s\"", key, URLUtils.percentEncode(parameters.get(key))));
} }
return header.toString(); return removeTrail(header);
} }
private void checkPreconditions(OAuthRequest request) private void checkPreconditions(OAuthRequest request)
@@ -38,4 +34,13 @@ public class HeaderExtractorImpl implements HeaderExtractor
} }
} }
private void addToHeader(StringBuffer header, String name, String value)
{
header.append(String.format("%s=\"%s\", ", name, URLUtils.percentEncode(value)));
}
private String removeTrail(StringBuffer header)
{
return header.toString().substring(0, header.length() - 2);
}
} }
+22 -7
View File
@@ -19,7 +19,7 @@ class Request
private String url; private String url;
private Verb verb; private Verb verb;
private Map<String, String> bodyParams; private Map<String, List<String>> bodyParams;
private Map<String, String> headers; private Map<String, String> headers;
private String payload = null; private String payload = null;
private Integer timeout = null; private Integer timeout = null;
@@ -35,7 +35,7 @@ class Request
{ {
this.verb = verb; this.verb = verb;
this.url = url; this.url = url;
this.bodyParams = new HashMap<String, String>(); this.bodyParams = new HashMap<String, List<String>>();
this.headers = new HashMap<String, String>(); this.headers = new HashMap<String, String>();
try try
{ {
@@ -108,7 +108,14 @@ class Request
*/ */
public void addBodyParameter(String key, String value) public void addBodyParameter(String key, String value)
{ {
this.bodyParams.put(key, value); if(bodyParams.get(key) != null)
{
bodyParams.get(key).add(value);
}
else
{
bodyParams.put(key, Arrays.asList(value));
}
} }
/** /**
@@ -131,18 +138,26 @@ class Request
* *
* @return a map containing the query string parameters * @return a map containing the query string parameters
*/ */
public Map<String, String> getQueryStringParams() public Map<String, List<String>> getQueryStringParams()
{ {
try try
{ {
Map<String, String> params = new HashMap<String, String>(); Map<String, List<String>> params = new HashMap<String, List<String>>();
String query = new URL(url).getQuery(); String query = new URL(url).getQuery();
if (query != null) if (query != null)
{ {
for (String param : query.split("&")) for (String param : query.split("&"))
{ {
String pair[] = param.split("="); String pair[] = param.split("=");
params.put(pair[0], pair[1]); String key = pair[0], value = pair[1];
if(params.get(key)!= null)
{
params.get(key).add(value);
}
else
{
params.put(key, Arrays.asList(value));
}
} }
} }
return params; return params;
@@ -157,7 +172,7 @@ class Request
* *
* @return a map containing the body parameters. * @return a map containing the body parameters.
*/ */
public Map<String, String> getBodyParams() public Map<String, List<String>> getBodyParams()
{ {
return bodyParams; return bodyParams;
} }
+20 -3
View File
@@ -5,22 +5,39 @@ import java.util.*;
public class MapUtils public class MapUtils
{ {
public static final Map<String, String> sort(Map<String, String> map) public static final Map<String, List<String>> sort(Map<String, List<String>> map)
{ {
Preconditions.checkNotNull(map, "Cannot sort a null object."); Preconditions.checkNotNull(map, "Cannot sort a null object.");
Map<String, String> sorted = new LinkedHashMap<String, String>(); Map<String, List<String>> sorted = new LinkedHashMap<String, List<String>>();
for (String key : getSortedKeys(map)) for (String key : getSortedKeys(map))
{ {
if(map.get(key).size() > 1)
{
Collections.sort(map.get(key));
}
sorted.put(key, map.get(key)); sorted.put(key, map.get(key));
} }
return sorted; return sorted;
} }
private static List<String> getSortedKeys(Map<String, String> map) private static List<String> getSortedKeys(Map<String, List<String>> map)
{ {
List<String> keys = new ArrayList<String>(map.keySet()); List<String> keys = new ArrayList<String>(map.keySet());
Collections.sort(keys); Collections.sort(keys);
return keys; return keys;
} }
@SuppressWarnings("unchecked")
public static final <T> Map<String, List<T>> toListMap(Map<String, T> map)
{
Preconditions.checkNotNull(map, "Cannot sort a null object.");
Map<String, List<T>> result = new HashMap<String, List<T>>();
for (Map.Entry<String, T> entry : map.entrySet())
{
result.put(entry.getKey(), Arrays.asList(entry.getValue()));
}
return result;
}
} }
@@ -1,13 +1,10 @@
package org.scribe.utils; package org.scribe.utils;
import java.util.regex.Pattern;
import org.scribe.model.OAuthConstants; import org.scribe.model.OAuthConstants;
public class Preconditions public class Preconditions
{ {
private static final String DEFAULT_MESSAGE = "Received an invalid parameter"; private static final String DEFAULT_MESSAGE = "Received an invalid parameter";
private static final Pattern URL_PATTERN = Pattern.compile("[a-zA-Z_-]+://\\S+");
public static void checkNotNull(Object object, String errorMsg) public static void checkNotNull(Object object, String errorMsg)
{ {
@@ -36,12 +33,12 @@ public class Preconditions
static boolean isUrl(String url) static boolean isUrl(String url)
{ {
return URL_PATTERN.matcher(url).matches(); return url.startsWith("http://") || url.startsWith("https://");
} }
private static void check(boolean requirements, String error) private static void check(boolean requirements, String error)
{ {
String message = (error == null || error.trim().length() <= 0) ? DEFAULT_MESSAGE : error; String message = (error == null || error.trim().isEmpty()) ? DEFAULT_MESSAGE : error;
if (!requirements) if (!requirements)
{ {
throw new IllegalArgumentException(message); throw new IllegalArgumentException(message);
+13 -10
View File
@@ -16,24 +16,28 @@ public class URLUtils
private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8); private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8);
public static String formURLEncodeMap(Map<String, String> map) public static String formURLEncodeMap(Map<String, List<String>> map)
{ {
Preconditions.checkNotNull(map, "Cannot url-encode a null object"); Preconditions.checkNotNull(map, "Cannot url-encode a null object");
return (map.size() <= 0) ? EMPTY_STRING : doFormUrlEncode(map); return (map.size() <= 0) ? EMPTY_STRING : doFormUrlEncode(map);
} }
private static String doFormUrlEncode(Map<String, String> map) private static String doFormUrlEncode(Map<String, List<String>> map)
{ {
StringBuffer encodedString = new StringBuffer(map.size() * 20); StringBuffer encodedString = new StringBuffer();
for (String key : map.keySet()) for (String key : map.keySet())
{ {
if(encodedString.length() > 0) for(String value: map.get(key))
{ {
encodedString.append(PARAM_SEPARATOR); encodedString.append(percentEncode(key)).append(PAIR_SEPARATOR).append(percentEncode(value)).append(PARAM_SEPARATOR);
} }
encodedString.append(percentEncode(key)).append(PAIR_SEPARATOR).append(percentEncode(map.get(key)));
} }
return encodedString.toString(); return removeTrailingSeparator(encodedString);
}
private static String removeTrailingSeparator(StringBuffer buffer)
{
return buffer.toString().substring(0, buffer.length() - 1);
} }
public static String percentEncode(String string) public static String percentEncode(String string)
@@ -41,9 +45,8 @@ public class URLUtils
Preconditions.checkNotNull(string, "Cannot encode null string"); Preconditions.checkNotNull(string, "Cannot encode null string");
try try
{ {
return URLEncoder.encode(string, UTF_8).replaceAll("\\+", "%20"); return URLEncoder.encode(string, UTF_8);
} } catch (UnsupportedEncodingException uee)
catch (UnsupportedEncodingException uee)
{ {
throw new OAuthException(ERROR_MSG, uee); throw new OAuthException(ERROR_MSG, uee);
} }
@@ -41,12 +41,4 @@ public class BaseStringExtractorTest
OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com"); OAuthRequest request = new OAuthRequest(Verb.GET, "http://example.com");
extractor.extract(request); extractor.extract(request);
} }
@Test
public void shouldProperlyEncodeSpaces()
{
String expected = "GET&http%3A%2F%2Fexample.com&body%3Dthis%2520param%2520has%2520whitespace%26oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E*%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456";
request.addBodyParameter("body", "this param has whitespace");
assertEquals(expected, extractor.extract(request));
}
} }
@@ -52,7 +52,7 @@ public class RequestTest
postRequest.addBodyParameter("param", "value"); postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param two", "value with spaces"); postRequest.addBodyParameter("param two", "value with spaces");
postRequest.send(); postRequest.send();
assertEquals("param%20two=value%20with%20spaces&param=value", postRequest.getBodyContents()); assertEquals("param+two=value+with+spaces&param=value", postRequest.getBodyContents());
assertTrue(connection.getHeaders().containsKey("Content-Length")); assertTrue(connection.getHeaders().containsKey("Content-Length"));
} }
@@ -9,40 +9,42 @@ import org.junit.*;
public class MapUtilsTest public class MapUtilsTest
{ {
private Map<String, String> unsorted; private Map<String, List<String>> unsorted;
@Before @Before
public void setup() public void setup()
{ {
unsorted = new LinkedHashMap<String, String>(); unsorted = new LinkedHashMap<String, List<String>>();
unsorted.put("d", "fourth"); unsorted.put("d", Arrays.asList("fourth"));
unsorted.put("a", "first"); unsorted.put("a", Arrays.asList("first"));
unsorted.put("c", "third"); unsorted.put("c", Arrays.asList("third"));
unsorted.put("b", "second"); unsorted.put("b", Arrays.asList("second", "second_two", "second_one"));
} }
@Test @Test
public void shouldSortMap() public void shouldSortMap()
{ {
Map<String, String> sorted = MapUtils.sort(unsorted); Map<String, List<String>> sorted = MapUtils.sort(unsorted);
List<String> values = new ArrayList<String>(sorted.values()); List<List<String>> values = new ArrayList<List<String>>(sorted.values());
assertEquals("first", values.get(0)); assertEquals("first", values.get(0).get(0));
assertEquals("second", values.get(1)); assertEquals("second", values.get(1).get(0));
assertEquals("third", values.get(2)); assertEquals("second_one", values.get(1).get(1));
assertEquals("fourth", values.get(3)); assertEquals("second_two", values.get(1).get(2));
assertEquals("third", values.get(2).get(0));
assertEquals("fourth", values.get(3).get(0));
} }
@Test @Test
public void shouldNotModifyTheOriginalMap() public void shouldNotModifyTheOriginalMap()
{ {
Map<String, String> sorted = MapUtils.sort(unsorted); Map<String, List<String>> sorted = MapUtils.sort(unsorted);
assertNotSame(sorted, unsorted); assertNotSame(sorted, unsorted);
List<String> values = new ArrayList<String>(unsorted.values()); List<List<String>> values = new ArrayList<List<String>>(unsorted.values());
assertEquals("fourth", values.get(0)); assertEquals("fourth", values.get(0).get(0));
assertEquals("first", values.get(1)); assertEquals("first", values.get(1).get(0));
assertEquals("third", values.get(2)); assertEquals("third", values.get(2).get(0));
assertEquals("second", values.get(3)); assertEquals("second", values.get(3).get(0));
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@@ -53,17 +53,6 @@ public class PreconditionsTest
Preconditions.checkValidUrl("https://www.example.com", ERROR_MSG); Preconditions.checkValidUrl("https://www.example.com", ERROR_MSG);
} }
public void shouldAllowNonStandarProtocolsForAndroid()
{
Preconditions.checkValidUrl("x-url-custom://www.example.com", ERROR_MSG);
}
@Test(expected = IllegalArgumentException.class)
public void shouldNotAllowStrangeProtocolNames()
{
Preconditions.checkValidUrl("$weird*://www.example.com", ERROR_MSG);
}
public void shouldAllowOutOfBandAsValidCallbackValue() public void shouldAllowOutOfBandAsValidCallbackValue()
{ {
Preconditions.checkValidOAuthCallback("oob", ERROR_MSG); Preconditions.checkValidOAuthCallback("oob", ERROR_MSG);
@@ -18,19 +18,19 @@ public class URLUtilsTest
@Test @Test
public void shouldPercentEncodeMap() public void shouldPercentEncodeMap()
{ {
Map<String, String> params = new LinkedHashMap<String, String>(); Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
params.put("key", "value"); params.put("key", Arrays.asList("value"));
params.put("key with spaces", "value with spaces"); params.put("key with spaces", Arrays.asList("value with spaces"));
params.put("&symbols!", "#!"); params.put("&symbols!", Arrays.asList("#!"));
String expected = "key=value&key%20with%20spaces=value%20with%20spaces&%26symbols%21=%23%21"; String expected = "key=value&key+with+spaces=value+with+spaces&%26symbols%21=%23%21";
assertEquals(expected, URLUtils.formURLEncodeMap(params)); assertEquals(expected, URLUtils.formURLEncodeMap(params));
} }
@Test @Test
public void shouldReturnEmptyStringForEmptyMap() public void shouldReturnEmptyStringForEmptyMap()
{ {
Map<String, String> params = new LinkedHashMap<String, String>(); Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
String expected = ""; String expected = "";
assertEquals(expected, URLUtils.formURLEncodeMap(params)); assertEquals(expected, URLUtils.formURLEncodeMap(params));
} }
@@ -39,7 +39,7 @@ public class URLUtilsTest
public void shouldPercentEncodeString() public void shouldPercentEncodeString()
{ {
String toEncode = "this is a test &^"; String toEncode = "this is a test &^";
String expected = "this%20is%20a%20test%20%26%5E"; String expected = "this+is+a+test+%26%5E";
assertEquals(expected, URLUtils.percentEncode(toEncode)); assertEquals(expected, URLUtils.percentEncode(toEncode));
} }
@@ -54,7 +54,7 @@ public class URLUtilsTest
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfMapIsNull() public void shouldThrowExceptionIfMapIsNull()
{ {
Map<String, String> nullMap = null; Map<String, List<String>> nullMap = null;
URLUtils.formURLEncodeMap(nullMap); URLUtils.formURLEncodeMap(nullMap);
} }