Skip to content
Browse files

Namespaced controller support

  • Loading branch information...
1 parent 31e7396 commit 9da894e24ce76247b8f4090940ee0660e27a417c @jeffbrown jeffbrown committed with jeffbrown
Showing with 428 additions and 97 deletions.
  1. +34 −4 grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/ControllerArtefactHandler.java
  2. +3 −2 ...ls-plugin-controllers/src/main/groovy/org/codehaus/groovy/grails/web/metaclass/ChainMethod.groovy
  3. +1 −1 ...plugin-gsp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/ApplicationTagLib.groovy
  4. +2 −1 grails-plugin-url-mappings/src/main/groovy/grails/test/GrailsUrlMappingsTestCase.groovy
  5. +24 −6 ...plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlCreator.java
  6. +25 −4 ...l-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingEvaluator.java
  7. +7 −1 ...in-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingInfo.java
  8. +43 −23 ...url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingsHolder.java
  9. +35 −10 ...s-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/RegexUrlMapping.java
  10. +19 −3 ...n-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/ResponseCodeUrlMapping.java
  11. +14 −1 ...url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java
  12. +16 −1 grails-test-suite-web/src/test/groovy/grails/test/GrailsUrlMappingsTestCaseTests.groovy
  13. +14 −14 ...test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping/RegexUrlMappingTests.groovy
  14. +52 −0 ...t-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/taglib/LinkRenderingTagLibTests.groovy
  15. +7 −1 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/AbstractUrlMapping.java
  16. +4 −3 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultLinkGenerator.groovy
  17. +2 −0 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/ForwardUrlMappingInfo.groovy
  18. +50 −0 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlCreator.java
  19. +44 −15 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlCreatorCache.java
  20. +2 −0 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMapping.java
  21. +2 −0 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappingInfo.java
  22. +2 −2 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappingsHolder.java
  23. +1 −0 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsApplicationAttributes.java
  24. +14 −2 ...ls-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsControllerHandlerMapping.java
  25. +8 −1 ...eb/src/main/groovy/org/codehaus/groovy/grails/web/servlet/mvc/AbstractGrailsControllerHelper.java
  26. +3 −2 ...ow/src/main/groovy/org/codehaus/groovy/grails/webflow/engine/builder/RuntimeRedirectAction.groovy
