1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.http.utils;
20
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static org.jclouds.io.Payloads.newUrlEncodedFormPayload;
23
24 import java.net.URI;
25 import java.util.Comparator;
26 import java.util.Iterator;
27 import java.util.Map;
28
29 import org.jclouds.javax.annotation.Nullable;
30 import javax.ws.rs.core.UriBuilder;
31
32 import org.jclouds.http.HttpRequest;
33 import org.jclouds.util.Strings2;
34
35 import com.google.common.collect.ImmutableList;
36 import com.google.common.collect.ImmutableMultimap;
37 import com.google.common.collect.ImmutableSet;
38 import com.google.common.collect.ImmutableSortedSet;
39 import com.google.common.collect.LinkedHashMultimap;
40 import com.google.common.collect.LinkedListMultimap;
41 import com.google.common.collect.Multimap;
42
43
44
45
46
47 public class ModifyRequest {
48 @SuppressWarnings("unchecked")
49 public static <R extends HttpRequest> R putHeaders(R request, Multimap<String, String> moreHeaders) {
50 return (R) request.toBuilder().headers(
51 ImmutableMultimap.<String, String> builder().putAll(request.getHeaders()).putAll(moreHeaders).build())
52 .build();
53 }
54
55 @SuppressWarnings("unchecked")
56 public static <R extends HttpRequest> R endpoint(R request, URI endpoint) {
57 return (R) checkNotNull(request, "request").toBuilder().endpoint(checkNotNull(endpoint, "endpoint")).build();
58 }
59
60 @SuppressWarnings("unchecked")
61 public static <R extends HttpRequest> R replaceHeaders(R request, Multimap<String, String> headers) {
62 Multimap<String, String> newHeaders = LinkedHashMultimap.create(checkNotNull(request, "request").getHeaders());
63 for (String header : headers.keySet())
64 newHeaders.replaceValues(header, headers.get(header));
65 return (R) request.toBuilder().headers(newHeaders).build();
66 }
67
68 public static <R extends HttpRequest> R replaceHeader(R request, String header, String... values) {
69 return replaceHeader(request, header, ImmutableList.copyOf(checkNotNull(values, "values")));
70 }
71
72 @SuppressWarnings("unchecked")
73 public static <R extends HttpRequest> R replaceHeader(R request, String header, Iterable<String> values) {
74 Multimap<String, String> headers = LinkedHashMultimap.create(checkNotNull(request, "request").getHeaders());
75 headers.replaceValues(checkNotNull(header, "header"), checkNotNull(values, "values"));
76 return (R) request.toBuilder().headers(headers).build();
77 }
78
79 @SuppressWarnings("unchecked")
80 public static <R extends HttpRequest> R removeHeader(R request, String header) {
81 Multimap<String, String> headers = LinkedHashMultimap.create(checkNotNull(request, "request").getHeaders());
82 headers.removeAll(checkNotNull(header, "header"));
83 return (R) request.toBuilder().headers(headers).build();
84 }
85
86 public static <R extends HttpRequest> R addQueryParam(R request, String key, Object value, UriBuilder builder) {
87 return addQueryParam(request, key, ImmutableSet.<Object> of(value), builder, request.getSkips());
88 }
89
90 public static <R extends HttpRequest> R addQueryParam(R request, String key, Iterable<?> values, UriBuilder builder) {
91 return addQueryParam(request, key, values, builder, request.getSkips());
92 }
93
94 @SuppressWarnings("unchecked")
95 public static <R extends HttpRequest> R addQueryParam(R request, String key, Iterable<?> values, UriBuilder builder,
96 char... skips) {
97 builder.uri(request.getEndpoint());
98 Multimap<String, String> map = parseQueryToMap(request.getEndpoint().getQuery());
99 for (Object o : values)
100 map.put(key, o.toString());
101 builder.replaceQuery(makeQueryLine(map, null, skips));
102 return (R) request.toBuilder().endpoint(builder.build()).build();
103 }
104
105 public static <R extends HttpRequest> R replaceMatrixParam(R request, String name, Object value, UriBuilder builder) {
106 return replaceMatrixParam(request, name, new Object[] { value }, builder);
107 }
108
109 @SuppressWarnings("unchecked")
110 public static <R extends HttpRequest> R replaceMatrixParam(R request, String name, Object[] values,
111 UriBuilder builder) {
112 builder.uri(request.getEndpoint());
113 builder.replaceMatrixParam(name, values);
114 return (R) request.toBuilder().endpoint(builder.build()).build();
115 }
116
117 public static <R extends HttpRequest> R addFormParam(R request, String key, String value) {
118 return addFormParam(request, key, ImmutableSet.<Object> of(value));
119 }
120
121 @SuppressWarnings("unchecked")
122 public static <R extends HttpRequest> R addFormParam(R request, String key, Iterable<?> values) {
123 Multimap<String, String> map = request.getPayload() != null ? parseQueryToMap(request.getPayload()
124 .getRawContent().toString()) : LinkedHashMultimap.<String, String> create();
125 for (Object o : values)
126 map.put(key, o.toString());
127 return (R) request.toBuilder().payload(newUrlEncodedFormPayload(map)).build();
128 }
129
130 @SuppressWarnings("unchecked")
131 public static <R extends HttpRequest> R putFormParams(R request, Multimap<String, String> params) {
132 Multimap<String, String> map = request.getPayload() != null ? parseQueryToMap(request.getPayload()
133 .getRawContent().toString()) : LinkedHashMultimap.<String, String> create();
134 map.putAll(params);
135 return (R) request.toBuilder().payload(newUrlEncodedFormPayload(map)).build();
136 }
137
138 public static Multimap<String, String> parseQueryToMap(String in) {
139 Multimap<String, String> map = LinkedListMultimap.create();
140 if (in == null) {
141 } else if (in.indexOf('&') == -1) {
142 if (in.contains("="))
143 parseKeyValueFromStringToMap(in, map);
144 else
145 map.put(in, null);
146 } else {
147 String[] parts = Strings2.urlDecode(in).split("&");
148 for (String part : parts) {
149 parseKeyValueFromStringToMap(part, map);
150 }
151 }
152 return map;
153 }
154
155 public static void parseKeyValueFromStringToMap(String stringToParse, Multimap<String, String> map) {
156
157 int indexOfFirstEquals = stringToParse.indexOf('=');
158 String key = indexOfFirstEquals == -1 ? stringToParse : stringToParse.substring(0, indexOfFirstEquals);
159 String value = indexOfFirstEquals == -1 ? null : stringToParse.substring(indexOfFirstEquals + 1);
160 map.put(key, value);
161 }
162
163 public static String makeQueryLine(Multimap<String, String> params,
164 @Nullable Comparator<Map.Entry<String, String>> sorter, char... skips) {
165 Iterator<Map.Entry<String, String>> pairs = ((sorter == null) ? params.entries() : ImmutableSortedSet.copyOf(
166 sorter, params.entries())).iterator();
167 StringBuilder formBuilder = new StringBuilder();
168 while (pairs.hasNext()) {
169 Map.Entry<String, String> pair = pairs.next();
170 formBuilder.append(Strings2.urlEncode(pair.getKey(), skips));
171 if (pair.getValue() != null)
172 formBuilder.append("=");
173 if (pair.getValue() != null && !pair.getValue().equals("")) {
174 formBuilder.append(Strings2.urlEncode(pair.getValue(), skips));
175 }
176 if (pairs.hasNext())
177 formBuilder.append("&");
178 }
179 return formBuilder.toString();
180 }
181 }