public static String normalize()

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();
    }