192 } |
192 } |
193 if (paramsInjectible) { |
193 if (paramsInjectible) { |
194 try { |
194 try { |
195 PathPattern pathPattern = new PathPattern(mapping.get().requestPath()); |
195 PathPattern pathPattern = new PathPattern(mapping.get().requestPath()); |
196 |
196 |
197 if (mappings |
197 final var methodMappings = mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()); |
198 .computeIfAbsent(mapping.get().method(), k -> new HashMap<>()) |
198 final var currentMapping = methodMappings.putIfAbsent(pathPattern, method); |
199 .putIfAbsent(pathPattern, method) != null) { |
199 if (currentMapping != null) { |
200 LOG.warn("{} {} has multiple mappings", |
200 LOG.warn("Cannot map {} {} to {} in class {} - this would override the mapping to {}", |
201 mapping.get().method(), |
201 mapping.get().method(), |
202 mapping.get().requestPath() |
202 mapping.get().requestPath(), |
|
203 method.getName(), |
|
204 getClass().getSimpleName(), |
|
205 currentMapping.getName() |
203 ); |
206 ); |
204 } |
207 } |
205 |
208 |
206 LOG.debug("{} {} maps to {}::{}", |
209 LOG.debug("{} {} maps to {}::{}", |
207 mapping.get().method(), |
210 mapping.get().method(), |
294 */ |
297 */ |
295 public void setViewModel(HttpServletRequest req, Object viewModel) { |
298 public void setViewModel(HttpServletRequest req, Object viewModel) { |
296 req.setAttribute(Constants.REQ_ATTR_VIEWMODEL, viewModel); |
299 req.setAttribute(Constants.REQ_ATTR_VIEWMODEL, viewModel); |
297 } |
300 } |
298 |
301 |
|
302 private <T> Optional<T> parseParameter(String paramValue, Class<T> clazz) { |
|
303 if (paramValue == null) return Optional.empty(); |
|
304 if (clazz.equals(Boolean.class)) { |
|
305 if (paramValue.toLowerCase().equals("false") || paramValue.equals("0")) { |
|
306 return Optional.of((T) Boolean.FALSE); |
|
307 } else { |
|
308 return Optional.of((T) Boolean.TRUE); |
|
309 } |
|
310 } |
|
311 if (clazz.equals(String.class)) return Optional.of((T) paramValue); |
|
312 if (java.sql.Date.class.isAssignableFrom(clazz)) { |
|
313 try { |
|
314 return Optional.of((T) java.sql.Date.valueOf(paramValue)); |
|
315 } catch (IllegalArgumentException ex) { |
|
316 return Optional.empty(); |
|
317 } |
|
318 } |
|
319 try { |
|
320 final Constructor<T> ctor = clazz.getConstructor(String.class); |
|
321 return Optional.of(ctor.newInstance(paramValue)); |
|
322 } catch (ReflectiveOperationException e) { |
|
323 // does not type check and is not convertible - treat as if the parameter was never set |
|
324 return Optional.empty(); |
|
325 } |
|
326 } |
|
327 |
299 /** |
328 /** |
300 * Obtains a request parameter of the specified type. |
329 * Obtains a request parameter of the specified type. |
301 * The specified type must have a single-argument constructor accepting a string to perform conversion. |
330 * The specified type must have a single-argument constructor accepting a string to perform conversion. |
302 * The constructor of the specified type may throw an exception on conversion failures. |
331 * The constructor of the specified type may throw an exception on conversion failures. |
303 * |
332 * |
320 throw new RuntimeException(e); |
349 throw new RuntimeException(e); |
321 } |
350 } |
322 } |
351 } |
323 return Optional.of(array); |
352 return Optional.of(array); |
324 } else { |
353 } else { |
325 final String paramValue = req.getParameter(name); |
354 return parseParameter(req.getParameter(name), clazz); |
326 if (paramValue == null) return Optional.empty(); |
|
327 if (clazz.equals(Boolean.class)) { |
|
328 if (paramValue.toLowerCase().equals("false") || paramValue.equals("0")) { |
|
329 return Optional.of((T) Boolean.FALSE); |
|
330 } else { |
|
331 return Optional.of((T) Boolean.TRUE); |
|
332 } |
|
333 } |
|
334 if (clazz.equals(String.class)) return Optional.of((T) paramValue); |
|
335 if (java.sql.Date.class.isAssignableFrom(clazz)) { |
|
336 try { |
|
337 return Optional.of((T) java.sql.Date.valueOf(paramValue)); |
|
338 } catch (IllegalArgumentException ex) { |
|
339 return Optional.empty(); |
|
340 } |
|
341 } |
|
342 try { |
|
343 final Constructor<T> ctor = clazz.getConstructor(String.class); |
|
344 return Optional.of(ctor.newInstance(paramValue)); |
|
345 } catch (ReflectiveOperationException e) { |
|
346 // does not type check and is not convertible - treat as if the parameter was never set |
|
347 return Optional.empty(); |
|
348 } |
|
349 } |
355 } |
350 } |
356 } |
351 |
357 |
352 /** |
358 /** |
353 * Tries to look up an entity with a key obtained from a request parameter. |
359 * Tries to look up an entity with a key obtained from a request parameter. |