getContext method
根据一个路径,获取路由上下文
Implementation
RouterContext getContext(String path, [String method = DEFAULT_METHOD]) {
assert(path != '');
final Uri uri = Uri.parse(path);
// 使用 / 拆分路径
Stack<String> pathParts = Stack(uri.pathSegments);
String pathPart;
Stack<MatchResult> matchedResults = Stack([MatchResult(root)]);
MatchResult lastMatchResult;
bool hasEnded = false;
while (pathParts.isNotEmpty && !hasEnded) {
pathPart = pathParts.pop();
if (pathPart == '') {
//忽略空的部分路径
continue;
}
lastMatchResult = matchedResults.top;
RouteNode currentNode = lastMatchResult.node;
MatchResult matchResult;
if (!lastMatchResult.partChildrenHadMatch) {
// 1. 在partChildren中匹配
matchResult = currentNode.matchPartChildren(pathPart);
lastMatchResult.partChildrenHadMatch = true;
}
// 2. 在paramChildren中匹配
if (matchResult == null) {
matchResult = currentNode.matchParamChildren(
pathPart, lastMatchResult.paramChildIndex);
}
// 3. 在wildChildren中匹配
if (matchResult == null) {
matchResult = currentNode.matchWildcardChild(pathPart);
}
if (matchResult != null) {
// 匹配到了路由节点
// 将匹配上的结果入栈
matchedResults.push(matchResult);
// 该情况是当前段已匹配上了一个节点,接下来继续匹配下一个节点
if (matchResult.node.type == NodeType.param) {
lastMatchResult.paramChildIndex++;
}
if (matchResult.node.type == NodeType.wildcard) {
pathParts.push(pathPart);
hasEnded = true;
// 匹配到通配节点,结束匹配
break;
}
if (pathParts.isEmpty && matchResult.node.getHandler(method) == null) {
// 已经匹配到路径最后了,但是没有找到对应的处理器函数,则需要检查回滚
if (matchResult.node.isHandleNode) {
// 匹配到了已绑定的路由,但是方法未能匹配,匹配已结束
hasEnded = true;
} else {
pathParts.push(pathPart);
matchedResults.pop();
switch (_backtrackingCheck(pathParts, matchedResults)) {
case _BacktrackingState.cant:
// 回溯之前需要判断层级,需要判断是不是每一层都已经回溯完了,如果都回溯完了的话,就表明当前路径是 404 的情况
// 不可回溯,如果可回溯的话,两个栈的状态都会回溯到正确位置
// 完全不可回溯了,也就是整个匹配过程已结束,但并未匹配上带当前方法的处理器的路由
return null;
break;
case _BacktrackingState.yes:
// ignore this do next loop
break;
case _BacktrackingState.stop:
hasEnded = true;
break;
}
}
}
} else {
// 当前这帧没有匹配上,则加回到栈中,然后再检查回溯条件
pathParts.push(pathPart);
switch (_backtrackingCheck(pathParts, matchedResults)) {
case _BacktrackingState.cant:
// 回溯之前需要判断层级,需要判断是不是每一层都已经回溯完了,如果都回溯完了的话,就表明当前路径是 404 的情况
// 不可回溯,如果可回溯的话,两个栈的状态都会回溯到正确位置
// 完全不可回溯了,也就是整个匹配过程已结束,但并未匹配上路由
return null;
case _BacktrackingState.yes:
// ignore this do next loop
break;
case _BacktrackingState.stop:
hasEnded = true;
break;
}
}
}
if (matchedResults.isEmpty) {
// 匹配完成之后,并未匹配到记录
return null;
}
// 已经匹配上了,根据匹配结果集构造路由上下文
RouterContext context =
_generateRouterContext(pathParts, matchedResults, method);
context.path = path;
context.queries = uri.queryParametersAll.map(
(String key, List<String> value) =>
MapEntry(key, value.length == 1 ? value[0] : value));
return context;
}