1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.blossom.web;
35
36 import info.magnolia.module.blossom.view.UuidRedirectViewResolver;
37 import info.magnolia.repository.RepositoryConstants;
38
39 import java.lang.reflect.InvocationTargetException;
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import org.springframework.beans.factory.BeanInitializationException;
45 import org.springframework.core.MethodParameter;
46 import org.springframework.util.PatternMatchUtils;
47 import org.springframework.web.context.request.NativeWebRequest;
48 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
49 import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
50 import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
51 import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
52 import org.springframework.web.method.support.ModelAndViewContainer;
53 import org.springframework.web.servlet.ModelAndView;
54 import org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler;
55 import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
56 import org.springframework.web.servlet.mvc.method.annotation.ViewNameMethodReturnValueHandler;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public class BlossomRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
75
76 public String[] redirectPatterns = new String[]{RepositoryConstants.WEBSITE + ":*", "dms:*"};
77
78 public String[] getRedirectPatterns() {
79 return redirectPatterns;
80 }
81
82
83
84
85
86
87 public void setRedirectPatterns(String... redirectPatterns) {
88 this.redirectPatterns = redirectPatterns;
89 }
90
91 @Override
92 public void afterPropertiesSet() {
93 super.afterPropertiesSet();
94
95 List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>(getExistingReturnValueHandlers());
96
97 for (int i = 0; i < handlers.size(); i++) {
98 HandlerMethodReturnValueHandler handler = handlers.get(i);
99 if (handler instanceof ViewNameMethodReturnValueHandler) {
100 handlers.set(i, new ViewNameMethodReturnValueHandler() {
101
102 @Override
103 protected boolean isRedirectViewName(String viewName) {
104 return super.isRedirectViewName(viewName) || BlossomRequestMappingHandlerAdapter.this.isRedirectViewName(viewName);
105 }
106 });
107 }
108 if (handler instanceof ModelAndViewMethodReturnValueHandler) {
109 handlers.set(i, new ModelAndViewMethodReturnValueHandler() {
110
111 @Override
112 public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
113 if (returnValue != null) {
114 ModelAndView mav = (ModelAndView) returnValue;
115 if (mav.isReference()) {
116 String viewName = mav.getViewName();
117 if (viewName != null && BlossomRequestMappingHandlerAdapter.this.isRedirectViewName(viewName)) {
118 mavContainer.setRedirectModelScenario(true);
119 }
120 }
121 }
122 super.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
123 }
124 });
125 }
126 }
127
128 super.setReturnValueHandlers(handlers);
129
130 List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(getExistingHandlerMethodArgumentResolvers());
131 sortArgumentResolvers(resolvers);
132 super.setArgumentResolvers(resolvers);
133 }
134
135 protected void sortArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
136
137 Iterator<HandlerMethodArgumentResolver> iterator = resolvers.iterator();
138 while (iterator.hasNext()) {
139 HandlerMethodArgumentResolver resolver = iterator.next();
140 if (resolver instanceof BlossomHandlerMethodArgumentResolver) {
141 iterator.remove();
142 resolvers.add(0, resolver);
143 break;
144 }
145 }
146 }
147
148
149
150
151
152
153
154
155 private List<HandlerMethodReturnValueHandler> getExistingReturnValueHandlers() {
156
157 Object returnValueHandlers;
158 try {
159 returnValueHandlers = getClass().getMethod("getReturnValueHandlers").invoke(this);
160 } catch (IllegalAccessException e) {
161 throw new BeanInitializationException("Could not get existing return value handlers", e);
162 } catch (InvocationTargetException e) {
163 throw new BeanInitializationException("Could not get existing return value handlers", e.getTargetException());
164 } catch (NoSuchMethodException e) {
165 throw new BeanInitializationException("Could not get existing return value handlers", e);
166 }
167
168 if (returnValueHandlers instanceof List) {
169 return (List<HandlerMethodReturnValueHandler>) returnValueHandlers;
170 }
171
172 if (returnValueHandlers instanceof HandlerMethodReturnValueHandlerComposite) {
173 return ((HandlerMethodReturnValueHandlerComposite) returnValueHandlers).getHandlers();
174 }
175
176 throw new BeanInitializationException("Could not get existing return value handlers");
177 }
178
179
180
181
182
183
184
185
186 private List<HandlerMethodArgumentResolver> getExistingHandlerMethodArgumentResolvers() {
187
188 Object argumentResolvers;
189 try {
190 argumentResolvers = getClass().getMethod("getArgumentResolvers").invoke(this);
191 } catch (IllegalAccessException e) {
192 throw new BeanInitializationException("Could not get existing argument resolvers", e);
193 } catch (InvocationTargetException e) {
194 throw new BeanInitializationException("Could not get existing argument resolvers", e.getTargetException());
195 } catch (NoSuchMethodException e) {
196 throw new BeanInitializationException("Could not get existing argument resolvers", e);
197 }
198
199 if (argumentResolvers instanceof List) {
200 return (List<HandlerMethodArgumentResolver>) argumentResolvers;
201 }
202
203 if (argumentResolvers instanceof HandlerMethodArgumentResolverComposite) {
204 return ((HandlerMethodArgumentResolverComposite) argumentResolvers).getResolvers();
205 }
206
207 throw new BeanInitializationException("Could not get existing argument resolvers");
208 }
209
210 protected boolean isRedirectViewName(String viewName) {
211 return viewName.equals(UuidRedirectViewResolver.REDIRECT_MAIN_CONTENT_PLACEHOLDER) ||
212 viewName.equals(UuidRedirectViewResolver.REDIRECT_CURRENT_CONTENT_PLACEHOLDER) ||
213 (redirectPatterns != null && PatternMatchUtils.simpleMatch(redirectPatterns, viewName));
214 }
215 }