From 58e924e5e1b9e7665f9000a7fe92f9da64851507 Mon Sep 17 00:00:00 2001 From: Burt Beckwith Date: Sat, 27 Mar 2010 21:17:14 -0400 Subject: [PATCH] GRAILS-2495 delayed object references and creation to the extent possible --- .../web/metaclass/RedirectDynamicMethod.java | 163 ++++++++++-------- 1 file changed, 87 insertions(+), 76 deletions(-) diff --git a/src/java/org/codehaus/groovy/grails/web/metaclass/RedirectDynamicMethod.java b/src/java/org/codehaus/groovy/grails/web/metaclass/RedirectDynamicMethod.java index 9add045354f..76a588bb502 100644 --- a/src/java/org/codehaus/groovy/grails/web/metaclass/RedirectDynamicMethod.java +++ b/src/java/org/codehaus/groovy/grails/web/metaclass/RedirectDynamicMethod.java @@ -1,12 +1,12 @@ /* * Copyright 2004-2005 the original author or authors. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -19,6 +19,16 @@ import groovy.lang.Closure; import groovy.lang.GroovyObject; import groovy.lang.MissingMethodException; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.codehaus.groovy.grails.commons.ControllerArtefactHandler; @@ -35,20 +45,12 @@ import org.springframework.validation.Errors; import org.springframework.web.context.request.RequestContextHolder; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - /** - * Implements the "redirect" Controller method for action redirection - * + * Implements the "redirect" Controller method for action redirection. + * * @author Graeme Rocher * @since 0.2 - * + * * Created Oct 27, 2005 */ public class RedirectDynamicMethod extends AbstractDynamicMethodInvocation { @@ -67,127 +69,137 @@ public class RedirectDynamicMethod extends AbstractDynamicMethodInvocation { private static final String ARGUMENT_FRAGMENT = "fragment"; public static final String ARGUMENT_ERRORS = "errors"; - private static final Log LOG = LogFactory.getLog(RedirectDynamicMethod.class); private UrlMappingsHolder urlMappingsHolder; private boolean useJessionId = false; private ApplicationContext applicationContext; + /** + * Constructor. + * @param applicationContext + */ public RedirectDynamicMethod(ApplicationContext applicationContext) { super(METHOD_PATTERN); - if(applicationContext.containsBean(UrlMappingsHolder.BEAN_ID)) - this.urlMappingsHolder = (UrlMappingsHolder)applicationContext.getBean(UrlMappingsHolder.BEAN_ID); - GrailsApplication application = (GrailsApplication) applicationContext.getBean(GrailsApplication.APPLICATION_ID); + if (applicationContext.containsBean(UrlMappingsHolder.BEAN_ID)) { + urlMappingsHolder = (UrlMappingsHolder)applicationContext.getBean(UrlMappingsHolder.BEAN_ID); + } + + GrailsApplication application = (GrailsApplication)applicationContext.getBean(GrailsApplication.APPLICATION_ID); Object o = application.getFlatConfig().get(GRAILS_VIEWS_ENABLE_JSESSIONID); - if(o instanceof Boolean) { + if (o instanceof Boolean) { useJessionId = (Boolean) o; } this.applicationContext = applicationContext; - } + @SuppressWarnings("unchecked") + @Override public Object invoke(Object target, String methodName, Object[] arguments) { - if(arguments.length == 0) + if (arguments.length == 0) { throw new MissingMethodException(METHOD_SIGNATURE,target.getClass(),arguments); + } Map argMap = arguments[0] instanceof Map ? (Map)arguments[0] : Collections.EMPTY_MAP; - if(argMap.size() == 0){ + if (argMap.isEmpty()) { throw new MissingMethodException(METHOD_SIGNATURE,target.getClass(),arguments); } GrailsWebRequest webRequest = (GrailsWebRequest)RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = webRequest.getCurrentRequest(); - HttpServletResponse response = webRequest.getCurrentResponse(); - - if(request.getAttribute(GRAILS_REDIRECT_ISSUED)!=null) { + if (request.getAttribute(GRAILS_REDIRECT_ISSUED) != null) { throw new CannotRedirectException("Cannot issue a redirect(..) here. A previous call to redirect(..) has already redirected the response."); } - if(response.isCommitted()) { + + HttpServletResponse response = webRequest.getCurrentResponse(); + if (response.isCommitted()) { throw new CannotRedirectException("Cannot issue a redirect(..) here. The response has already been committed either by another redirect or by directly writing to the response."); } - - Object actionRef = argMap.get(ARGUMENT_ACTION); - String controllerName = getControllerName(target, argMap); - - Object id = argMap.get(ARGUMENT_ID); - String frag = argMap.get(ARGUMENT_FRAGMENT) != null ? argMap.get(ARGUMENT_FRAGMENT).toString() : null; - Object uri = argMap.get(ARGUMENT_URI); - String url = argMap.containsKey(ARGUMENT_URL) ? argMap.get(ARGUMENT_URL).toString() : null; - Map params = (Map)argMap.get(ARGUMENT_PARAMS); - if(params==null)params = new HashMap(); - Errors errors = (Errors)argMap.get(ARGUMENT_ERRORS); GroovyObject controller = (GroovyObject)target; // if there are errors add it to the list of errors - Errors controllerErrors = (Errors)controller.getProperty( ControllerDynamicMethods.ERRORS_PROPERTY ); - if(controllerErrors != null) { + Errors controllerErrors = (Errors)controller.getProperty(ControllerDynamicMethods.ERRORS_PROPERTY); + Errors errors = (Errors)argMap.get(ARGUMENT_ERRORS); + if (controllerErrors != null) { controllerErrors.addAllErrors(errors); } else { - controller.setProperty( ControllerDynamicMethods.ERRORS_PROPERTY, errors); + controller.setProperty(ControllerDynamicMethods.ERRORS_PROPERTY, errors); } + Object uri = argMap.get(ARGUMENT_URI); + String url = argMap.containsKey(ARGUMENT_URL) ? argMap.get(ARGUMENT_URL).toString() : null; String actualUri; - GrailsApplicationAttributes attrs = webRequest.getAttributes(); - - if(uri != null) { + if (uri != null) { + GrailsApplicationAttributes attrs = webRequest.getAttributes(); actualUri = attrs.getApplicationUri(request) + uri.toString(); } - else if(url != null) { + else if (url != null) { actualUri = url; } - else { - String actionName = establishActionName(actionRef, target, webRequest); + else { + Object actionRef = argMap.get(ARGUMENT_ACTION); + String actionName = establishActionName(actionRef, target); + String controllerName = getControllerName(target, argMap); controllerName = controllerName != null ? controllerName : webRequest.getControllerName(); - if(LOG.isDebugEnabled()) { - LOG.debug("Dynamic method [redirect] looking up URL mapping for controller ["+controllerName+"] and action ["+actionName+"] and params ["+params+"] with ["+urlMappingsHolder+"]"); + Map params = (Map)argMap.get(ARGUMENT_PARAMS); + if (params == null) { + params = new HashMap(); } + if (LOG.isDebugEnabled()) { + LOG.debug("Dynamic method [redirect] looking up URL mapping for controller ["+controllerName+"] and action ["+actionName+"] and params ["+params+"] with ["+urlMappingsHolder+"]"); + } - + Object id = argMap.get(ARGUMENT_ID); try { - if( id != null ) params.put( ARGUMENT_ID, id ); + if (id != null) { + params.put(ARGUMENT_ID, id); + } - UrlCreator urlMapping = urlMappingsHolder.getReverseMapping( controllerName, actionName, params ); - if( LOG.isDebugEnabled() && urlMapping == null ) { - LOG.debug( "Dynamic method [redirect] no URL mapping found for params [" + params + "]" ); + UrlCreator urlMapping = urlMappingsHolder.getReverseMapping(controllerName, actionName, params); + if (urlMapping == null && LOG.isDebugEnabled()) { + LOG.debug("Dynamic method [redirect] no URL mapping found for params [" + params + "]"); } - actualUri = urlMapping.createURL( controllerName, actionName, params, request.getCharacterEncoding(), frag ); + String frag = argMap.get(ARGUMENT_FRAGMENT) != null ? argMap.get(ARGUMENT_FRAGMENT).toString() : null; + actualUri = urlMapping.createURL(controllerName, actionName, params, request.getCharacterEncoding(), frag); - if( LOG.isDebugEnabled() ) { - LOG.debug( "Dynamic method [redirect] mapped to URL [" + actualUri + "]" ); + if (LOG.isDebugEnabled()) { + LOG.debug("Dynamic method [redirect] mapped to URL [" + actualUri + "]"); + } + } + finally { + if (id != null) { + params.remove(ARGUMENT_ID); } - - } finally { - if( id != null ) params.remove( ARGUMENT_ID ); } - } return redirectResponse(actualUri, request,response); } + @SuppressWarnings("unchecked") private String getControllerName(Object target, Map argMap) { - return argMap.containsKey(ARGUMENT_CONTROLLER) ? argMap.get(ARGUMENT_CONTROLLER).toString() : GrailsNameUtils.getLogicalPropertyName(target.getClass().getName(), ControllerArtefactHandler.TYPE); + return argMap.containsKey(ARGUMENT_CONTROLLER) ? + argMap.get(ARGUMENT_CONTROLLER).toString() : + GrailsNameUtils.getLogicalPropertyName(target.getClass().getName(), + ControllerArtefactHandler.TYPE); } - /* * Redirects the response the the given URI */ private Object redirectResponse(String actualUri, HttpServletRequest request, HttpServletResponse response) { - if(LOG.isDebugEnabled()) { + if (LOG.isDebugEnabled()) { LOG.debug("Dynamic method [redirect] forwarding request to ["+actualUri +"]"); } try { - - if(LOG.isDebugEnabled()) { + if (LOG.isDebugEnabled()) { LOG.debug("Executing redirect with response ["+response+"]"); } @@ -195,12 +207,12 @@ private Object redirectResponse(String actualUri, HttpServletRequest request, Ht response.sendRedirect(redirectUrl); Map redirectListeners = applicationContext.getBeansOfType(RedirectEventListener.class); for (RedirectEventListener redirectEventListener : redirectListeners.values()) { - redirectEventListener.responseRedirected(redirectUrl); + redirectEventListener.responseRedirected(redirectUrl); } request.setAttribute(GRAILS_REDIRECT_ISSUED, true); - - } catch (IOException e) { + } + catch (IOException e) { throw new CannotRedirectException("Error redirecting request for url ["+actualUri +"]: " + e.getMessage(),e); } return null; @@ -209,18 +221,17 @@ private Object redirectResponse(String actualUri, HttpServletRequest request, Ht /* * Figures out the action name from the specified action reference (either a string or closure) */ - private String establishActionName(Object actionRef, Object target, GrailsWebRequest webRequest) { + private String establishActionName(Object actionRef, Object target) { String actionName = null; - if(actionRef instanceof String) { - actionName = (String)actionRef; - } else if(actionRef instanceof CharSequence) { + if (actionRef instanceof String) { + actionName = (String)actionRef; + } + else if (actionRef instanceof CharSequence) { actionName = actionRef.toString(); } - else if(actionRef instanceof Closure) { - Closure c = (Closure)actionRef; - actionName = GrailsClassUtils.findPropertyNameForValue(target, c); + else if (actionRef instanceof Closure) { + actionName = GrailsClassUtils.findPropertyNameForValue(target, actionRef); } return actionName; } - }