33import java .io .ByteArrayOutputStream ;
44import java .io .IOException ;
55import java .io .InputStream ;
6+ import java .nio .charset .Charset ;
67import java .util .Collection ;
78import java .util .List ;
9+ import java .util .regex .Matcher ;
10+ import java .util .regex .Pattern ;
811
912public class StringUtils {
1013 public static final String EMPTY = "" ;
1114
1215 /**
1316 * Join a list of Strings
14- * @param list strings to join
17+ *
18+ * @param list strings to join
1519 * @param separator the separator to insert between the strings
1620 * @return a string made of the strings in list separated by separator
1721 */
@@ -25,7 +29,8 @@ public static String join(List<String> list, String separator) {
2529
2630 /**
2731 * Join a array of Strings
28- * @param array strings to join
32+ *
33+ * @param array strings to join
2934 * @param separator the separator to insert between the strings
3035 * @return a string made of the strings in array separated by separator
3136 */
@@ -38,8 +43,9 @@ public static String join(Object[] array, String separator) {
3843
3944 /**
4045 * Join a collection of Strings
46+ *
4147 * @param collection strings to join
42- * @param separator the separator to insert between the strings
48+ * @param separator the separator to insert between the strings
4349 * @return a string made of the strings in collection separated by separator
4450 */
4551 public static String join (Collection <String > collection , String separator ) {
@@ -51,10 +57,11 @@ public static String join(Collection<String> collection, String separator) {
5157
5258 /**
5359 * Join a array of Strings from startIndex to endIndex
54- * @param array strings to join
55- * @param separator the separator to insert between the strings
60+ *
61+ * @param array strings to join
62+ * @param separator the separator to insert between the strings
5663 * @param startIndex the string to start from
57- * @param endIndex the last string to join
64+ * @param endIndex the last string to join
5865 * @return a string made of the strings in array separated by separator
5966 */
6067 public static String join (final Object [] array , String separator , final int startIndex , final int endIndex ) {
@@ -87,6 +94,7 @@ public static String join(final Object[] array, String separator, final int star
8794
8895 /**
8996 * Convert an array of bytes to a string of hex values
97+ *
9098 * @param bytes bytes to convert
9199 * @return a string of hex values.
92100 */
@@ -102,6 +110,7 @@ public static String encodeHexString(byte[] bytes) {
102110
103111 /**
104112 * Convert a string of hex values to an array of bytes
113+ *
105114 * @param s a string of two digit Hex numbers. The length of string to parse must be even.
106115 * @return bytes representation of the string
107116 */
@@ -125,14 +134,15 @@ public static byte[] hexStringToByteArray(String s) {
125134 *
126135 * @param input The String to escape
127136 * @return The escaped String
128- * @see HtmlEscape#escapeTextArea(String)
137+ * @see HtmlEscape#escapeTextArea(String)
129138 */
130139 public static String escapeHtml (String input ) {
131140 return HtmlEscape .escapeTextArea (input );
132141 }
133142
134143 /**
135144 * Verify that the input has non whitespace characters in it
145+ *
136146 * @param input a String-like object
137147 * @return true if input has non whitespace characters in it
138148 */
@@ -143,6 +153,7 @@ public static boolean isNotBlank(Object input) {
143153
144154 /**
145155 * Verify that the input has non whitespace characters in it
156+ *
146157 * @param input a String
147158 * @return true if input has non whitespace characters in it
148159 */
@@ -152,6 +163,7 @@ public static boolean isNotBlank(String input) {
152163
153164 /**
154165 * Verify that the input has no characters
166+ *
155167 * @param input a string
156168 * @return true if input is null or has no characters
157169 */
@@ -161,7 +173,8 @@ public static boolean isEmpty(String input) {
161173
162174 /**
163175 * Verify that the input is an empty string or contains only whitespace characters.<br>
164- * see {@link Character#isWhitespace(char)}
176+ * see {@link Character#isWhitespace(char)}
177+ *
165178 * @param input a string
166179 * @return true if input is an empty string or contains only whitespace characters
167180 */
@@ -180,6 +193,7 @@ public static boolean isBlank(String input) {
180193
181194 /**
182195 * Read the entire input stream in 1KB chunks
196+ *
183197 * @param in input stream to read from
184198 * @return a String generated from the input stream
185199 * @throws IOException thrown by the input stream
@@ -198,4 +212,34 @@ public static boolean isRemoteUrl(String file) {
198212 return file .matches ("ftp:.*|https?:.*|s3:.*|data:[^;]*;base64,([a-zA-Z0-9/+\n =]+)" );
199213 }
200214
215+ /**
216+ * Replaces the unsafe characters in url with url-encoded values.
217+ * This is based on {@link java.net.URLEncoder#encode(String, String)}
218+ * @param url The url to encode
219+ * @param unsafe Regex pattern of unsafe caracters
220+ * @param charset
221+ * @return An encoded url string
222+ */
223+ public static String urlEncode (String url , Pattern unsafe , Charset charset ) {
224+ StringBuffer sb = new StringBuffer (url .length ());
225+ Matcher matcher = unsafe .matcher (url );
226+ while (matcher .find ()) {
227+ String str = matcher .group (0 );
228+ byte [] bytes = str .getBytes (charset );
229+ StringBuilder escaped = new StringBuilder (str .length () * 3 );
230+
231+ for (byte aByte : bytes ) {
232+ escaped .append ('%' );
233+ char ch = Character .forDigit ((aByte >> 4 ) & 0xF , 16 );
234+ escaped .append (ch );
235+ ch = Character .forDigit (aByte & 0xF , 16 );
236+ escaped .append (ch );
237+ }
238+
239+ matcher .appendReplacement (sb , Matcher .quoteReplacement (escaped .toString ().toLowerCase ()));
240+ }
241+
242+ matcher .appendTail (sb );
243+ return sb .toString ();
244+ }
201245}
0 commit comments