Skip to content

Commit

Permalink
refactor: AnnotationHandlerMapping 메서드 리팩터링
Browse files Browse the repository at this point in the history
  • Loading branch information
BGuga committed Sep 13, 2023
1 parent c852c27 commit f368be6
Showing 1 changed file with 34 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import web.org.springframework.web.bind.annotation.RequestMapping;
import web.org.springframework.web.bind.annotation.RequestMethod;

public class AnnotationHandlerMapping {

Expand All @@ -44,55 +40,22 @@ private void validateBasePackage(Object[] basePackage) {

public void initialize() {
log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.putAll(findHandlersFrom(basePackage));
handlerExecutions.putAll(extractHandler());
}

private Map<HandlerKey, HandlerExecution> findHandlersFrom(Object[] basePackage) {
List<String> basePackages = convertToString(basePackage);
Map<HandlerKey, HandlerExecution> handlers = new HashMap<>();
for (String targetPackage : basePackages) {
Map<HandlerKey, HandlerExecution> packageHandler = extractHandler(targetPackage);
checkDuplication(handlers, packageHandler);
handlers.putAll(packageHandler);
}
return handlers;
}

private static List<String> convertToString(Object[] basePackage) {
return Arrays.stream(basePackage)
.map(o -> (String) o)
.collect(Collectors.toList());
}

private Map<HandlerKey, HandlerExecution> extractHandler(String targetPackage) {
Reflections reflections = new Reflections(targetPackage);
private Map<HandlerKey, HandlerExecution> extractHandler() {
Reflections reflections = new Reflections(basePackage);
return reflections.getTypesAnnotatedWith(Controller.class).stream()
.map(this::extractHandlerFromClass)
.reduce(
new HashMap<>(),
migrateHandler());
}

private void checkDuplication(Map<HandlerKey, HandlerExecution> originHandlers,
Map<HandlerKey, HandlerExecution> newHandlers) {
Set<HandlerKey> duplicatedHandlerKeys = new HashSet<>(originHandlers.keySet());
duplicatedHandlerKeys.retainAll(newHandlers.keySet());
if (!duplicatedHandlerKeys.isEmpty()) {
HandlerKey duplicatedHandlerKey = duplicatedHandlerKeys.iterator().next();
log.error("duplication handler : {}", duplicatedHandlerKey);
throw new IllegalArgumentException("Duplicated HandlerKey");
}
.reduce(new HashMap<>(), migrateHandler());
}

private Map<HandlerKey, HandlerExecution> extractHandlerFromClass(Class<?> targetClass) {
Object handler = makeClass(targetClass);
return Arrays.stream(targetClass.getMethods())
.filter(this::haveRequestMapping)
.map(method -> extractHandlerFromMethod(method, handler))
.reduce(
new HashMap<>(),
migrateHandler()
);
.reduce(new HashMap<>(), migrateHandler());
}

private Object makeClass(Class<?> targetClass) {
Expand All @@ -106,47 +69,49 @@ private Object makeClass(Class<?> targetClass) {
}
}

private Map<HandlerKey, HandlerExecution> extractHandlerFromMethod(Method method,
Object handler) {
return Arrays.stream(method.getAnnotation(RequestMapping.class).method())
.map(makeHandler(method, handler, method.getAnnotation(RequestMapping.class)))
.reduce(
new HashMap<>(),
migrateHandler()
);
private boolean haveRequestMapping(Method method) {
return Arrays.stream(method.getDeclaredAnnotations())
.anyMatch(RequestMapping.class::isInstance);
}

private Function<RequestMethod, Map<HandlerKey, HandlerExecution>> makeHandler(Method method,
Object handler,
RequestMapping requestMapping) {
return requestMethod -> {
Map<HandlerKey, HandlerExecution> extractedHandlerMapping = new HashMap<>();
extractedHandlerMapping.put(
new HandlerKey(requestMapping.value(), requestMethod),
new HandlerExecution(handler, method)
);
return extractedHandlerMapping;
};
private Map<HandlerKey, HandlerExecution> extractHandlerFromMethod(Method method,
Object handler) {
HandlerExecution handlerExecution = new HandlerExecution(handler, method);
RequestMapping annotation = method.getAnnotation(RequestMapping.class);
return Arrays.stream(annotation.method())
.map(requestMethod -> {
Map<HandlerKey, HandlerExecution> extractedHandlerMapping = new HashMap<>();
extractedHandlerMapping.put(new HandlerKey(annotation.value(), requestMethod),
handlerExecution);
return extractedHandlerMapping;
})
.reduce(new HashMap<>(), migrateHandler());
}

private BinaryOperator<Map<HandlerKey, HandlerExecution>> migrateHandler() {
return (extractedHandler, extractingController) -> {
checkDuplication(extractedHandler, extractingController);
extractedHandler.putAll(extractingController);
return extractedHandler;
return (originHandler, migrateHandler) -> {
checkDuplication(originHandler, migrateHandler);
originHandler.putAll(migrateHandler);
return originHandler;
};
}

private boolean haveRequestMapping(Method method) {
return Arrays.stream(method.getDeclaredAnnotations())
.anyMatch(RequestMapping.class::isInstance);
private void checkDuplication(Map<HandlerKey, HandlerExecution> originHandlers,
Map<HandlerKey, HandlerExecution> newHandlers) {
Set<HandlerKey> duplicatedHandlerKeys = new HashSet<>(originHandlers.keySet());
duplicatedHandlerKeys.retainAll(newHandlers.keySet());
if (!duplicatedHandlerKeys.isEmpty()) {
HandlerKey duplicatedHandlerKey = duplicatedHandlerKeys.iterator().next();
log.error("duplication handler : {}", duplicatedHandlerKey);
throw new IllegalArgumentException("Duplicated HandlerKey");
}
}

public Object getHandler(final HttpServletRequest request) {
Optional<HandlerKey> findHandler = handlerExecutions.keySet().stream()
.filter(handlerKey -> handlerKey.canHandle(request))
.findAny();
return findHandler.map(handlerExecutions::get)
.orElse(null);
.orElseGet(null);
}
}

0 comments on commit f368be6

Please sign in to comment.