@Override protected Object retrieveAction( GroovyObject controller, String actionName, HttpServletResponse response) { Class<?> controllerClass = AopProxyUtils.ultimateTargetClass(controller); Method mAction = ReflectionUtils.findMethod( controllerClass, actionName, MethodGrailsControllerHelper.NOARGS); if (mAction != null) { ReflectionUtils.makeAccessible(mAction); if (mAction.getAnnotation(Action.class) != null) { return mAction; } } try { return controller.getProperty(actionName); } catch (MissingPropertyException mpe) { try { response.sendError(HttpServletResponse.SC_NOT_FOUND); return null; } catch (IOException e) { throw new ControllerExecutionException("I/O error sending 404 error", e); } } }
public final Collection<ConfigAttribute> getAttributes(Object object) { if (object instanceof MethodInvocation) { MethodInvocation mi = (MethodInvocation) object; Object target = mi.getThis(); Class<?> targetClass = null; if (target != null) { targetClass = target instanceof Class<?> ? (Class<?>) target : AopProxyUtils.ultimateTargetClass(target); } Collection<ConfigAttribute> attrs = getAttributes(mi.getMethod(), targetClass); if (attrs != null && !attrs.isEmpty()) { return attrs; } if (target != null && !(target instanceof Class<?>)) { attrs = getAttributes(mi.getMethod(), target.getClass()); } return attrs; } throw new IllegalArgumentException("Object must be a non-null MethodInvocation"); }
@Override protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws Exception { // TODO need blocking cache stuff from CachingFilter initContext(); try { Object controller = lookupController(getContext().getControllerClass()); if (controller == null) { log.debug( "Not a controller request {}:{} {}", request.getMethod(), request.getRequestURI(), getContext()); chain.doFilter(request, response); return; } Class<?> controllerClass = AopProxyUtils.ultimateTargetClass(controller); if (controllerClass == null) { controllerClass = controller.getClass(); } Method method = getContext().getMethod(); if (method == null) { log.debug( "No cacheable method found for {}:{} {}", request.getMethod(), request.getRequestURI(), getContext()); chain.doFilter(request, response); return; } Collection<CacheOperation> cacheOperations = cacheOperationSource.getCacheOperations(method, controllerClass, true); if (CollectionUtils.isEmpty(cacheOperations)) { log.debug( "No cacheable annotation found for {}:{} {}", request.getMethod(), request.getRequestURI(), getContext()); chain.doFilter(request, response); return; } Map<String, Collection<CacheOperationContext>> operationsByType = createOperationContext(cacheOperations, method, controllerClass, request); // start with evictions if (inspectBeforeCacheEvicts(operationsByType.get(EVICT))) { chain.doFilter(request, response); return; } // follow up with cacheable CacheStatus status = inspectCacheables(operationsByType.get(CACHEABLE)); Map<CacheOperationContext, Object> updates = inspectCacheUpdates(operationsByType.get(UPDATE)); if (status != null) { if (status.updateRequired) { updates.putAll(status.updates); } // render cached response else { logRequestDetails(request, getContext(), "Caching enabled for request"); PageInfo pageInfo = buildCachedPageInfo(request, response, status); writeResponse(request, response, pageInfo); return; } } logRequestDetails(request, getContext(), "Caching enabled for request"); PageInfo pageInfo = buildNewPageInfo(request, response, chain, status, operationsByType); writeResponse(request, response, pageInfo); inspectAfterCacheEvicts(operationsByType.get(EVICT)); if (!updates.isEmpty()) { Collection<Cache> caches = new ArrayList<Cache>(); for (Map.Entry<CacheOperationContext, Object> entry : updates.entrySet()) { for (Cache cache : entry.getKey().getCaches()) { caches.add(cache); } } update(caches, pageInfo, status, calculateKey(request)); } } finally { destroyContext(); } }
@SuppressWarnings("unchecked") protected final <T> Class<T> getClass(T object) { return (Class<T>) AopProxyUtils.ultimateTargetClass(object); }