in dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/rest/mapping/condition/PathParser.java [72:237]
private void parseSegments(String path) {
int state = State.INITIAL;
boolean regexBraceStart = false;
boolean regexMulti = false;
String variableName = null;
int len = path.length();
for (int i = 0; i < len; i++) {
char c = path.charAt(i);
switch (c) {
case '/':
switch (state) {
case State.INITIAL:
case State.SEGMENT_END:
continue;
case State.LITERAL_START:
if (buf.length() > 0) {
appendSegment(Type.LITERAL);
}
break;
case State.WILDCARD_START:
appendSegment(Type.WILDCARD);
break;
case State.REGEX_VARIABLE_START:
if (path.charAt(i - 1) != '^' || path.charAt(i - 2) != '[') {
regexMulti = true;
}
buf.append(c);
continue;
case State.VARIABLE_START:
case State.WILDCARD_VARIABLE_START:
throw new PathParserException(Messages.MISSING_CLOSE_CAPTURE, path, i);
default:
}
segments.add(SLASH);
state = State.SEGMENT_END;
continue;
case '?':
switch (state) {
case State.INITIAL:
case State.LITERAL_START:
case State.SEGMENT_END:
state = State.WILDCARD_START;
break;
default:
}
break;
case '*':
switch (state) {
case State.INITIAL:
case State.LITERAL_START:
case State.SEGMENT_END:
state = State.WILDCARD_START;
break;
case State.VARIABLE_START:
if (path.charAt(i - 1) == '{') {
state = State.WILDCARD_VARIABLE_START;
continue;
}
break;
default:
}
break;
case '.':
if (state == State.REGEX_VARIABLE_START) {
if (path.charAt(i - 1) != '\\') {
regexMulti = true;
}
}
break;
case 'S':
case 'W':
if (state == State.REGEX_VARIABLE_START) {
if (path.charAt(i - 1) == '\\') {
regexMulti = true;
}
}
break;
case ':':
if (state == State.VARIABLE_START) {
state = State.REGEX_VARIABLE_START;
variableName = buf.toString();
buf.setLength(0);
continue;
}
break;
case '{':
switch (state) {
case State.INITIAL:
case State.SEGMENT_END:
state = State.VARIABLE_START;
continue;
case State.LITERAL_START:
if (buf.length() > 0) {
appendSegment(Type.LITERAL);
}
state = State.VARIABLE_START;
continue;
case State.VARIABLE_START:
case State.WILDCARD_VARIABLE_START:
throw new PathParserException(Messages.ILLEGAL_NESTED_CAPTURE, path, i);
case State.REGEX_VARIABLE_START:
if (path.charAt(i - 1) != '\\') {
regexBraceStart = true;
}
break;
default:
}
break;
case '}':
switch (state) {
case State.INITIAL:
case State.LITERAL_START:
case State.SEGMENT_END:
throw new PathParserException(Messages.MISSING_OPEN_CAPTURE, path);
case State.VARIABLE_START:
appendSegment(Type.VARIABLE, buf.toString());
state = State.LITERAL_START;
continue;
case State.REGEX_VARIABLE_START:
if (regexBraceStart) {
regexBraceStart = false;
} else {
if (buf.length() == 0) {
throw new PathParserException(Messages.MISSING_REGEX_CONSTRAINT, path, i);
}
appendSegment(regexMulti ? Type.PATTERN_MULTI : Type.PATTERN, variableName);
regexMulti = false;
state = State.LITERAL_START;
continue;
}
break;
case State.WILDCARD_VARIABLE_START:
appendSegment(Type.WILDCARD_TAIL, buf.toString());
state = State.END;
continue;
default:
}
break;
default:
if (state == State.INITIAL || state == State.SEGMENT_END) {
state = State.LITERAL_START;
}
break;
}
if (state == State.END) {
throw new PathParserException(Messages.NO_MORE_DATA_ALLOWED, path, i);
}
buf.append(c);
}
if (buf.length() > 0) {
switch (state) {
case State.LITERAL_START:
appendSegment(Type.LITERAL);
break;
case State.WILDCARD_START:
appendSegment(Type.WILDCARD);
break;
case State.VARIABLE_START:
case State.REGEX_VARIABLE_START:
case State.WILDCARD_VARIABLE_START:
throw new PathParserException(Messages.MISSING_CLOSE_CAPTURE, path, len - 1);
default:
}
}
}