source: josm/trunk/src/oauth/signpost/http/HttpParameters.java@ 7185

Last change on this file since 7185 was 6849, checked in by stoecker, 10 years ago

see #9710 - update oauth library code

File size: 9.3 KB
Line 
1/* Copyright (c) 2008, 2009 Netflix, Matthias Kaeppler
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15package oauth.signpost.http;
16
17import java.io.Serializable;
18import java.util.Collection;
19import java.util.Iterator;
20import java.util.List;
21import java.util.Map;
22import java.util.Set;
23import java.util.SortedSet;
24import java.util.TreeMap;
25import java.util.TreeSet;
26
27import oauth.signpost.OAuth;
28
29/**
30 * A multi-map of HTTP request parameters. Each key references a
31 * {@link SortedSet} of parameters collected from the request during message
32 * signing. Parameter values are sorted as per {@linkplain http
33 * ://oauth.net/core/1.0a/#anchor13}. Every key/value pair will be
34 * percent-encoded upon insertion. This class has special semantics tailored to
35 * being useful for message signing; it's not a general purpose collection class
36 * to handle request parameters.
37 *
38 * @author Matthias Kaeppler
39 */
40@SuppressWarnings("serial")
41public class HttpParameters implements Map<String, SortedSet<String>>, Serializable {
42
43 private TreeMap<String, SortedSet<String>> wrappedMap = new TreeMap<String, SortedSet<String>>();
44
45 public SortedSet<String> put(String key, SortedSet<String> value) {
46 return wrappedMap.put(key, value);
47 }
48
49 public SortedSet<String> put(String key, SortedSet<String> values, boolean percentEncode) {
50 if (percentEncode) {
51 remove(key);
52 for (String v : values) {
53 put(key, v, true);
54 }
55 return get(key);
56 } else {
57 return wrappedMap.put(key, values);
58 }
59 }
60
61 /**
62 * Convenience method to add a single value for the parameter specified by
63 * 'key'.
64 *
65 * @param key
66 * the parameter name
67 * @param value
68 * the parameter value
69 * @return the value
70 */
71 public String put(String key, String value) {
72 return put(key, value, false);
73 }
74
75 /**
76 * Convenience method to add a single value for the parameter specified by
77 * 'key'.
78 *
79 * @param key
80 * the parameter name
81 * @param value
82 * the parameter value
83 * @param percentEncode
84 * whether key and value should be percent encoded before being
85 * inserted into the map
86 * @return the value
87 */
88 public String put(String key, String value, boolean percentEncode) {
89 // fix contributed by Bjorn Roche - key should be encoded before wrappedMap.get
90 key = percentEncode ? OAuth.percentEncode(key) : key;
91 SortedSet<String> values = wrappedMap.get(key);
92 if (values == null) {
93 values = new TreeSet<String>();
94 wrappedMap.put( key, values);
95 }
96 if (value != null) {
97 value = percentEncode ? OAuth.percentEncode(value) : value;
98 values.add(value);
99 }
100
101 return value;
102 }
103
104 /**
105 * Convenience method to allow for storing null values. {@link #put} doesn't
106 * allow null values, because that would be ambiguous.
107 *
108 * @param key
109 * the parameter name
110 * @param nullString
111 * can be anything, but probably... null?
112 * @return null
113 */
114 public String putNull(String key, String nullString) {
115 return put(key, nullString);
116 }
117
118 public void putAll(Map<? extends String, ? extends SortedSet<String>> m) {
119 wrappedMap.putAll(m);
120 }
121
122 public void putAll(Map<? extends String, ? extends SortedSet<String>> m, boolean percentEncode) {
123 if (percentEncode) {
124 for (String key : m.keySet()) {
125 put(key, m.get(key), true);
126 }
127 } else {
128 wrappedMap.putAll(m);
129 }
130 }
131
132 public void putAll(String[] keyValuePairs, boolean percentEncode) {
133 for (int i = 0; i < keyValuePairs.length - 1; i += 2) {
134 this.put(keyValuePairs[i], keyValuePairs[i + 1], percentEncode);
135 }
136 }
137
138 /**
139 * Convenience method to merge a Map<String, List<String>>.
140 *
141 * @param m
142 * the map
143 */
144 public void putMap(Map<String, List<String>> m) {
145 for (String key : m.keySet()) {
146 SortedSet<String> vals = get(key);
147 if (vals == null) {
148 vals = new TreeSet<String>();
149 put(key, vals);
150 }
151 vals.addAll(m.get(key));
152 }
153 }
154
155 public SortedSet<String> get(Object key) {
156 return wrappedMap.get(key);
157 }
158
159 /**
160 * Convenience method for {@link #getFirst(key, false)}.
161 *
162 * @param key
163 * the parameter name (must be percent encoded if it contains unsafe
164 * characters!)
165 * @return the first value found for this parameter
166 */
167 public String getFirst(Object key) {
168 return getFirst(key, false);
169 }
170
171 /**
172 * Returns the first value from the set of all values for the given
173 * parameter name. If the key passed to this method contains special
174 * characters, you MUST first percent encode it using
175 * {@link OAuth#percentEncode(String)}, otherwise the lookup will fail
176 * (that's because upon storing values in this map, keys get
177 * percent-encoded).
178 *
179 * @param key
180 * the parameter name (must be percent encoded if it contains unsafe
181 * characters!)
182 * @param percentDecode
183 * whether the value being retrieved should be percent decoded
184 * @return the first value found for this parameter
185 */
186 public String getFirst(Object key, boolean percentDecode) {
187 SortedSet<String> values = wrappedMap.get(key);
188 if (values == null || values.isEmpty()) {
189 return null;
190 }
191 String value = values.first();
192 return percentDecode ? OAuth.percentDecode(value) : value;
193 }
194
195 /**
196 * Concatenates all values for the given key to a list of key/value pairs
197 * suitable for use in a URL query string.
198 *
199 * @param key
200 * the parameter name
201 * @return the query string
202 */
203 public String getAsQueryString(Object key) {
204 return getAsQueryString(key, true);
205 }
206
207 /**
208 * Concatenates all values for the given key to a list of key/value pairs
209 * suitable for use in a URL query string.
210 *
211 * @param key
212 * the parameter name
213 * @param percentEncode
214 * whether key should be percent encoded before being
215 * used with the map
216 * @return the query string
217 */
218 public String getAsQueryString(Object key, boolean percentEncode) {
219 // fix contributed by Stjepan Rajko - we need the percentEncode parameter
220 // because some places (like SignatureBaseString.normalizeRequestParameters)
221 // need to supply the parameter percent encoded
222
223 StringBuilder sb = new StringBuilder();
224 if(percentEncode)
225 key = OAuth.percentEncode((String) key);
226 Set<String> values = wrappedMap.get(key);
227 if (values == null) {
228 return key + "=";
229 }
230 Iterator<String> iter = values.iterator();
231 while (iter.hasNext()) {
232 sb.append(key + "=" + iter.next());
233 if (iter.hasNext()) {
234 sb.append("&");
235 }
236 }
237 return sb.toString();
238 }
239
240 public String getAsHeaderElement(String key) {
241 String value = getFirst(key);
242 if (value == null) {
243 return null;
244 }
245 return key + "=\"" + value + "\"";
246 }
247
248 public boolean containsKey(Object key) {
249 return wrappedMap.containsKey(key);
250 }
251
252 public boolean containsValue(Object value) {
253 for (Set<String> values : wrappedMap.values()) {
254 if (values.contains(value)) {
255 return true;
256 }
257 }
258 return false;
259 }
260
261 public int size() {
262 int count = 0;
263 for (String key : wrappedMap.keySet()) {
264 count += wrappedMap.get(key).size();
265 }
266 return count;
267 }
268
269 public boolean isEmpty() {
270 return wrappedMap.isEmpty();
271 }
272
273 public void clear() {
274 wrappedMap.clear();
275 }
276
277 public SortedSet<String> remove(Object key) {
278 return wrappedMap.remove(key);
279 }
280
281 public Set<String> keySet() {
282 return wrappedMap.keySet();
283 }
284
285 public Collection<SortedSet<String>> values() {
286 return wrappedMap.values();
287 }
288
289 public Set<Entry<String, SortedSet<String>>> entrySet() {
290 return wrappedMap.entrySet();
291 }
292
293 public HttpParameters getOAuthParameters() {
294 HttpParameters oauthParams = new HttpParameters();
295
296 for (Entry<String, SortedSet<String>> param : this.entrySet()) {
297 String key = param.getKey();
298 if (key.startsWith("oauth_") || key.startsWith("x_oauth_")) {
299 oauthParams.put(key, param.getValue());
300 }
301 }
302
303 return oauthParams;
304 }
305}
Note: See TracBrowser for help on using the repository browser.