1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.jclouds.util;
20
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.io.ByteStreams.toByteArray;
23 import static com.google.common.io.Closeables.closeQuietly;
24 import static org.jclouds.util.Patterns.CHAR_TO_ENCODED_PATTERN;
25 import static org.jclouds.util.Patterns.CHAR_TO_PATTERN;
26 import static org.jclouds.util.Patterns.PLUS_PATTERN;
27 import static org.jclouds.util.Patterns.STAR_PATTERN;
28 import static org.jclouds.util.Patterns.TOKEN_TO_PATTERN;
29 import static org.jclouds.util.Patterns.URL_ENCODED_PATTERN;
30 import static org.jclouds.util.Patterns._7E_PATTERN;
31
32 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.UnsupportedEncodingException;
36 import java.net.URLDecoder;
37 import java.net.URLEncoder;
38 import java.util.Map;
39 import java.util.Map.Entry;
40 import java.util.concurrent.ExecutionException;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43
44 import javax.annotation.Resource;
45
46 import org.jclouds.logging.Logger;
47
48 import com.google.common.base.Charsets;
49
50
51
52
53
54
55 public class Strings2 {
56
57
58
59
60 public static String urlEncode(String in, char... skipEncode) {
61 if (isUrlEncoded(in))
62 return in;
63 try {
64 String returnVal = URLEncoder.encode(in, "UTF-8");
65 returnVal = Strings2.replaceAll(returnVal, '+', PLUS_PATTERN, "%20");
66 returnVal = Strings2.replaceAll(returnVal, '*', STAR_PATTERN, "%2A");
67 returnVal = Strings2.replaceAll(returnVal, _7E_PATTERN, "~");
68 for (char c : skipEncode) {
69 returnVal = Strings2.replaceAll(returnVal, CHAR_TO_ENCODED_PATTERN.get(c), c + "");
70 }
71 return returnVal;
72 } catch (UnsupportedEncodingException e) {
73 throw new IllegalStateException("Bad encoding on input: " + in, e);
74 } catch (ExecutionException e) {
75 throw new IllegalStateException("error creating pattern: " + in, e);
76 }
77 }
78
79 public static boolean isUrlEncoded(String in) {
80 return URL_ENCODED_PATTERN.matcher(in).matches();
81 }
82
83 public static String urlDecode(String in) {
84 try {
85 return URLDecoder.decode(in, "UTF-8");
86 } catch (UnsupportedEncodingException e) {
87 throw new IllegalStateException("Bad encoding on input: " + in, e);
88 }
89 }
90
91 public static String replaceTokens(String value, Iterable<Entry<String, String>> tokenValues) {
92 for (Entry<String, String> tokenValue : tokenValues) {
93 try {
94 value = Strings2.replaceAll(value, TOKEN_TO_PATTERN.get(tokenValue.getKey()), tokenValue.getValue());
95 } catch (ExecutionException e) {
96 throw new IllegalStateException("error creating pattern: " + tokenValue.getKey(), e);
97 }
98 }
99 return value;
100 }
101
102 public static String replaceAll(String returnVal, Pattern pattern, String replace) {
103 Matcher m = pattern.matcher(returnVal);
104 returnVal = m.replaceAll(replace);
105 return returnVal;
106 }
107
108 public static String replaceAll(String input, char ifMatch, Pattern pattern, String replacement) {
109 if (input.indexOf(ifMatch) != -1) {
110 input = pattern.matcher(input).replaceAll(replacement);
111 }
112 return input;
113 }
114
115 public static String replaceAll(String input, char match, String replacement) {
116 if (input.indexOf(match) != -1) {
117 try {
118 input = CHAR_TO_PATTERN.get(match).matcher(input).replaceAll(replacement);
119 } catch (ExecutionException e) {
120 throw new IllegalStateException("error creating pattern: " + match, e);
121 }
122 }
123 return input;
124 }
125
126 public static final String UTF8_ENCODING = "UTF-8";
127
128 public static String toStringAndClose(InputStream input) throws IOException {
129 checkNotNull(input, "input");
130 try {
131 return new String(toByteArray(input), Charsets.UTF_8);
132 } catch (IOException e) {
133 logger.warn(e, "Failed to read from stream");
134 return null;
135 } catch (NullPointerException e) {
136 return null;
137 } finally {
138 closeQuietly(input);
139 }
140 }
141
142 public static InputStream toInputStream(String in) {
143 return new ByteArrayInputStream(in.getBytes(Charsets.UTF_8));
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157 public static byte[] encodeString(String str, String charsetName) {
158 try {
159 return str.getBytes(charsetName);
160 } catch (UnsupportedEncodingException e) {
161 logger.warn(e, "Failed to encode string to bytes with encoding " + charsetName
162 + ". Falling back to system's default encoding");
163 return str.getBytes();
164 }
165 }
166
167 @Resource
168 private static Logger logger = Logger.NULL;
169
170
171
172
173
174
175
176
177
178
179 public static byte[] encodeString(String str) {
180 return encodeString(str, UTF8_ENCODING);
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 public static String replaceTokens(String input, Map<String, String> replacements) {
197 Matcher matcher = Patterns.TOKEN_PATTERN.matcher(input);
198 StringBuilder builder = new StringBuilder();
199 int i = 0;
200 while (matcher.find()) {
201 String replacement = replacements.get(matcher.group(1));
202 builder.append(input.substring(i, matcher.start()));
203 if (replacement == null)
204 builder.append(matcher.group(0));
205 else
206 builder.append(replacement);
207 i = matcher.end();
208 }
209 builder.append(input.substring(i, input.length()));
210 return builder.toString();
211 }
212
213 }