View
38 ...ls-core/src/main/groovy/org/codehaus/groovy/grails/commons/ControllerArtefactHandler.java
@@ -15,8 +15,13 @@
*/
package org.codehaus.groovy.grails.commons;
+import java.util.Map;
+
import grails.util.Environment;
+import grails.util.GrailsNameUtils;
+import org.codehaus.groovy.grails.plugins.GrailsPlugin;
+import org.codehaus.groovy.grails.plugins.GrailsPluginManager;
import org.codehaus.groovy.grails.plugins.support.aware.GrailsApplicationAware;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
@@ -68,12 +73,22 @@ public String getPluginName() {
}
@Override
- public GrailsClass getArtefactForFeature(Object feature) {
+ public GrailsClass getArtefactForFeature(Object featureId) {
if (artefactInfo == null) {
return null;
}
+
+ String uri = null;
+ String pluginName = null;
+
+ if(featureId instanceof Map) {
+ Map featureIdMap = (Map)featureId;
+ uri = (String)featureIdMap.get("uri");
+ pluginName = (String)featureIdMap.get("pluginName");
+ } else {
+ uri = featureId.toString();
+ }
- String uri = feature.toString();
GrailsClass controllerClass = uriToControllerClassCache.get(uri);
if (controllerClass == null) {
final GrailsClass[] controllerClasses = artefactInfo.getGrailsClasses();
@@ -81,8 +96,23 @@ public GrailsClass getArtefactForFeature(Object feature) {
for (int i = (controllerClasses.length-1); i >= 0; i--) {
GrailsClass c = controllerClasses[i];
if (((GrailsControllerClass) c).mapsToURI(uri)) {
- controllerClass = c;
- break;
+ boolean foundController = false;
+ if(pluginName != null) {
+ Object bean = grailsApplication.getMainContext().getBean("pluginManager");
+ if(bean instanceof GrailsPluginManager) {
+ GrailsPluginManager gpm = (GrailsPluginManager) bean;
+ GrailsPlugin pluginForClass = gpm.getPluginForClass(c.getClazz());
+ if(pluginForClass != null && pluginName.equals(pluginForClass.getName())) {
+ foundController = true;
+ }
+ }
+ } else {
+ foundController = true;
+ }
+ if(foundController) {
+ controllerClass = c;
+ break;
+ }
}
}
if (controllerClass == null) {
View
5 ...n-controllers/src/main/groovy/org/codehaus/groovy/grails/web/metaclass/ChainMethod.groovy
@@ -35,6 +35,7 @@ class ChainMethod {
def controller = args.controller ?: GrailsNameUtils.getLogicalPropertyName(
target.class.name, ControllerArtefactHandler.TYPE)
def action = args.action
+ def plugin = args.remove('plugin')
def id = args.id
def params = args.params ?: [:]
def model = args.model ?: [:]
@@ -70,10 +71,10 @@ class ChainMethod {
// the reverse URL mapping.
if (id) params.id = id
- UrlCreator creator = mappings.getReverseMapping(controller, action, params)
+ UrlCreator creator = mappings.getReverseMapping(controller, action, plugin, params)
def response = webRequest.getCurrentResponse()
- def url = response.encodeRedirectURL(creator.createURL(controller,action, params, 'utf-8'))
+ def url = response.encodeRedirectURL(creator.createURL(controller, action, plugin, params, 'utf-8'))
response.sendRedirect url
}
}
View
2 ...sp/src/main/groovy/org/codehaus/groovy/grails/plugins/web/taglib/ApplicationTagLib.groovy
@@ -219,7 +219,7 @@ class ApplicationTagLib implements ApplicationContextAware, InitializingBean, Gr
if (elementId) {
writer << " id=\"${elementId}\""
}
-
+ attrs.remove('plugin')
def remainingKeys = attrs.keySet() - LinkGenerator.LINK_ATTRIBUTES
for (key in remainingKeys) {
writer << " " << key << "=\"" << attrs[key]?.encodeAsHTML() << "\""
View
3 grails-plugin-url-mappings/src/main/groovy/grails/test/GrailsUrlMappingsTestCase.groovy
@@ -206,13 +206,14 @@ class GrailsUrlMappingsTestCase extends GroovyTestCase {
void assertReverseUrlMapping(assertions, url, paramAssertions) {
def controller = assertions.controller
def action = assertions.action
+ def plugin = assertions.plugin
def params = [:]
if (paramAssertions) {
paramAssertions.delegate = params
paramAssertions.resolveStrategy = Closure.DELEGATE_ONLY
paramAssertions.call()
}
- def urlCreator = mappingsHolder.getReverseMapping(controller, action, params)
+ def urlCreator = mappingsHolder.getReverseMapping(controller, action, plugin, params)
assertNotNull("could not create reverse mapping of '$url' for {controller = $controller, action = $action, params = $params}", urlCreator)
def createdUrl = urlCreator.createRelativeURL(controller, action, params, "UTF-8")
assertEquals("reverse mapping assertion for {controller = $controller, action = $action, params = $params}", url, createdUrl)
View
30 ...rl-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlCreator.java
@@ -102,12 +102,16 @@ private String createURLWithWebRequest(Map parameterValues, GrailsWebRequest web
return actualUriBuf.toString();
}
- @SuppressWarnings("unchecked")
public String createURL(String controller, String action, Map parameterValues, String encoding) {
- return createURLInternal(controller, action, parameterValues, true);
+ return createURL(controller, action, null, parameterValues, encoding);
+ }
+
+ @SuppressWarnings("unchecked")
+ public String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding) {
+ return createURLInternal(controller, action, pluginName, parameterValues, true);
}
- private String createURLInternal(String controller, String action,
+ private String createURLInternal(String controller, String action, String pluginName,
Map<String, String> parameterValues, boolean includeContextPath) {
GrailsWebRequest webRequest = (GrailsWebRequest) RequestContextHolder.getRequestAttributes();
@@ -137,17 +141,31 @@ private String createURLInternal(String controller, String action,
@SuppressWarnings("unchecked")
public String createRelativeURL(String controller, String action, Map parameterValues, String encoding) {
- return createURLInternal(controller, action, parameterValues, false);
+ return createRelativeURL(controller, action, null, parameterValues, encoding);
+ }
+
+ @SuppressWarnings("unchecked")
+ public String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding) {
+ return createURLInternal(controller, action, pluginName, parameterValues, false);
}
@SuppressWarnings("unchecked")
public String createRelativeURL(String controller, String action, Map parameterValues, String encoding, String fragment) {
- final String url = createURLInternal(controller, action, parameterValues, false);
+ return createRelativeURL(controller, action, null, parameterValues, encoding, fragment);
+ }
+
+ @SuppressWarnings("unchecked")
+ public String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment) {
+ final String url = createURLInternal(controller, action, pluginName, parameterValues, false);
return createUrlWithFragment(encoding, fragment, url);
}
public String createURL(String controller, String action, Map parameterValues, String encoding, String fragment) {
- String url = createURL(controller, action, parameterValues, encoding);
+ return createURL(controller, action, null, parameterValues, encoding, fragment);
+ }
+
+ public String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment) {
+ String url = createURL(controller, action, pluginName, parameterValues, encoding);
return createUrlWithFragment(encoding, fragment, url);
}
View
29 ...gs/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingEvaluator.java
@@ -224,6 +224,7 @@ public Object call(Object... args) {
private Map<String, Object> parameterValues = new HashMap<String, Object>();
private Binding binding;
private Object actionName = null;
+ private Object pluginName = null;
private Object controllerName = null;
private Object viewName = null;
private ServletContext sc;
@@ -292,6 +293,14 @@ public void setController(Object controller) {
public Object getController() {
return controllerName;
}
+
+ public void setPlugin(Object plugin) {
+ pluginName = plugin;
+ }
+
+ public Object getPlugin() {
+ return pluginName;
+ }
public Object getView() {
return viewName;
@@ -352,6 +361,8 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
@SuppressWarnings("hiding")
Object actionName;
@SuppressWarnings("hiding")
+ Object pluginName;
+ @SuppressWarnings("hiding")
Object viewName;
@SuppressWarnings("hiding")
Object uri;
@@ -361,10 +372,12 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
actionName = binding.getVariables().get(GrailsControllerClass.ACTION);
viewName = binding.getVariables().get(GrailsControllerClass.VIEW);
uri = binding.getVariables().get("uri");
+ pluginName = binding.getVariables().get("plugin");
}
else {
controllerName = this.controllerName;
actionName = this.actionName;
+ pluginName = this.pluginName;
viewName = this.viewName;
uri = this.uri;
}
@@ -380,7 +393,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
}
}
else {
- urlMapping = createURLMapping(urlData, isResponseCode, controllerName, actionName, viewName, constraints);
+ urlMapping = createURLMapping(urlData, isResponseCode, controllerName, actionName, pluginName, viewName, constraints);
}
if (binding != null) {
@@ -416,6 +429,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
controllerName = null;
actionName = null;
viewName = null;
+ pluginName = null;
}
previousConstraints.clear();
urlDefiningMode = true;
@@ -506,6 +520,8 @@ private UrlMapping getURLMappingForNamedArgs(Map namedArguments,
controllerName = getControllerName(namedArguments, bindingVariables);
actionName = getActionName(namedArguments, bindingVariables);
}
+ @SuppressWarnings("hiding")
+ Object pluginName = getPluginName(namedArguments, bindingVariables);
@SuppressWarnings("hiding")
Object viewName = getViewName(namedArguments, bindingVariables);
@@ -528,7 +544,7 @@ private UrlMapping getURLMappingForNamedArgs(Map namedArguments,
}
}
else {
- urlMapping = createURLMapping(urlData, isResponseCode, controllerName, actionName, viewName, constraints);
+ urlMapping = createURLMapping(urlData, isResponseCode, controllerName, actionName, pluginName, viewName, constraints);
}
Object exceptionArg = getException(namedArguments, bindingVariables);
@@ -588,6 +604,10 @@ private Object getControllerName(Map namedArguments, Map bindingVariables) {
return getVariableFromNamedArgsOrBinding(namedArguments, bindingVariables,GrailsControllerClass.CONTROLLER, controllerName);
}
+ private Object getPluginName(Map namedArguments, Map bindingVariables) {
+ return getVariableFromNamedArgsOrBinding(namedArguments, bindingVariables, "plugin", pluginName);
+ }
+
private Object getViewName(Map namedArguments, Map bindingVariables) {
return getVariableFromNamedArgsOrBinding(namedArguments, bindingVariables,GrailsControllerClass.VIEW, viewName);
}
@@ -603,13 +623,14 @@ private Object getException(Map namedArguments, Map bindingVariables) {
private UrlMapping createURLMapping(UrlMappingData urlData, boolean isResponseCode,
@SuppressWarnings("hiding") Object controllerName,
@SuppressWarnings("hiding") Object actionName,
+ @SuppressWarnings("hiding") Object pluginName,
@SuppressWarnings("hiding") Object viewName, ConstrainedProperty[] constraints) {
if (!isResponseCode) {
- return new RegexUrlMapping(urlData, controllerName, actionName, viewName,
+ return new RegexUrlMapping(urlData, controllerName, actionName, pluginName, viewName,
constraints, sc);
}
- return new ResponseCodeUrlMapping(urlData, controllerName, actionName, viewName,
+ return new ResponseCodeUrlMapping(urlData, controllerName, actionName, pluginName, viewName,
null, sc);
}
}
View
8 ...appings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingInfo.java
@@ -48,6 +48,7 @@
private Object controllerName;
private Object actionName;
+ private Object pluginName;
private Object id;
private static final String ID_PARAM = "id";
private UrlMappingData urlData;
@@ -70,13 +71,14 @@ private DefaultUrlMappingInfo(Map params, UrlMappingData urlData, ServletContext
}
@SuppressWarnings("rawtypes")
- public DefaultUrlMappingInfo(Object controllerName, Object actionName, Object viewName, Map params,
+ public DefaultUrlMappingInfo(Object controllerName, Object actionName, Object pluginName, Object viewName, Map params,
UrlMappingData urlData, ServletContext servletContext) {
this(params, urlData, servletContext);
Assert.isTrue(controllerName != null || viewName != null, "URL mapping must either provide a controller or view name to map to!");
Assert.notNull(params, "Argument [params] cannot be null");
this.controllerName = controllerName;
this.actionName = actionName;
+ this.pluginName = pluginName;
if (actionName == null) {
this.viewName = viewName;
}
@@ -112,6 +114,10 @@ public boolean isParsingRequest() {
public void setParsingRequest(boolean parsingRequest) {
this.parsingRequest = parsingRequest;
}
+
+ public String getPluginName() {
+ return pluginName != null ? pluginName.toString() : null;
+ }
public String getControllerName() {
String name = evaluateNameForValue(controllerName);
View
66 ...ings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingsHolder.java
@@ -116,6 +116,7 @@ public void initialize() {
}
String controllerName = mapping.getControllerName() instanceof String ? mapping.getControllerName().toString() : null;
String actionName = mapping.getActionName() instanceof String ? mapping.getActionName().toString() : null;
+ String pluginName = mapping.getPluginName() instanceof String ? mapping.getPluginName().toString() : null;
ConstrainedProperty[] params = mapping.getConstraints();
Set<String> requiredParams = new HashSet<String>();
@@ -130,10 +131,10 @@ public void initialize() {
break;
}
}
- UrlMappingKey key = new UrlMappingKey(controllerName, actionName, requiredParams);
+ UrlMappingKey key = new UrlMappingKey(controllerName, actionName, pluginName, requiredParams);
mappingsLookup.put(key, mapping);
- UrlMappingsListKey listKey = new UrlMappingsListKey(controllerName, actionName);
+ UrlMappingsListKey listKey = new UrlMappingsListKey(controllerName, actionName, pluginName);
mappingsListLookup.put(listKey, key);
if (LOG.isDebugEnabled()) {
@@ -144,10 +145,10 @@ public void initialize() {
for (int j = optionalIndex; j < params.length; j++) {
ConstrainedProperty param = params[j];
requiredParamsAndOptionals.add(param.getPropertyName());
- key = new UrlMappingKey(controllerName, actionName, new HashSet<String>(requiredParamsAndOptionals));
+ key = new UrlMappingKey(controllerName, actionName, pluginName, new HashSet<String>(requiredParamsAndOptionals));
mappingsLookup.put(key, mapping);
- listKey = new UrlMappingsListKey(controllerName, actionName);
+ listKey = new UrlMappingsListKey(controllerName, actionName, pluginName);
mappingsListLookup.put(listKey, key);
if (LOG.isDebugEnabled()) {
@@ -183,17 +184,21 @@ public List getExcludePatterns() {
return excludePatterns;
}
+ public UrlCreator getReverseMapping(final String controller, final String action, Map params) {
+ return getReverseMapping(controller, action, null, params);
+ }
+
/**
* @see UrlMappingsHolder#getReverseMapping(String, String, java.util.Map)
*/
- public UrlCreator getReverseMapping(final String controller, final String action, Map params) {
+ public UrlCreator getReverseMapping(final String controller, final String action, final String pluginName, Map params) {
if (params == null) params = Collections.EMPTY_MAP;
if (urlCreatorCache != null) {
- UrlCreatorCache.ReverseMappingKey key=urlCreatorCache.createKey(controller, action, params);
+ UrlCreatorCache.ReverseMappingKey key=urlCreatorCache.createKey(controller, action, pluginName, params);
UrlCreator creator=urlCreatorCache.lookup(key);
if (creator==null) {
- creator=resolveUrlCreator(controller, action, params, true);
+ creator=resolveUrlCreator(controller, action, pluginName, params, true);
creator=urlCreatorCache.putAndDecorate(key, creator);
}
// preserve previous side-effect, remove mappingName from params
@@ -201,17 +206,17 @@ public UrlCreator getReverseMapping(final String controller, final String action
return creator;
}
// cache is disabled
- return resolveUrlCreator(controller, action, params, true);
+ return resolveUrlCreator(controller, action, pluginName, params, true);
}
- public UrlCreator getReverseMappingNoDefault(String controller, String action, Map params) {
+ public UrlCreator getReverseMappingNoDefault(String controller, String action, String pluginName, Map params) {
if (params == null) params = Collections.EMPTY_MAP;
if (urlCreatorCache != null) {
- UrlCreatorCache.ReverseMappingKey key=urlCreatorCache.createKey(controller, action, params);
+ UrlCreatorCache.ReverseMappingKey key=urlCreatorCache.createKey(controller, action, pluginName, params);
UrlCreator creator=urlCreatorCache.lookup(key);
if (creator==null) {
- creator=resolveUrlCreator(controller, action, params, false);
+ creator=resolveUrlCreator(controller, action, pluginName, params, false);
if (creator != null) {
creator = urlCreatorCache.putAndDecorate(key, creator);
}
@@ -221,30 +226,32 @@ public UrlCreator getReverseMappingNoDefault(String controller, String action, M
return creator;
}
// cache is disabled
- return resolveUrlCreator(controller, action, params, true);
+ return resolveUrlCreator(controller, action, pluginName, params, true);
}
@SuppressWarnings("unchecked")
private UrlCreator resolveUrlCreator(final String controller,
- final String action, Map params, boolean useDefault) {
+ final String action,
+ final String pluginName,
+ Map params, boolean useDefault) {
UrlMapping mapping = null;
mapping = namedMappings.get(params.remove("mappingName"));
if (mapping == null) {
- mapping = lookupMapping(controller, action, params);
+ mapping = lookupMapping(controller, action, pluginName, params);
}
if (mapping == null || (mapping instanceof ResponseCodeUrlMapping)) {
- mapping = mappingsLookup.get(new UrlMappingKey(controller, action, Collections.EMPTY_SET));
+ mapping = mappingsLookup.get(new UrlMappingKey(controller, action, pluginName, Collections.EMPTY_SET));
}
if (mapping == null || (mapping instanceof ResponseCodeUrlMapping)) {
Set<String> lookupParams = new HashSet<String>(DEFAULT_ACTION_PARAMS);
Set<String> paramKeys = new HashSet<String>(params.keySet());
paramKeys.removeAll(lookupParams);
lookupParams.addAll(paramKeys);
- mapping = mappingsLookup.get(new UrlMappingKey(controller, null, lookupParams));
+ mapping = mappingsLookup.get(new UrlMappingKey(controller, null, pluginName, lookupParams));
if (mapping == null) {
lookupParams.removeAll(paramKeys);
- mapping = mappingsLookup.get(new UrlMappingKey(controller, null, lookupParams));
+ mapping = mappingsLookup.get(new UrlMappingKey(controller, null, pluginName, lookupParams));
}
}
if (mapping == null || (mapping instanceof ResponseCodeUrlMapping)) {
@@ -253,10 +260,10 @@ private UrlCreator resolveUrlCreator(final String controller,
paramKeys.removeAll(lookupParams);
lookupParams.addAll(paramKeys);
- mapping = mappingsLookup.get(new UrlMappingKey(null, null, lookupParams));
+ mapping = mappingsLookup.get(new UrlMappingKey(null, null, pluginName, lookupParams));
if (mapping == null) {
lookupParams.removeAll(paramKeys);
- mapping = mappingsLookup.get(new UrlMappingKey(null, null, lookupParams));
+ mapping = mappingsLookup.get(new UrlMappingKey(null, null, pluginName, lookupParams));
}
}
UrlCreator creator = null;
@@ -282,8 +289,8 @@ private UrlCreator resolveUrlCreator(final String controller,
* @return A UrlMapping instance or null
*/
@SuppressWarnings("unchecked")
- protected UrlMapping lookupMapping(String controller, String action, Map params) {
- final UrlMappingsListKey lookupKey = new UrlMappingsListKey(controller, action);
+ protected UrlMapping lookupMapping(String controller, String action, String pluginName, Map params) {
+ final UrlMappingsListKey lookupKey = new UrlMappingsListKey(controller, action, pluginName);
SortedSet mappingKeysSet = mappingsListLookup.get(lookupKey);
final String actionName = lookupKey.action;
@@ -424,11 +431,13 @@ public String toString() {
class UrlMappingKey implements Comparable {
String controller;
String action;
+ String pluginName;
Set<String> paramNames = Collections.EMPTY_SET;
- public UrlMappingKey(String controller, String action, Set<String> paramNames) {
+ public UrlMappingKey(String controller, String action, String pluginName, Set<String> paramNames) {
this.controller = controller;
this.action = action;
+ this.pluginName = pluginName;
this.paramNames = paramNames;
}
@@ -441,6 +450,7 @@ public boolean equals(Object o) {
if (action != null && !action.equals(that.action)) return false;
if (controller != null && !controller.equals(that.controller)) return false;
+ if (pluginName != null && !pluginName.equals(that.pluginName)) return false;
if (!paramNames.equals(that.paramNames)) return false;
return true;
@@ -451,6 +461,7 @@ public int hashCode() {
int result;
result = (controller != null ? controller.hashCode() : 0);
result = 31 * result + (action != null ? action.hashCode() : 0);
+ result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
result = 31 * result + paramNames.hashCode();
return result;
}
@@ -459,6 +470,7 @@ public int hashCode() {
public String toString() {
return new ToStringCreator(this).append("controller", controller)
.append("action",action)
+ .append("plugin",pluginName)
.append("params", paramNames)
.toString();
}
@@ -482,6 +494,9 @@ public int compareTo(Object o) {
comparison = action != null ? action.compareTo(other.action) : EQUAL;
if (comparison != EQUAL) return comparison;
+ comparison = pluginName != null ? pluginName.compareTo(other.pluginName) : EQUAL;
+ if (comparison != EQUAL) return comparison;
+
return EQUAL;
}
}
@@ -492,10 +507,12 @@ public int compareTo(Object o) {
class UrlMappingsListKey {
String controller;
String action;
+ String pluginName;
- public UrlMappingsListKey(String controller, String action) {
+ public UrlMappingsListKey(String controller, String action, String pluginName) {
this.controller = controller;
this.action = action;
+ this.pluginName = pluginName;
}
@Override
@@ -507,6 +524,7 @@ public boolean equals(Object o) {
if (action != null && !action.equals(that.action)) return false;
if (controller != null && !controller.equals(that.controller)) return false;
+ if (pluginName != null && !pluginName.equals(that.pluginName)) return false;
return true;
}
@@ -516,6 +534,7 @@ public int hashCode() {
int result;
result = (controller != null ? controller.hashCode() : 0);
result = 31 * result + (action != null ? action.hashCode() : 0);
+ result = 31 * result + (pluginName != null ? pluginName.hashCode() : 0);
return result;
}
@@ -523,6 +542,7 @@ public int hashCode() {
public String toString() {
return new ToStringCreator(this).append("controller", controller)
.append("action",action)
+ .append("plugin",pluginName)
.toString();
}
}
View
45 ...-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/RegexUrlMapping.java
@@ -85,9 +85,9 @@
* @param servletContext
* @see org.codehaus.groovy.grails.validation.ConstrainedProperty
*/
- public RegexUrlMapping(UrlMappingData data, Object controllerName, Object actionName,
+ public RegexUrlMapping(UrlMappingData data, Object controllerName, Object actionName, Object pluginName,
Object viewName, ConstrainedProperty[] constraints, ServletContext servletContext) {
- super(controllerName, actionName, viewName, constraints != null ? constraints : new ConstrainedProperty[0], servletContext);
+ super(controllerName, actionName, pluginName, viewName, constraints != null ? constraints : new ConstrainedProperty[0], servletContext);
this.grailsApplication = GrailsWebUtil.lookupApplication(servletContext);
parse(data, constraints);
}
@@ -290,17 +290,22 @@ public String createURL(Map paramValues, String encoding, String fragment) {
}
public String createURL(String controller, String action, Map paramValues, String encoding) {
- return createURLInternal(controller, action, paramValues, encoding, true);
+ return createURL(controller, action, null, paramValues, encoding);
}
+ public String createURL(String controller, String action, String pluginName, Map paramValues, String encoding) {
+ return createURLInternal(controller, action, pluginName, paramValues, encoding, true);
+ }
+
@SuppressWarnings("unchecked")
- private String createURLInternal(String controller, String action, Map paramValues,
+ private String createURLInternal(String controller, String action, String pluginName, Map paramValues,
String encoding, boolean includeContextPath) {
if (paramValues == null) paramValues = new HashMap();
boolean hasController = !StringUtils.isBlank(controller);
boolean hasAction = !StringUtils.isBlank(action);
+ boolean hasPlugin = !StringUtils.isBlank(pluginName);
try {
if (hasController) {
@@ -309,6 +314,9 @@ private String createURLInternal(String controller, String action, Map paramValu
if (hasAction) {
paramValues.put(ACTION, action);
}
+ if (hasPlugin) {
+ paramValues.put("plugin", pluginName);
+ }
return createURLInternal(paramValues, encoding, includeContextPath);
}
@@ -319,25 +327,42 @@ private String createURLInternal(String controller, String action, Map paramValu
if (hasAction) {
paramValues.remove(ACTION);
}
+ if (hasPlugin) {
+ paramValues.remove("plugin");
+ }
}
}
public String createRelativeURL(String controller, String action, Map paramValues, String encoding) {
- return createURLInternal(controller, action, paramValues, encoding, false);
+ return createRelativeURL(controller, action, null, paramValues, encoding);
}
+ public String createRelativeURL(String controller, String action, String pluginName, Map paramValues, String encoding) {
+ return createURLInternal(controller, action, pluginName, paramValues, encoding, false);
+ }
+
public String createRelativeURL(String controller, String action, Map paramValues,
String encoding, String fragment) {
- final String url = createURLInternal(controller, action, paramValues, encoding, false);
- return createUrlWithFragment(url, fragment, encoding);
+ return createRelativeURL(controller, action, null, paramValues, encoding, fragment);
}
- public String createURL(String controller, String action, Map paramValues,
+ public String createRelativeURL(String controller, String action, String pluginName, Map paramValues,
String encoding, String fragment) {
- String url = createURL(controller, action, paramValues, encoding);
+ final String url = createURLInternal(controller, action, pluginName, paramValues, encoding, false);
return createUrlWithFragment(url, fragment, encoding);
}
+
+ public String createURL(String controller, String action, Map paramValues,
+ String encoding, String fragment) {
+ return createURL(controller, action, null, paramValues, encoding, fragment);
+ }
+ public String createURL(String controller, String action, String pluginName, Map paramValues,
+ String encoding, String fragment) {
+ String url = createURL(controller, action, pluginName, paramValues, encoding);
+ return createUrlWithFragment(url, fragment, encoding);
+ }
+
private String createUrlWithFragment(String url, String fragment, String encoding) {
if (fragment != null) {
// A 'null' encoding will cause an exception, so default to 'UTF-8'.
@@ -483,7 +508,7 @@ else if (viewName != null && controllerName == null) {
info = new DefaultUrlMappingInfo(viewName, params, urlData, servletContext);
}
else {
- info = new DefaultUrlMappingInfo(controllerName, actionName, getViewName(), params, urlData, servletContext);
+ info = new DefaultUrlMappingInfo(controllerName, actionName, pluginName, getViewName(), params, urlData, servletContext);
}
if (parseRequest) {
View
22 ...ppings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/ResponseCodeUrlMapping.java
@@ -36,8 +36,8 @@
private Map parameterValues = Collections.EMPTY_MAP;
private Class<?> exceptionType;
- public ResponseCodeUrlMapping(UrlMappingData urlData, Object controllerName, Object actionName, Object viewName, ConstrainedProperty[] constraints, ServletContext servletContext) {
- super(controllerName, actionName, viewName, constraints, servletContext);
+ public ResponseCodeUrlMapping(UrlMappingData urlData, Object controllerName, Object actionName, Object pluginName, Object viewName, ConstrainedProperty[] constraints, ServletContext servletContext) {
+ super(controllerName, actionName, pluginName, viewName, constraints, servletContext);
this.urlData = (ResponseCodeMappingData) urlData;
Assert.isTrue(constraints == null || constraints.length == 0,
@@ -93,21 +93,37 @@ public String createURL(String controller, String action, Map values, String enc
throw new UnsupportedOperationException("Method createURL not implemented in " + getClass());
}
+ public String createURL(String controller, String action, String pluginName, Map values, String encoding) {
+ throw new UnsupportedOperationException("Method createURL not implemented in " + getClass());
+ }
+
public String createRelativeURL(String controller, String action, Map values, String encoding) {
throw new UnsupportedOperationException("Method createRelativeURL not implemented in " + getClass());
}
+ public String createRelativeURL(String controller, String action, String pluginName, Map values, String encoding) {
+ throw new UnsupportedOperationException("Method createRelativeURL not implemented in " + getClass());
+ }
+
public String createRelativeURL(String controller, String action, Map values, String encoding, String fragment) {
throw new UnsupportedOperationException("Method createRelativeURL not implemented in " + getClass());
}
+ public String createRelativeURL(String controller, String action, String pluginName, Map values, String encoding, String fragment) {
+ throw new UnsupportedOperationException("Method createRelativeURL not implemented in " + getClass());
+ }
+
public String createURL(String controller, String action, Map values, String encoding, String fragment) {
throw new UnsupportedOperationException("Method createURL not implemented in " + getClass());
}
+ public String createURL(String controller, String action, String pluginName, Map values, String encoding, String fragment) {
+ throw new UnsupportedOperationException("Method createURL not implemented in " + getClass());
+ }
+
public UrlMappingInfo match(int responseCode) {
if (responseCode == urlData.getResponseCode()) {
- return new DefaultUrlMappingInfo(controllerName, actionName, viewName,
+ return new DefaultUrlMappingInfo(controllerName, actionName, pluginName, viewName,
parameterValues, urlData, servletContext);
}
return null;
View
15 ...ings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java
@@ -176,12 +176,25 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
viewName = info.getViewName();
if (viewName == null && info.getURI() == null) {
final String controllerName = info.getControllerName();
- GrailsClass controller = application.getArtefactForFeature(ControllerArtefactHandler.TYPE, WebUtils.SLASH + urlConverter.toUrlElement(controllerName) + WebUtils.SLASH + urlConverter.toUrlElement(action));
+ String pluginName = info.getPluginName();
+ String featureUri = WebUtils.SLASH + urlConverter.toUrlElement(controllerName) + WebUtils.SLASH + urlConverter.toUrlElement(action);
+
+ Object featureId = null;
+ if(pluginName != null) {
+ Map featureIdMap = new HashMap();
+ featureIdMap.put("uri", featureUri);
+ featureIdMap.put("pluginName", pluginName);
+ featureId = featureIdMap;
+ } else {
+ featureId = featureUri;
+ }
+ GrailsClass controller = application.getArtefactForFeature(ControllerArtefactHandler.TYPE, featureId);
if (controller == null) {
continue;
}
webRequest.setAttribute(GrailsApplicationAttributes.CONTROLLER_NAME_ATTRIBUTE, controller.getLogicalPropertyName(), WebRequest.SCOPE_REQUEST);
+ webRequest.setAttribute(GrailsApplicationAttributes.CONTROLLER_ATTRIBUTE, controller, WebRequest.SCOPE_REQUEST);
}
}
catch (Exception e) {
View
17 grails-test-suite-web/src/test/groovy/grails/test/GrailsUrlMappingsTestCaseTests.groovy
@@ -396,11 +396,16 @@ class GrailsUrlMappingsTestCaseFakeController {
class MockUrlMapping implements UrlMapping {
String controller
String action
+ String plugin
boolean restfulMapping
MockUrlMapping(String controller, String action) {
+ this(controller, action, null)
+ }
+ MockUrlMapping(String controller, String action, String pluginName) {
this.controller = controller
this.action = action
+ this.plugin = pluginName
}
boolean equals(other) {
@@ -418,19 +423,29 @@ class MockUrlMapping implements UrlMapping {
String createURL(Map parameterValues, String encoding, String fragment) { null }
String createURL(String controller, String action, Map parameterValues, String encoding) { null }
-
+
+ String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding) { null }
+
String createRelativeURL(String controller, String action, Map parameterValues, String encoding) { null }
+ String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding) { null }
+
String createRelativeURL(String controller, String action, Map parameterValues, String encoding, String fragment) { null }
+ String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment) { null }
+
String createURL(String controller, String action, Map parameterValues, String encoding, String fragment) { null }
+ String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment) { null }
+
ConstrainedProperty[] getConstraints() { new ConstrainedProperty[0] }
Object getControllerName() { controller }
Object getActionName() { action }
+ Object getPluginName() { plugin }
+
Object getViewName() { null }
void setParameterValues(Map parameterValues) {}
View
28 ...te-web/src/test/groovy/org/codehaus/groovy/grails/web/mapping/RegexUrlMappingTests.groovy
@@ -176,16 +176,16 @@ mappings {
void testComparable() {
def parser = new DefaultUrlMappingParser()
- def m1 = new RegexUrlMapping(parser.parse("/foo/"), "test", null, null, null, servletContext)
- def m2 = new RegexUrlMapping(parser.parse("/"), "test", null, null, null, servletContext)
- def m3 = new RegexUrlMapping(parser.parse("/foo/bar/(*)"), "test", null, null, null, servletContext)
- def m4 = new RegexUrlMapping(parser.parse("/foo/(*)/bar"), "test", null, null, null, servletContext)
- def m5 = new RegexUrlMapping(parser.parse("/(*)/foo/bar"), "test", null, null, null, servletContext)
- def m6 = new RegexUrlMapping(parser.parse("/foo/(*)"), "test", null, null, null, servletContext)
- def m7 = new RegexUrlMapping(parser.parse("/(*)"), "test", null, null, null, servletContext)
- def m8 = new RegexUrlMapping(parser.parse("/foo/(*)/(*)"), "test", null, null, null, servletContext)
- def m9 = new RegexUrlMapping(parser.parse("/(*)/(*)/bar"), "test", null, null, null, servletContext)
- def m10 = new RegexUrlMapping(parser.parse("/(*)/(*)/(*)"), "test", null, null, null, servletContext)
+ def m1 = new RegexUrlMapping(parser.parse("/foo/"), "test", null, null, null, null, servletContext)
+ def m2 = new RegexUrlMapping(parser.parse("/"), "test", null, null, null, null, servletContext)
+ def m3 = new RegexUrlMapping(parser.parse("/foo/bar/(*)"), "test", null, null, null, null, servletContext)
+ def m4 = new RegexUrlMapping(parser.parse("/foo/(*)/bar"), "test", null, null, null, null, servletContext)
+ def m5 = new RegexUrlMapping(parser.parse("/(*)/foo/bar"), "test", null, null, null, null, servletContext)
+ def m6 = new RegexUrlMapping(parser.parse("/foo/(*)"), "test", null, null, null, null, servletContext)
+ def m7 = new RegexUrlMapping(parser.parse("/(*)"), "test", null, null, null, null, servletContext)
+ def m8 = new RegexUrlMapping(parser.parse("/foo/(*)/(*)"), "test", null, null, null, null, servletContext)
+ def m9 = new RegexUrlMapping(parser.parse("/(*)/(*)/bar"), "test", null, null, null, null, servletContext)
+ def m10 = new RegexUrlMapping(parser.parse("/(*)/(*)/(*)"), "test", null, null, null, null, servletContext)
assertTrue m1.compareTo(m2) > 0
@@ -311,7 +311,7 @@ mappings {
// mapping would be "/foo/$hello/bar
def parser = new DefaultUrlMappingParser()
- def m = new RegexUrlMapping(parser.parse('/foo/(*)/bar'), "test", "action", null, [cp] as ConstrainedProperty[], servletContext)
+ def m = new RegexUrlMapping(parser.parse('/foo/(*)/bar'), "test", "action", null, null, [cp] as ConstrainedProperty[], servletContext)
def info = m.match("/foo/world/bar")
assert info
@@ -327,7 +327,7 @@ mappings {
// mapping would be "/foo/$hello/bar
def parser = new DefaultUrlMappingParser()
- def m = new RegexUrlMapping(parser.parse('/foo/(*)/bar'), "test", "action", null, [cp] as ConstrainedProperty[], servletContext)
+ def m = new RegexUrlMapping(parser.parse('/foo/(*)/bar'), "test", "action", null, null, [cp] as ConstrainedProperty[], servletContext)
def info = m.match("/foo/2007/bar")
assert info
@@ -356,12 +356,12 @@ mappings {
void testInit() {
def parser = new DefaultUrlMappingParser()
- def m = new RegexUrlMapping(parser.parse("/(*)/hello"), "test", null, null, [] as ConstrainedProperty[], servletContext)
+ def m = new RegexUrlMapping(parser.parse("/(*)/hello"), "test", null, null, null, [] as ConstrainedProperty[], servletContext)
}
void testMatchUriNoConstraints() {
def parser = new DefaultUrlMappingParser()
- def m = new RegexUrlMapping(parser.parse("/foo/(*)/bar"), "test", null, null, [] as ConstrainedProperty[], servletContext)
+ def m = new RegexUrlMapping(parser.parse("/foo/(*)/bar"), "test", null, null, null, [] as ConstrainedProperty[], servletContext)
def info = m.match("/foo/test/bar")
assert info
View
52 ...web/src/test/groovy/org/codehaus/groovy/grails/web/taglib/LinkRenderingTagLibTests.groovy
@@ -31,6 +31,20 @@ class TestUrlMappings {
}
"/dummy/$action/$name/$id"(controller: "test2")
+
+ "/pluginOneFirstController" {
+ controller = 'first'
+ action = 'index'
+ plugin = 'firstUtil'
+ }
+
+ "/pluginTwoFirstController/$num?" {
+ controller = 'first'
+ action = 'index'
+ plugin = 'secondUtil'
+ }
+
+ "/pluginThreeFirstController"(controller: 'first', action: 'index', plugin: 'thirdUtil')
}
}
''')
@@ -38,6 +52,44 @@ class TestUrlMappings {
grailsApplication.addArtefact(UrlMappingsArtefactHandler.TYPE, mappingClass)
}
+ void testMappingsWhichSpecifyAPlugin() {
+ def template = '<g:link controller="first" action="index" plugin="firstUtil">click</g:link>'
+ assertOutputEquals '<a href="/pluginOneFirstController">click</a>', template
+
+ template = '<g:link controller="first" action="index" plugin="secondUtil">click</g:link>'
+ assertOutputEquals '<a href="/pluginTwoFirstController">click</a>', template
+
+ template = '<g:link controller="first" action="index" plugin="thirdUtil">click</g:link>'
+ assertOutputEquals '<a href="/pluginThreeFirstController">click</a>', template
+
+ template = '<g:link controller="first" action="index" plugin="firstUtil" params="[num: 42]" >click</g:link>'
+ assertOutputEquals '<a href="/pluginOneFirstController?num=42">click</a>', template
+
+ template = '<g:link controller="first" action="index" plugin="secondUtil" params="[num: 42]" >click</g:link>'
+ assertOutputEquals '<a href="/pluginTwoFirstController/42">click</a>', template
+
+ template = '<g:link controller="first" action="index" plugin="thirdUtil" params="[num: 42]" >click</g:link>'
+ assertOutputEquals '<a href="/pluginThreeFirstController?num=42">click</a>', template
+
+ template = '<g:createLink controller="first" action="index" plugin="firstUtil" />'
+ assertOutputEquals '/pluginOneFirstController', template
+
+ template = '<g:createLink controller="first" action="index" plugin="secondUtil" />'
+ assertOutputEquals '/pluginTwoFirstController', template
+
+ template = '<g:createLink controller="first" action="index" plugin="thirdUtil" />'
+ assertOutputEquals '/pluginThreeFirstController', template
+
+ template = '<g:createLink controller="first" action="index" plugin="firstUtil" params="[num: 42]" />'
+ assertOutputEquals '/pluginOneFirstController?num=42', template
+
+ template = '<g:createLink controller="first" action="index" plugin="secondUtil" params="[num: 42]" />'
+ assertOutputEquals '/pluginTwoFirstController/42', template
+
+ template = '<g:createLink controller="first" action="index" plugin="thirdUtil" params="[num: 42]" />'
+ assertOutputEquals '/pluginThreeFirstController?num=42', template
+ }
+
void testLinkTagWithAttributeValueContainingEqualSignFollowedByQuote() {
// Some of these tests look peculiar but they relate to
// scenarios that were broken before GRAILS-7229 was addressed
View
8 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/AbstractUrlMapping.java
@@ -33,6 +33,7 @@
protected final ConstrainedProperty[] constraints;
protected Object controllerName;
protected Object actionName;
+ protected Object pluginName;
protected Object viewName;
protected Object forwardURI;
protected ServletContext servletContext;
@@ -50,9 +51,10 @@
* @param constraints Any constraints that apply to the mapping
* @param servletContext
*/
- public AbstractUrlMapping(Object controllerName, Object actionName, Object viewName, ConstrainedProperty[] constraints, ServletContext servletContext) {
+ public AbstractUrlMapping(Object controllerName, Object actionName, Object pluginName, Object viewName, ConstrainedProperty[] constraints, ServletContext servletContext) {
this.controllerName = controllerName;
this.actionName = actionName;
+ this.pluginName = pluginName;
this.constraints = constraints;
this.viewName = viewName;
this.servletContext = servletContext;
@@ -91,6 +93,10 @@ public Object getActionName() {
return actionName;
}
+ public Object getPluginName() {
+ return pluginName;
+ }
+
/**
* @see org.codehaus.groovy.grails.web.mapping.UrlMapping#getViewName()
*
View
7 ...ls-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultLinkGenerator.groovy
@@ -120,12 +120,13 @@ class DefaultLinkGenerator implements LinkGenerator, PluginManagerAware{
if (id != null) {
params.put(ATTRIBUTE_ID, id)
}
- UrlCreator mapping = urlMappingsHolder.getReverseMappingNoDefault(controller,action,params)
+ def pluginName = attrs.get('plugin')
+ UrlCreator mapping = urlMappingsHolder.getReverseMappingNoDefault(controller,action,pluginName,params)
if (mapping == null && isDefaultAction) {
- mapping = urlMappingsHolder.getReverseMappingNoDefault(controller,null,params)
+ mapping = urlMappingsHolder.getReverseMappingNoDefault(controller,null,pluginName,params)
}
if (mapping == null) {
- mapping = urlMappingsHolder.getReverseMapping(controller,action,params)
+ mapping = urlMappingsHolder.getReverseMapping(controller,action,pluginName,params)
}
boolean absolute = false
View
2 ...s-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/ForwardUrlMappingInfo.groovy
@@ -26,6 +26,7 @@ class ForwardUrlMappingInfo extends AbstractUrlMappingInfo {
String controllerName
String actionName
+ String pluginName
String viewName
String URI
String id
@@ -33,6 +34,7 @@ class ForwardUrlMappingInfo extends AbstractUrlMappingInfo {
void setController(String controller) { controllerName = controller }
void setAction(String action) { actionName = action }
+ void setPluginName(String plugin) { pluginName = plugin }
void setView(String view) { viewName = view }
void setParams(Map params) {
if (params) {
View
50 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlCreator.java
@@ -60,6 +60,18 @@
String createURL(String controller, String action, Map parameterValues, String encoding);
/**
+ * Creates a URL for the given parameters values, controller and action names
+ *
+ * @param controller The controller name
+ * @param action The action name
+ * @param pluginName The name of the plugin which provides the controller
+ * @param parameterValues The parameter values
+ * @param encoding The encoding to use for parameters
+ * @return The created URL for the given arguments
+ */
+ String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding);
+
+ /**
* Creates a URL for the given parameters values, controller and action names without the context path information
*
* @param controller The controller name
@@ -69,6 +81,18 @@
* @return The created URL for the given arguments
*/
String createRelativeURL(String controller, String action, Map parameterValues, String encoding);
+
+ /**
+ * Creates a URL for the given parameters values, controller and action names without the context path information
+ *
+ * @param controller The controller name
+ * @param action The action name
+ * @param pluginName The name of the plugin which provides the controller
+ * @param parameterValues The parameter values
+ * @param encoding The encoding to use for parameters
+ * @return The created URL for the given arguments
+ */
+ String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding);
/**
* Creates a URL for the given parameters values, controller and action names without the context path information
@@ -83,6 +107,19 @@
String createRelativeURL(String controller, String action, Map parameterValues, String encoding, String fragment);
/**
+ * Creates a URL for the given parameters values, controller and action names without the context path information
+ *
+ * @param controller The controller name
+ * @param action The action name
+ * @param pluginName The name of the plugin which provides the controller
+ * @param parameterValues The parameter values
+ * @param encoding The encoding to use for parameters
+ * @param fragment The fragment to append to the end
+ * @return The created URL for the given arguments
+ */
+ String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment);
+
+ /**
* Creates a URL for the given parameters values, controller and action names
*
* @param controller The controller name
@@ -93,4 +130,17 @@
* @return The created URL for the given arguments
*/
String createURL(String controller, String action, Map parameterValues, String encoding, String fragment);
+
+ /**
+ * Creates a URL for the given parameters values, controller and action names
+ *
+ * @param controller The controller name
+ * @param action The action name
+ * @param pluginName The name of the plugin which provides the controller
+ * @param parameterValues The parameter values
+ * @param encoding The encoding to use for parameters
+ * @param fragment The URL fragment to be appended to the URL following a #
+ * @return The created URL for the given arguments
+ */
+ String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment);
}
View
59 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlCreatorCache.java
@@ -43,8 +43,8 @@ public void clear() {
cacheMap.clear();
}
- public ReverseMappingKey createKey(String controller, String action, Map params) {
- return new ReverseMappingKey(controller, action, params);
+ public ReverseMappingKey createKey(String controller, String action, String pluginName, Map params) {
+ return new ReverseMappingKey(controller, action, pluginName, params);
}
public UrlCreator lookup(ReverseMappingKey key) {
@@ -76,40 +76,57 @@ public int weight() {
public String createRelativeURL(String controller, String action, Map parameterValues,
String encoding, String fragment) {
- UrlCreatorKey key = new UrlCreatorKey(controller, action, parameterValues, encoding, fragment, 0);
+ return createRelativeURL(controller, action, null, parameterValues, encoding, fragment);
+ }
+
+ public String createRelativeURL(String controller, String action, String pluginName, Map parameterValues,
+ String encoding, String fragment) {
+ UrlCreatorKey key = new UrlCreatorKey(controller, action, pluginName, parameterValues, encoding, fragment, 0);
String url = cache.get(key);
if (url == null) {
- url = delegate.createRelativeURL(controller, action, parameterValues, encoding, fragment);
+ url = delegate.createRelativeURL(controller, action, pluginName, parameterValues, encoding, fragment);
cache.put(key, url);
}
return url;
}
public String createRelativeURL(String controller, String action, Map parameterValues, String encoding) {
- UrlCreatorKey key = new UrlCreatorKey(controller, action, parameterValues, encoding, null, 0);
+ return createRelativeURL(controller, action, null, parameterValues, encoding);
+ }
+
+ public String createRelativeURL(String controller, String action, String pluginName, Map parameterValues, String encoding) {
+ UrlCreatorKey key = new UrlCreatorKey(controller, action, pluginName, parameterValues, encoding, null, 0);
String url = cache.get(key);
if (url == null) {
- url = delegate.createRelativeURL(controller, action, parameterValues, encoding);
+ url = delegate.createRelativeURL(controller, action, pluginName, parameterValues, encoding);
cache.put(key, url);
}
return url;
}
public String createURL(String controller, String action, Map parameterValues, String encoding, String fragment) {
- UrlCreatorKey key = new UrlCreatorKey(controller, action, parameterValues, encoding, fragment, 1);
+ return createURL(controller, action, null, parameterValues, encoding, fragment);
+ }
+
+ public String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding, String fragment) {
+ UrlCreatorKey key = new UrlCreatorKey(controller, action, pluginName, parameterValues, encoding, fragment, 1);
String url = cache.get(key);
if (url == null) {
- url = delegate.createURL(controller, action, parameterValues, encoding, fragment);
+ url = delegate.createURL(controller, action, pluginName, parameterValues, encoding, fragment);
cache.put(key, url);
}
return url;
}
public String createURL(String controller, String action, Map parameterValues, String encoding) {
- UrlCreatorKey key = new UrlCreatorKey(controller, action, parameterValues, encoding, null, 1);
+ return createURL(controller, action, null, parameterValues, encoding);
+ }
+
+ public String createURL(String controller, String action, String pluginName, Map parameterValues, String encoding) {
+ UrlCreatorKey key = new UrlCreatorKey(controller, action, pluginName, parameterValues, encoding, null, 1);
String url = cache.get(key);
if (url == null) {
- url = delegate.createURL(controller, action, parameterValues, encoding);
+ url = delegate.createURL(controller, action, pluginName, parameterValues, encoding);
cache.put(key, url);
}
return url;
@@ -129,12 +146,14 @@ public String createURL(Map parameterValues, String encoding) {
public static class ReverseMappingKey {
protected final String controller;
protected final String action;
+ protected final String pluginName;
protected final String[] paramKeys;
protected final String[] paramValues;
- public ReverseMappingKey(String controller, String action, Map<Object, Object> params) {
+ public ReverseMappingKey(String controller, String action, String pluginName, Map<Object, Object> params) {
this.controller = controller;
this.action = action;
+ this.pluginName = pluginName;
if (params != null) {
paramKeys = new String[params.size()];
paramValues = new String[params.size()];
@@ -168,6 +187,7 @@ public int weight() {
int weight = 0;
weight += (controller != null) ? controller.length() : 0;
weight += (action != null) ? action.length() : 0;
+ weight += (pluginName != null) ? pluginName.length() : 0;
for (int i = 0; i < paramKeys.length; i++) {
weight += (paramKeys[i] != null) ? paramKeys[i].length() : 0;
}
@@ -182,6 +202,7 @@ public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((action == null) ? 0 : action.hashCode());
+ result = prime * result + ((pluginName == null) ? 0 : pluginName.hashCode());
result = prime * result + ((controller == null) ? 0 : controller.hashCode());
result = prime * result + Arrays.hashCode(paramKeys);
result = prime * result + Arrays.hashCode(paramValues);
@@ -216,6 +237,14 @@ else if (!action.equals(other.action)) {
else if (!controller.equals(other.controller)) {
return false;
}
+ if (pluginName == null) {
+ if (other.pluginName != null) {
+ return false;
+ }
+ }
+ else if (!pluginName.equals(other.pluginName)) {
+ return false;
+ }
if (!Arrays.equals(paramKeys, other.paramKeys)) {
return false;
}
@@ -227,7 +256,7 @@ else if (!controller.equals(other.controller)) {
@Override
public String toString() {
- return "UrlCreatorCache.ReverseMappingKey [action=" + action + ", controller=" + controller +
+ return "UrlCreatorCache.ReverseMappingKey [action=" + action + ", controller=" + controller + ", plugin=" + pluginName +
", paramKeys=" + Arrays.toString(paramKeys) + ", paramValues=" +
Arrays.toString(paramValues) + "]";
}
@@ -238,9 +267,9 @@ public String toString() {
protected final String fragment;
protected final int urlType;
- public UrlCreatorKey(String controller, String action, Map<Object, Object> params, String encoding,
+ public UrlCreatorKey(String controller, String action, String pluginName, Map<Object, Object> params, String encoding,
String fragment, int urlType) {
- super(controller, action, params);
+ super(controller, action, pluginName, params);
this.encoding = (encoding != null) ? encoding.toLowerCase() : null;
this.fragment = fragment;
this.urlType = urlType;
@@ -293,7 +322,7 @@ else if (!fragment.equals(other.fragment)) {
@Override
public String toString() {
return "UrlCreatorCache.UrlCreatorKey [encoding=" + encoding + ", fragment=" + fragment +
- ", urlType=" + urlType + ", action=" + action + ", controller=" + controller +
+ ", urlType=" + urlType + ", action=" + action + ", controller=" + controller + ", plugin=" + pluginName +
", paramKeys=" + Arrays.toString(paramKeys) + ", paramValues=" +
Arrays.toString(paramValues) + "]";
}
View
2 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMapping.java
@@ -83,6 +83,8 @@
* @return The action name as a {@link groovy.lang.Closure} or {@link java.lang.String}
*/
Object getActionName();
+
+ Object getPluginName();
/**
* Returns the name of the view to map to
View
2 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappingInfo.java
@@ -50,6 +50,8 @@
* @return The name of the action or null if not known
*/
String getActionName();
+
+ String getPluginName();
/**
* The name of the view that the URL mappping maps to
View
4 grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappingsHolder.java
@@ -53,7 +53,7 @@
* @return A URI for the given arguments
*/
@SuppressWarnings("rawtypes")
- UrlCreator getReverseMapping(String controller, String action, Map params);
+ UrlCreator getReverseMapping(String controller, String action, String pluginName, Map params);
/**
* Retrieves the best guess of a URI for the given controller, action and parameters or null if non could be found.
@@ -64,7 +64,7 @@
* @return A URI for the given arguments
*/
@SuppressWarnings("rawtypes")
- UrlCreator getReverseMappingNoDefault(String controller, String action, Map params);
+ UrlCreator getReverseMappingNoDefault(String controller, String action, String pluginName, Map params);
/**
* Match and return the first UrlMappingInfo instance possible
View
1 ...b/src/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsApplicationAttributes.java
@@ -57,6 +57,7 @@
String REQUEST_REDIRECTED_ATTRIBUTE = "org.codehaus.groovy.grails.request_redirected";
String ACTION_NAME_ATTRIBUTE = "org.codehaus.groovy.grails.ACTION_NAME_ATTRIBUTE";
String CONTROLLER_NAME_ATTRIBUTE = "org.codehaus.groovy.grails.CONTROLLER_NAME_ATTRIBUTE";
+ String CONTROLLER_ATTRIBUTE = "org.codehaus.groovy.grails.CONTROLLER_ATTRIBUTE";
String APP_URI_ATTRIBUTE = "org.codehaus.groovy.grails.APP_URI_ATTRIBUTE";
String RENDERING_ERROR_ATTRIBUTE = "org.codehaus.groovy.grails.RENDERING_ERROR_ATTRIBUTE";
String REDIRECT_ISSUED = "org.codehaus.groovy.grails.REDIRECT_ISSUED";
View
16 ...rc/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsControllerHandlerMapping.java
@@ -24,8 +24,10 @@
import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.codehaus.groovy.grails.commons.GrailsControllerClass;
import org.codehaus.groovy.grails.plugins.support.aware.GrailsApplicationAware;
+import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;
@@ -53,8 +55,18 @@ protected Object getHandlerInternal(HttpServletRequest request) throws Exception
if (logger.isDebugEnabled()) {
logger.debug("Looking up Grails controller for URI ["+uri+"]");
}
- GrailsControllerClass controllerClass = (GrailsControllerClass) grailsApplication.getArtefactForFeature(
- ControllerArtefactHandler.TYPE, uri);
+ GrailsControllerClass controllerClass;
+ Object controllerAttribute = null;
+ GrailsWebRequest webRequest = (GrailsWebRequest)request.getAttribute(GrailsApplicationAttributes.WEB_REQUEST);
+ if(webRequest != null) {
+ controllerAttribute = webRequest.getAttribute(GrailsApplicationAttributes.CONTROLLER_ATTRIBUTE, WebRequest.SCOPE_REQUEST);
+ }
+ if(controllerAttribute instanceof GrailsControllerClass) {
+ controllerClass = (GrailsControllerClass) controllerAttribute;
+ } else {
+ controllerClass = (GrailsControllerClass) grailsApplication.getArtefactForFeature(
+ ControllerArtefactHandler.TYPE, uri);
+ }
return getHandlerForControllerClass(controllerClass, request);
}
View
9 ...ain/groovy/org/codehaus/groovy/grails/web/servlet/mvc/AbstractGrailsControllerHelper.java
@@ -51,6 +51,7 @@
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;
+import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
/**
@@ -132,7 +133,13 @@ public ModelAndView handleURI(String uri, GrailsWebRequest grailsWebRequest, Map
}
// Step 2: lookup the controller in the application.
- GrailsControllerClass controllerClass = getControllerClassByURI(uri);
+ GrailsControllerClass controllerClass;
+ Object attribute = grailsWebRequest.getAttribute(GrailsApplicationAttributes.CONTROLLER_ATTRIBUTE, WebRequest.SCOPE_REQUEST);
+ if(attribute instanceof GrailsControllerClass) {
+ controllerClass = (GrailsControllerClass) attribute;
+ } else {
+ controllerClass = getControllerClassByURI(uri);
+ }
if (controllerClass == null) {
throw new UnknownControllerException("No controller found for URI [" + uri + "]!");
View
5 ...ain/groovy/org/codehaus/groovy/grails/webflow/engine/builder/RuntimeRedirectAction.groovy
@@ -33,6 +33,7 @@ class RuntimeRedirectAction extends AbstractAction {
def controller
def action
+ def plugin
Map params
UrlMappingsHolder urlMapper
@@ -63,8 +64,8 @@ class RuntimeRedirectAction extends AbstractAction {
Map params = params.clone()
resolveExpressionsInParams(delegate, params)
- UrlCreator creator = urlMapper.getReverseMapping(controller, action, params)
- def url = creator.createRelativeURL(controller, action, params, 'utf-8')
+ UrlCreator creator = urlMapper.getReverseMapping(controller, action, plugin, params)
+ def url = creator.createRelativeURL(controller, action, plugin, params, 'utf-8')
context.getExternalContext().requestExternalRedirect("contextRelative:$url")
return success()

0 comments on commit 9da894e

Please sign in to comment.
Something went wrong with that request. Please try again.