RequestMappingRegistry.java

package sprout.mvc.mapping;

import sprout.beans.annotation.Component;
import sprout.mvc.http.HttpMethod;

import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class RequestMappingRegistry {
    private final Map<PathPattern, Map<HttpMethod, RequestMappingInfo>> mappings = new ConcurrentHashMap<>();

    public void register(PathPattern pathPattern, HttpMethod httpMethod, Object controller, Method handlerMethod) {
        System.out.println("Registering request mapping for " + pathPattern.getOriginalPattern() + " with http method " + httpMethod);
        mappings.computeIfAbsent(pathPattern, k -> new EnumMap<>(HttpMethod.class))
                .put(httpMethod, new RequestMappingInfo(pathPattern, httpMethod, controller, handlerMethod));
    }

    public RequestMappingInfo getHandlerMethod(String path, HttpMethod httpMethod) {
        List<RequestMappingInfo> matchingHandlers = new ArrayList<>();

        // 1. 먼저 요청 경로와 일치하는 모든 핸들러를 찾는다.
        for (PathPattern registeredPattern : mappings.keySet()) {
            if (registeredPattern.matches(path)) {
                Map<HttpMethod, RequestMappingInfo> methodMappings = mappings.get(registeredPattern);
                if (methodMappings != null && methodMappings.containsKey(httpMethod)) {
                    matchingHandlers.add(methodMappings.get(httpMethod));
                }
            }
        }
        if (matchingHandlers.isEmpty()) {
            return null;
        }
        // 2. 찾은 핸들러들을 PathPattern의 우선순위에 따라 정렬한다.
        matchingHandlers.sort(Comparator.comparing(RequestMappingInfo::pattern));

        // 3. 가장 우선순위가 높은 (가장 구체적인) 핸들러를 반환한다.
        return matchingHandlers.get(0);
    }
}