/
StringUtil.java
168 lines (160 loc) · 5.58 KB
/
StringUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package org.folio.util;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* Utility class for String operations.
*/
public final class StringUtil {
private StringUtil() {
throw new UnsupportedOperationException();
}
/**
* Appends s to appendable as a quoted CQL string constant.
* It masks the five special CQL characters {@code \ * ? ^ "}
* and puts the result into double quotes.
*
* <p>Example usage:
*
* <pre>
* StringBuilder query = new StringBuilder("username==");
* StringUtil.appendCqlEncoded(query, username).append(" AND x=y";
* String url = "https://example.com/users?query=" + PercentCodec.encode(query);
* </pre>
*
* <p>query is {@code username=="" AND x=y} if username is null
* <p>query is {@code username=="" AND x=y} if username is an empty string
* <p>query is {@code username=="foo" AND x=y} if username is {@code foo}
* <p>query is {@code username=="foo\* bar\*" AND x=y} if username is {@code foo* bar*}
* <p>query is {@code username=="\\\*\?\^\"" AND x=y} if username is {@code \*?^"}
*
* @return appendable
*/
public static Appendable appendCqlEncoded(Appendable appendable, CharSequence s) {
try {
appendable.append('"');
if (s != null) {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\\':
case '*':
case '?':
case '^':
case '"':
appendable.append('\\').append(c);
break;
default:
appendable.append(c);
}
}
}
appendable.append('"');
return appendable;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
/**
* Returns s as a quoted CQL string constant. It masks the five
* special CQL characters {@code \ * ? ^ "} and puts the result into
* double quotes.
*
* <p>Example usage:
*
* <pre>
* String query = "username==" + StringUtil.cqlEncode(username);
* String url = "https://example.com/users?query=" + PercentCodec.encode(query);
* </pre>
*
* <p>query is {@code username==""} if s is null
* <p>query is {@code username==""} if s is an empty string
* <p>query is {@code username=="foo"} if s is {@code foo}
* <p>query is {@code username=="foo\* bar\*"} if s is {@code foo* bar*}
* <p>query is {@code username=="\\\*\?\^\""} if s is {@code \*?^"}
*
* @return appendable
* @see #appendCqlEncoded(Appendable, CharSequence) appendCqlEncoded for appending to a StringBuilder
*/
public static String cqlEncode(CharSequence s) {
if (s == null) {
return "\"\"";
}
return appendCqlEncoded(new StringBuilder(s.length() + 2), s).toString();
}
/**
* Encode source using www-form-urlencoded scheme and charset.
*
* <p>This is for web forms only.
*
* <p>Otherwise use {@link PercentCodec}, for example for HTTP requests.
*
* @param source String to encode
* @param charset name of the charset to use
* @return the encoded String, "" if source is null, or null if charset is not supported or null
*/
public static String urlEncode(String source, String charset) {
if (source == null) {
return "";
}
try {
return URLEncoder.encode(source, charset);
} catch (UnsupportedEncodingException|NullPointerException e) {
return null;
}
}
/**
* Encode source using www-form-urlencoded scheme and UTF-8 charset.
*
* <p>This is for web forms only.
*
* <p>Otherwise use {@link PercentCodec}, for example for HTTP requests.
*
* <p>Note that <a href="https://tools.ietf.org/html/rfc3986#section-2.5">RFC3986 Section 2.5</a>
* requires UTF-8 encoding and that {@link java.net.URLEncoder#encode(String)} is deprecated
* because it uses the platform's default encoding. See also
* <a href="https://en.wikipedia.org/wiki/Percent-encoding">https://en.wikipedia.org/wiki/Percent-encoding</a>.
*
* @param source String to encode
* @return the encoded String or "" if source is null.
*/
public static String urlEncode(String source) {
// Using this standard charset is always supported and therefore will
// never trigger an UnsupportedEncodingException.
return urlEncode(source, StandardCharsets.UTF_8.name());
}
/**
* Decode source using www-form-urlencoded scheme and charset.
*
* @param source String to encode
* @param charset name of the charset to use
* @return the decoded String, "" if source is null, or null if charset is not supported or null
*/
public static String urlDecode(String source, String charset) {
if (source == null) {
return "";
}
try {
return URLDecoder.decode(source, charset);
} catch (UnsupportedEncodingException|NullPointerException e) {
return null;
}
}
/**
* Decode source using www-form-urlencoded scheme and UTF-8 charset.
*
* <p>Note that <a href="https://tools.ietf.org/html/rfc3986#section-2.5">RFC3986 Section 2.5</a>
* requires UTF-8 encoding and that {@link java.net.URLDecoder#decode(String)} is deprecated
* because it uses the platform's default encoding. See also
* <a href="https://en.wikipedia.org/wiki/Percent-encoding">https://en.wikipedia.org/wiki/Percent-encoding</a>.
*
* @param source String to decode
* @return the decoded String or "" if source is null.
*/
public static String urlDecode(String source) {
return urlDecode(source, StandardCharsets.UTF_8.name());
}
}