mirror of
https://github.com/moparisthebest/davmail
synced 2025-01-08 04:08:12 -05:00
Refactor StringUtil and encode ~ in urlcompname
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2050 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
1165665d01
commit
0cf9f1ce80
@ -24,7 +24,9 @@ import org.apache.commons.codec.binary.Hex;
|
|||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -128,79 +130,112 @@ public final class StringUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class PatternMap {
|
||||||
|
protected String match;
|
||||||
|
protected String value;
|
||||||
|
protected Pattern pattern;
|
||||||
|
|
||||||
|
protected PatternMap(String match, String value) {
|
||||||
|
this.match = match;
|
||||||
|
this.value = value;
|
||||||
|
pattern = Pattern.compile(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PatternMap(String match, String escapedMatch, String value) {
|
||||||
|
this.match = match;
|
||||||
|
this.value = value;
|
||||||
|
pattern = Pattern.compile(escapedMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PatternMap(String match, Pattern pattern, String value) {
|
||||||
|
this.match = match;
|
||||||
|
this.value = value;
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String replaceAll(String string) {
|
||||||
|
if (string != null && string.indexOf(match) >= 0) {
|
||||||
|
return pattern.matcher(string).replaceAll(value);
|
||||||
|
} else {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Pattern AMP_PATTERN = Pattern.compile("&");
|
private static final Pattern AMP_PATTERN = Pattern.compile("&");
|
||||||
private static final Pattern LT_PATTERN = Pattern.compile("<");
|
private static final Pattern PLUS_PATTERN = Pattern.compile("\\+");
|
||||||
private static final Pattern GT_PATTERN = Pattern.compile(">");
|
|
||||||
private static final Pattern PERCENT_PATTERN = Pattern.compile("%");
|
|
||||||
private static final Pattern HASH_PATTERN = Pattern.compile("#");
|
|
||||||
private static final Pattern STAR_PATTERN = Pattern.compile("\\*");
|
|
||||||
|
|
||||||
private static final Pattern QUOTE_PATTERN = Pattern.compile("\"");
|
private static final Pattern QUOTE_PATTERN = Pattern.compile("\"");
|
||||||
private static final Pattern CR_PATTERN = Pattern.compile("\r");
|
private static final Pattern CR_PATTERN = Pattern.compile("\r");
|
||||||
private static final Pattern LF_PATTERN = Pattern.compile("\n");
|
private static final Pattern LF_PATTERN = Pattern.compile("\n");
|
||||||
|
|
||||||
private static final Pattern URLENCODED_F8FF_PATTERN = Pattern.compile(String.valueOf((char) 0xF8FF));
|
private static final List<PatternMap> URLENCODED_PATTERNS = new ArrayList<PatternMap>();
|
||||||
private static final Pattern URLENCODED_AMP_PATTERN = Pattern.compile("%26");
|
static {
|
||||||
private static final Pattern URLENCODED_PLUS_PATTERN = Pattern.compile("%2B");
|
URLENCODED_PATTERNS.add(new PatternMap(String.valueOf((char) 0xF8FF), "_xF8FF_"));
|
||||||
private static final Pattern URLENCODED_COLON_PATTERN = Pattern.compile("%3A");
|
URLENCODED_PATTERNS.add(new PatternMap("%26", "&"));
|
||||||
private static final Pattern URLENCODED_SEMICOLON_PATTERN = Pattern.compile("%3B");
|
URLENCODED_PATTERNS.add(new PatternMap("%2B", "+"));
|
||||||
private static final Pattern URLENCODED_LT_PATTERN = Pattern.compile("%3C");
|
URLENCODED_PATTERNS.add(new PatternMap("%3A", ":"));
|
||||||
private static final Pattern URLENCODED_GT_PATTERN = Pattern.compile("%3E");
|
URLENCODED_PATTERNS.add(new PatternMap("%3B", ";"));
|
||||||
private static final Pattern URLENCODED_QUOTE_PATTERN = Pattern.compile("%22");
|
URLENCODED_PATTERNS.add(new PatternMap("%3C", "<"));
|
||||||
private static final Pattern URLENCODED_X0D0A_PATTERN = Pattern.compile("\n");
|
URLENCODED_PATTERNS.add(new PatternMap("%3E", ">"));
|
||||||
private static final Pattern URLENCODED_PERCENT_PATTERN = Pattern.compile("%25");
|
URLENCODED_PATTERNS.add(new PatternMap("%22", "\""));
|
||||||
private static final Pattern URLENCODED_HASH_PATTERN = Pattern.compile("%23");
|
URLENCODED_PATTERNS.add(new PatternMap("%23", "#"));
|
||||||
private static final Pattern URLENCODED_STAR_PATTERN = Pattern.compile("%2A");
|
URLENCODED_PATTERNS.add(new PatternMap("%2A", "*"));
|
||||||
private static final Pattern URLENCODED_PIPE_PATTERN = Pattern.compile("%7C");
|
URLENCODED_PATTERNS.add(new PatternMap("%7C", "|"));
|
||||||
private static final Pattern URLENCODED_QUESTION_PATTERN = Pattern.compile("%3F");
|
URLENCODED_PATTERNS.add(new PatternMap("%3F", "?"));
|
||||||
|
URLENCODED_PATTERNS.add(new PatternMap("%7E", "~"));
|
||||||
|
|
||||||
private static final Pattern ENCODED_AMP_PATTERN = Pattern.compile("&");
|
// CRLF is replaced with LF in response
|
||||||
private static final Pattern ENCODED_LT_PATTERN = Pattern.compile("<");
|
URLENCODED_PATTERNS.add(new PatternMap("\n", "_x000D__x000A_"));
|
||||||
private static final Pattern ENCODED_GT_PATTERN = Pattern.compile(">");
|
|
||||||
|
|
||||||
private static final Pattern F8FF_PATTERN = Pattern.compile("_xF8FF_");
|
// last replace %
|
||||||
private static final Pattern X0D0A_PATTERN = Pattern.compile("_x000D__x000A_");
|
URLENCODED_PATTERNS.add(new PatternMap("%25", "%"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<PatternMap> URLENCODE_PATTERNS = new ArrayList<PatternMap>();
|
||||||
|
static {
|
||||||
|
// first replace %
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("%", "%25"));
|
||||||
|
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("_xF8FF_", String.valueOf((char) 0xF8FF)));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("&", AMP_PATTERN, "%26"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("+", PLUS_PATTERN, "%2B"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap(":", "%3A"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap(";", "%3B"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("<", "%3C"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap(">", "%3E"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("\"", "%22"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("#", "%23"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("~", "%7E"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("*", "\\*", "%2A"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("|", "\\|", "%7C"));
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("?", "\\?", "%3F"));
|
||||||
|
|
||||||
|
URLENCODE_PATTERNS.add(new PatternMap("_x000D__x000A_", "\r\n"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<PatternMap> XML_DECODE_PATTERNS = new ArrayList<PatternMap>();
|
||||||
|
static {
|
||||||
|
XML_DECODE_PATTERNS.add(new PatternMap("&", "&"));
|
||||||
|
XML_DECODE_PATTERNS.add(new PatternMap("<", "<"));
|
||||||
|
XML_DECODE_PATTERNS.add(new PatternMap(">", ">"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<PatternMap> XML_ENCODE_PATTERNS = new ArrayList<PatternMap>();
|
||||||
|
static {
|
||||||
|
XML_ENCODE_PATTERNS.add(new PatternMap("&", AMP_PATTERN, "&"));
|
||||||
|
XML_ENCODE_PATTERNS.add(new PatternMap("<", "<"));
|
||||||
|
XML_ENCODE_PATTERNS.add(new PatternMap(">", ">"));
|
||||||
|
}
|
||||||
|
|
||||||
private static final Pattern PLUS_PATTERN = Pattern.compile("\\+");
|
|
||||||
private static final Pattern COLON_PATTERN = Pattern.compile(":");
|
|
||||||
private static final Pattern SEMICOLON_PATTERN = Pattern.compile(";");
|
|
||||||
private static final Pattern SLASH_PATTERN = Pattern.compile("/");
|
private static final Pattern SLASH_PATTERN = Pattern.compile("/");
|
||||||
private static final Pattern UNDERSCORE_PATTERN = Pattern.compile("_");
|
private static final Pattern UNDERSCORE_PATTERN = Pattern.compile("_");
|
||||||
private static final Pattern DASH_PATTERN = Pattern.compile("-");
|
private static final Pattern DASH_PATTERN = Pattern.compile("-");
|
||||||
private static final Pattern PIPE_PATTERN = Pattern.compile("\\|");
|
|
||||||
private static final Pattern QUESTION_PATTERN = Pattern.compile("\\?");
|
|
||||||
|
|
||||||
// WebDav search parameter encode
|
// WebDav search parameter encode
|
||||||
private static final Pattern APOS_PATTERN = Pattern.compile("'");
|
private static final Pattern APOS_PATTERN = Pattern.compile("'");
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode & to %26 for urlcompname.
|
|
||||||
*
|
|
||||||
* @param name decoded name
|
|
||||||
* @return name encoded name
|
|
||||||
*/
|
|
||||||
public static String urlEncodeAmpersand(String name) {
|
|
||||||
String result = name;
|
|
||||||
if (name.indexOf('&') >= 0) {
|
|
||||||
result = AMP_PATTERN.matcher(result).replaceAll("%26");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode %26 to & for urlcompname.
|
|
||||||
*
|
|
||||||
* @param name decoded name
|
|
||||||
* @return name encoded name
|
|
||||||
*/
|
|
||||||
public static String urlDecodeAmpersand(String name) {
|
|
||||||
String result = name;
|
|
||||||
if (name != null && name.indexOf("%26") >= 0) {
|
|
||||||
result = URLENCODED_AMP_PATTERN.matcher(result).replaceAll("&");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Xml encode content.
|
* Xml encode content.
|
||||||
*
|
*
|
||||||
@ -209,15 +244,9 @@ public final class StringUtil {
|
|||||||
*/
|
*/
|
||||||
public static String xmlEncode(String name) {
|
public static String xmlEncode(String name) {
|
||||||
String result = name;
|
String result = name;
|
||||||
if (name != null) {
|
if (result != null) {
|
||||||
if (name.indexOf('&') >= 0) {
|
for (PatternMap patternMap : XML_ENCODE_PATTERNS) {
|
||||||
result = AMP_PATTERN.matcher(result).replaceAll("&");
|
result = patternMap.replaceAll(result);
|
||||||
}
|
|
||||||
if (name.indexOf('<') >= 0) {
|
|
||||||
result = LT_PATTERN.matcher(result).replaceAll("<");
|
|
||||||
}
|
|
||||||
if (name.indexOf('>') >= 0) {
|
|
||||||
result = GT_PATTERN.matcher(result).replaceAll(">");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -253,14 +282,10 @@ public final class StringUtil {
|
|||||||
*/
|
*/
|
||||||
public static String xmlDecode(String name) {
|
public static String xmlDecode(String name) {
|
||||||
String result = name;
|
String result = name;
|
||||||
if (name.indexOf("&") >= 0) {
|
if (result != null) {
|
||||||
result = ENCODED_AMP_PATTERN.matcher(result).replaceAll("&");
|
for (PatternMap patternMap : XML_DECODE_PATTERNS) {
|
||||||
|
result = patternMap.replaceAll(result);
|
||||||
}
|
}
|
||||||
if (name.indexOf("<") >= 0) {
|
|
||||||
result = ENCODED_LT_PATTERN.matcher(result).replaceAll("<");
|
|
||||||
}
|
|
||||||
if (name.indexOf(">") >= 0) {
|
|
||||||
result = ENCODED_GT_PATTERN.matcher(result).replaceAll(">");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -302,47 +327,10 @@ public final class StringUtil {
|
|||||||
*/
|
*/
|
||||||
public static String encodeUrlcompname(String value) {
|
public static String encodeUrlcompname(String value) {
|
||||||
String result = value;
|
String result = value;
|
||||||
if (result.indexOf('%') >= 0) {
|
if (result != null) {
|
||||||
result = PERCENT_PATTERN.matcher(result).replaceAll("%25");
|
for (PatternMap patternMap : URLENCODE_PATTERNS) {
|
||||||
|
result = patternMap.replaceAll(result);
|
||||||
}
|
}
|
||||||
if (result.indexOf("_xF8FF_") >= 0) {
|
|
||||||
result = F8FF_PATTERN.matcher(result).replaceAll(String.valueOf((char) 0xF8FF));
|
|
||||||
}
|
|
||||||
if (result.indexOf('&') >= 0) {
|
|
||||||
result = AMP_PATTERN.matcher(result).replaceAll("%26");
|
|
||||||
}
|
|
||||||
if (result.indexOf('+') >= 0) {
|
|
||||||
result = PLUS_PATTERN.matcher(result).replaceAll("%2B");
|
|
||||||
}
|
|
||||||
if (result.indexOf(':') >= 0) {
|
|
||||||
result = COLON_PATTERN.matcher(result).replaceAll("%3A");
|
|
||||||
}
|
|
||||||
if (result.indexOf(';') >= 0) {
|
|
||||||
result = SEMICOLON_PATTERN.matcher(result).replaceAll("%3B");
|
|
||||||
}
|
|
||||||
if (result.indexOf('<') >= 0) {
|
|
||||||
result = LT_PATTERN.matcher(result).replaceAll("%3C");
|
|
||||||
}
|
|
||||||
if (result.indexOf('>') >= 0) {
|
|
||||||
result = GT_PATTERN.matcher(result).replaceAll("%3E");
|
|
||||||
}
|
|
||||||
if (result.indexOf('"') >= 0) {
|
|
||||||
result = QUOTE_PATTERN.matcher(result).replaceAll("%22");
|
|
||||||
}
|
|
||||||
if (result.indexOf('#') >= 0) {
|
|
||||||
result = HASH_PATTERN.matcher(result).replaceAll("%23");
|
|
||||||
}
|
|
||||||
if (result.indexOf('*') >= 0) {
|
|
||||||
result = STAR_PATTERN.matcher(result).replaceAll("%2A");
|
|
||||||
}
|
|
||||||
if (result.indexOf("_x000D__x000A_") >= 0) {
|
|
||||||
result = X0D0A_PATTERN.matcher(result).replaceAll("\r\n");
|
|
||||||
}
|
|
||||||
if (result.indexOf('|') >= 0) {
|
|
||||||
result = PIPE_PATTERN.matcher(result).replaceAll("%7C");
|
|
||||||
}
|
|
||||||
if (result.indexOf('?') >= 0) {
|
|
||||||
result = QUESTION_PATTERN.matcher(result).replaceAll("%3F");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -356,49 +344,8 @@ public final class StringUtil {
|
|||||||
public static String decodeUrlcompname(String urlcompname) {
|
public static String decodeUrlcompname(String urlcompname) {
|
||||||
String result = urlcompname;
|
String result = urlcompname;
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
if (result.indexOf((char) 0xF8FF) >= 0) {
|
for (PatternMap patternMap : URLENCODED_PATTERNS) {
|
||||||
result = URLENCODED_F8FF_PATTERN.matcher(result).replaceAll("_xF8FF_");
|
result = patternMap.replaceAll(result);
|
||||||
}
|
|
||||||
if (result.indexOf("%26") >= 0) {
|
|
||||||
result = URLENCODED_AMP_PATTERN.matcher(result).replaceAll("&");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%2B") >= 0) {
|
|
||||||
result = URLENCODED_PLUS_PATTERN.matcher(result).replaceAll("+");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%3A") >= 0) {
|
|
||||||
result = URLENCODED_COLON_PATTERN.matcher(result).replaceAll(":");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%3B") >= 0) {
|
|
||||||
result = URLENCODED_SEMICOLON_PATTERN.matcher(result).replaceAll(";");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%3C") >= 0) {
|
|
||||||
result = URLENCODED_LT_PATTERN.matcher(result).replaceAll("<");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%3E") >= 0) {
|
|
||||||
result = URLENCODED_GT_PATTERN.matcher(result).replaceAll(">");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%22") >= 0) {
|
|
||||||
result = URLENCODED_QUOTE_PATTERN.matcher(result).replaceAll("\"");
|
|
||||||
}
|
|
||||||
// CRLF is replaced with LF in response
|
|
||||||
if (result.indexOf('\n') >= 0) {
|
|
||||||
result = URLENCODED_X0D0A_PATTERN.matcher(result).replaceAll("_x000D__x000A_");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%23") >= 0) {
|
|
||||||
result = URLENCODED_HASH_PATTERN.matcher(result).replaceAll("#");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%2A") >= 0) {
|
|
||||||
result = URLENCODED_STAR_PATTERN.matcher(result).replaceAll("*");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%7C") >= 0) {
|
|
||||||
result = URLENCODED_PIPE_PATTERN.matcher(result).replaceAll("|");
|
|
||||||
}
|
|
||||||
if (result.indexOf("%3F") >= 0) {
|
|
||||||
result = URLENCODED_QUESTION_PATTERN.matcher(result).replaceAll("?");
|
|
||||||
}
|
|
||||||
// last replace %
|
|
||||||
if (result.indexOf("%25") >= 0) {
|
|
||||||
result = URLENCODED_PERCENT_PATTERN.matcher(result).replaceAll("%");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -60,22 +60,17 @@ public class StringUtilTest extends TestCase {
|
|||||||
assertEquals("<test>", StringUtil.xmlEncode("<test>"));
|
assertEquals("<test>", StringUtil.xmlEncode("<test>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUrlEncodeAmpersand() {
|
|
||||||
assertEquals("%26", StringUtil.urlEncodeAmpersand("&"));
|
|
||||||
assertEquals("&", StringUtil.urlDecodeAmpersand("%26"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testPerf() {
|
public void testPerf() {
|
||||||
String value = "dqsdqs+dsqds+dsqdqs";
|
String value = "dqsdqs+dsqds+dsqdqs";
|
||||||
for (int j = 0; j < 5; j++) {
|
for (int j = 0; j < 5; j++) {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
for (int i = 0; i < 1000000; i++) {
|
for (int i = 0; i < 1000000; i++) {
|
||||||
//String result = StringUtil.encodePlusSign(value);
|
//String result = StringUtil.encodePlusSign(value);
|
||||||
//String result = StringUtil.replaceAll(value, '+', "%2B");
|
//String result = value.replaceAll("\\+", "%2B");
|
||||||
|
|
||||||
/*int length = value.length();
|
int length = value.length();
|
||||||
StringBuilder buffer = new StringBuilder(length);
|
StringBuilder buffer = new StringBuilder(length);
|
||||||
int startIndex = 0;
|
/*int startIndex = 0;
|
||||||
int endIndex = value.indexOf('+');
|
int endIndex = value.indexOf('+');
|
||||||
while (endIndex >= 0) {
|
while (endIndex >= 0) {
|
||||||
buffer.append(value.substring(startIndex, endIndex));
|
buffer.append(value.substring(startIndex, endIndex));
|
||||||
@ -83,8 +78,8 @@ public class StringUtilTest extends TestCase {
|
|||||||
startIndex = endIndex + 1;
|
startIndex = endIndex + 1;
|
||||||
endIndex = value.indexOf('+', startIndex);
|
endIndex = value.indexOf('+', startIndex);
|
||||||
}
|
}
|
||||||
buffer.append(value.substring(startIndex)); */
|
buffer.append(value.substring(startIndex));*/
|
||||||
/*
|
|
||||||
for (int k = 0; k < length; k++) {
|
for (int k = 0; k < length; k++) {
|
||||||
char c = value.charAt(k);
|
char c = value.charAt(k);
|
||||||
if (c == '+') {
|
if (c == '+') {
|
||||||
@ -92,7 +87,7 @@ public class StringUtilTest extends TestCase {
|
|||||||
} else {
|
} else {
|
||||||
buffer.append(c);
|
buffer.append(c);
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
//String result = buffer.toString();
|
//String result = buffer.toString();
|
||||||
//String result = value.replaceAll("\\+", "%2B");
|
//String result = value.replaceAll("\\+", "%2B");
|
||||||
}
|
}
|
||||||
@ -119,4 +114,10 @@ public class StringUtilTest extends TestCase {
|
|||||||
assertEquals("test %3F", StringUtil.encodeUrlcompname("test ?"));
|
assertEquals("test %3F", StringUtil.encodeUrlcompname("test ?"));
|
||||||
assertEquals("test ?", StringUtil.decodeUrlcompname("test %3F"));
|
assertEquals("test ?", StringUtil.decodeUrlcompname("test %3F"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEncodeUrlCompname() {
|
||||||
|
|
||||||
|
assertEquals("test %7E", StringUtil.encodeUrlcompname("test ~"));
|
||||||
|
assertEquals("test ~", StringUtil.decodeUrlcompname("test %7E"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user