in dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/util/PathUtils.java [168:295]
public static String normalize(@Nonnull String path) {
int len = path.length();
if (len == 0) {
return RestConstants.SLASH;
}
int state = State.INITIAL;
int start = -1, end = 0;
StringBuilder buf = null;
out:
for (int i = 0; i < len; i++) {
char c = path.charAt(i);
switch (c) {
case ' ':
case '\t':
case '\n':
case '\r':
continue;
case '/':
switch (state) {
case State.SLASH:
if (start != -1) {
if (buf == null) {
buf = new StringBuilder(len);
}
buf.append(path, start, i);
}
start = -1;
continue;
case State.DOT:
state = State.SLASH;
if (buf == null) {
buf = new StringBuilder(len);
}
buf.append(path, start, i - 1);
start = -1;
continue;
case State.DOT_DOT:
state = State.SLASH;
if (buf == null) {
buf = new StringBuilder(len);
}
if (end > 2) {
buf.append(path, start, i - 2);
int bLen = buf.length();
if (bLen > 1) {
int index = buf.lastIndexOf(RestConstants.SLASH, bLen - 2);
if (!"/../".equals(buf.substring(index))) {
buf.setLength(index + 1);
start = -1;
continue;
}
}
}
buf.append(path, start, i + 1);
start = -1;
continue;
default:
state = State.SLASH;
break;
}
break;
case '.':
switch (state) {
case State.INITIAL:
if (buf == null) {
buf = new StringBuilder(len);
}
buf.append('/');
case State.SLASH:
state = State.DOT;
break;
case State.DOT:
state = State.DOT_DOT;
break;
case State.DOT_DOT:
state = State.NORMAL;
break;
default:
}
break;
case '?':
case '#':
break out;
default:
switch (state) {
case State.INITIAL:
if (buf == null) {
buf = new StringBuilder(len);
}
buf.append('/');
case State.SLASH:
case State.DOT:
case State.DOT_DOT:
state = State.NORMAL;
break;
default:
}
break;
}
if (start == -1) {
start = i;
}
end = i;
}
switch (state) {
case State.DOT:
end--;
break;
case State.DOT_DOT:
if (buf == null) {
buf = new StringBuilder(len);
}
if (end > 2) {
buf.append(path, start, end - 2);
buf.setLength(buf.lastIndexOf(RestConstants.SLASH) + 1);
start = -1;
}
break;
default:
}
if (buf == null) {
return start == -1 ? path : path.substring(start, end + 1);
}
if (start != -1) {
buf.append(path, start, end + 1);
}
return buf.toString();
}