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

Last change on this file since 4231 was 4231, checked in by stoecker, 13 years ago

add signpost and metadata extractor code to repository directly

File size: 8.0 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 SortedSet<String> values = wrappedMap.get(key);
90 if (values == null) {
91 values = new TreeSet<String>();
92 wrappedMap.put(percentEncode ? OAuth.percentEncode(key) : key, values);
93 }
94 if (value != null) {
95 value = percentEncode ? OAuth.percentEncode(value) : value;
96 values.add(value);
97 }
98
99 return value;
100 }
101
102 /**
103 * Convenience method to allow for storing null values. {@link #put} doesn't
104 * allow null values, because that would be ambiguous.
105 *
106 * @param key
107 * the parameter name
108 * @param nullString
109 * can be anything, but probably... null?
110 * @return null
111 */
112 public String putNull(String key, String nullString) {
113 return put(key, nullString);
114 }
115
116 public void putAll(Map<? extends String, ? extends SortedSet<String>> m) {
117 wrappedMap.putAll(m);
118 }
119
120 public void putAll(Map<? extends String, ? extends SortedSet<String>> m, boolean percentEncode) {
121 if (percentEncode) {
122 for (String key : m.keySet()) {
123 put(key, m.get(key), true);
124 }
125 } else {
126 wrappedMap.putAll(m);
127 }
128 }
129
130 public void putAll(String[] keyValuePairs, boolean percentEncode) {
131 for (int i = 0; i < keyValuePairs.length - 1; i += 2) {
132 this.put(keyValuePairs[i], keyValuePairs[i + 1], percentEncode);
133 }
134 }
135
136 /**
137 * Convenience method to merge a Map<String, List<String>>.
138 *
139 * @param m
140 * the map
141 */
142 public void putMap(Map<String, List<String>> m) {
143 for (String key : m.keySet()) {
144 SortedSet<String> vals = get(key);
145 if (vals == null) {
146 vals = new TreeSet<String>();
147 put(key, vals);
148 }
149 vals.addAll(m.get(key));
150 }
151 }
152
153 public SortedSet<String> get(Object key) {
154 return wrappedMap.get(key);
155 }
156
157 /**
158 * Convenience method for {@link #getFirst(key, false)}.
159 *
160 * @param key
161 * the parameter name (must be percent encoded if it contains unsafe
162 * characters!)
163 * @return the first value found for this parameter
164 */
165 public String getFirst(Object key) {
166 return getFirst(key, false);
167 }
168
169 /**
170 * Returns the first value from the set of all values for the given
171 * parameter name. If the key passed to this method contains special
172 * characters, you MUST first percent encode it using
173 * {@link OAuth#percentEncode(String)}, otherwise the lookup will fail
174 * (that's because upon storing values in this map, keys get
175 * percent-encoded).
176 *
177 * @param key
178 * the parameter name (must be percent encoded if it contains unsafe
179 * characters!)
180 * @param percentDecode
181 * whether the value being retrieved should be percent decoded
182 * @return the first value found for this parameter
183 */
184 public String getFirst(Object key, boolean percentDecode) {
185 SortedSet<String> values = wrappedMap.get(key);
186 if (values == null || values.isEmpty()) {
187 return null;
188 }
189 String value = values.first();
190 return percentDecode ? OAuth.percentDecode(value) : value;
191 }
192
193 /**
194 * Concatenates all values for the given key to a list of key/value pairs
195 * suitable for use in a URL query string.
196 *
197 * @param key
198 * the parameter name
199 * @return the query string
200 */
201 public String getAsQueryString(Object key) {
202 StringBuilder sb = new StringBuilder();
203 key = OAuth.percentEncode((String) key);
204 Set<String> values = wrappedMap.get(key);
205 if (values == null) {
206 return key + "=";
207 }
208 Iterator<String> iter = values.iterator();
209 while (iter.hasNext()) {
210 sb.append(key + "=" + iter.next());
211 if (iter.hasNext()) {
212 sb.append("&");
213 }
214 }
215 return sb.toString();
216 }
217
218 public String getAsHeaderElement(String key) {
219 String value = getFirst(key);
220 if (value == null) {
221 return null;
222 }
223 return key + "=\"" + value + "\"";
224 }
225
226 public boolean containsKey(Object key) {
227 return wrappedMap.containsKey(key);
228 }
229
230 public boolean containsValue(Object value) {
231 for (Set<String> values : wrappedMap.values()) {
232 if (values.contains(value)) {
233 return true;
234 }
235 }
236 return false;
237 }
238
239 public int size() {
240 int count = 0;
241 for (String key : wrappedMap.keySet()) {
242 count += wrappedMap.get(key).size();
243 }
244 return count;
245 }
246
247 public boolean isEmpty() {
248 return wrappedMap.isEmpty();
249 }
250
251 public void clear() {
252 wrappedMap.clear();
253 }
254
255 public SortedSet<String> remove(Object key) {
256 return wrappedMap.remove(key);
257 }
258
259 public Set<String> keySet() {
260 return wrappedMap.keySet();
261 }
262
263 public Collection<SortedSet<String>> values() {
264 return wrappedMap.values();
265 }
266
267 public Set<java.util.Map.Entry<String, SortedSet<String>>> entrySet() {
268 return wrappedMap.entrySet();
269 }
270}
Note: See TracBrowser for help on using the repository browser.