001package io.jstach.opt.spring.webmvc; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import org.eclipse.jdt.annotation.Nullable; 007import org.springframework.context.ApplicationContext; 008import org.springframework.web.servlet.HandlerInterceptor; 009import org.springframework.web.servlet.ModelAndView; 010import org.springframework.web.servlet.View; 011import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 012import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 013 014import jakarta.servlet.http.HttpServletRequest; 015import jakarta.servlet.http.HttpServletResponse; 016 017/** 018 * A {@link HandlerInterceptor} that automatically applies all 019 * {@link JStachioModelViewConfigurer} instances to views before rendering. Also 020 * implements {@link WebMvcConfigurer} so that it registers itself when the servlet 021 * context starts. 022 * 023 * @author dsyer 024 */ 025@SuppressWarnings("exports") 026public class ViewSetupHandlerInterceptor implements HandlerInterceptor, WebMvcConfigurer { 027 028 private final List<JStachioModelViewConfigurer> configurers = new ArrayList<>(); 029 030 private final ApplicationContext context; 031 032 /** 033 * Injected context will be searched for {@link JStachioModelViewConfigurer} 034 * @param context autowired. 035 */ 036 public ViewSetupHandlerInterceptor(ApplicationContext context) { 037 for (String name : context.getBeanNamesForType(JStachioModelViewConfigurer.class)) { 038 this.configurers.add((JStachioModelViewConfigurer) context.getBean(name)); 039 } 040 this.context = context; 041 } 042 043 /** 044 * {@inheritDoc} If the modelAndView is a {@link JStachioModelView} then it will be 045 * configured with all of the found {@link JStachioModelViewConfigurer} in the 046 * application context. 047 */ 048 @Override 049 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 050 ModelAndView modelAndView) throws Exception { 051 @Nullable 052 JStachioModelView view = findView(modelAndView); 053 if (view != null) { 054 Object page = view.model(); 055 for (JStachioModelViewConfigurer configurer : configurers) { 056 configurer.configure(page, modelAndView.getModel(), request); 057 } 058 } 059 } 060 061 private @Nullable JStachioModelView findView(ModelAndView modelAndView) { 062 if (modelAndView != null) { 063 if (modelAndView.getView() instanceof JStachioModelView) { 064 return (JStachioModelView) modelAndView.getView(); 065 } 066 if (modelAndView.getView() instanceof View) { 067 return null; 068 } 069 if (this.context.containsBean(modelAndView.getViewName()) 070 && this.context.getBean(modelAndView.getViewName()) instanceof JStachioModelView view) { 071 return view; 072 } 073 } 074 return null; 075 } 076 077 @Override 078 public void addInterceptors(InterceptorRegistry registry) { 079 registry.addInterceptor(this); 080 } 081 082}