Skip to content

Commit

Permalink
Merge pull request #13628 from codeconsole/6.2.x-resource-controller-…
Browse files Browse the repository at this point in the history
…link

Support controller attribute in tags with resource attribute and resolve correct identity Fixes #13627
  • Loading branch information
codeconsole authored Sep 10, 2024
2 parents da8668d + bf6a0c3 commit 8871703
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011 SpringSource
* Copyright 2011-2024 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.
Expand Down Expand Up @@ -189,7 +189,7 @@ class DefaultLinkGenerator implements LinkGenerator, PluginManagerAware {
}
}
List tokens = resource.contains('/') ? resource.tokenize('/') :[resource]
controller = tokens[-1]
controller = controllerAttribute?:tokens[-1]
if (tokens.size()>1) {
for(t in tokens[0..-2]) {
final key = "${t}Id".toString()
Expand Down Expand Up @@ -291,6 +291,20 @@ class DefaultLinkGenerator implements LinkGenerator, PluginManagerAware {

@CompileStatic(TypeCheckingMode.SKIP)
protected String getResourceId(resourceAttribute) {
try {
// Three options for using indent():
// 1. Check instanceof GormEntity, but that would require coupling web-common to grails-datastore-gorm
// 2. GrailsMetaClassUtils.invokeMethodIfExists(o, "ident", new Object[0]); Slow?
// 3. Just assuming resource is a GormEntity or has ident() implemented and catching an exception if it is not.
def ident = resourceAttribute.ident()
if (ident) {
return ident.toString()
}
} catch (MissingMethodException | IllegalStateException ignored) {
// An IllegalStateException occurs if GORM is not initialized.
// A MissingMethodException if it is not a GormEntity
}

final id = resourceAttribute.id
if (id) {
return id.toString()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.grails.web.mapping

import grails.artefact.Artefact
import grails.core.DefaultGrailsApplication
import grails.plugins.DefaultGrailsPluginManager
import grails.util.GrailsWebMockUtil
Expand Down Expand Up @@ -289,6 +290,29 @@ class LinkGeneratorSpec extends Specification {
cacheKey == "somePrefix[resource:org.grails.web.mapping.Widget->2]"
}

@Issue('https://github.com/grails/grails-core/issues/13627')
def 'resource links should use ident and allow controller override'() {
given:
final webRequest = GrailsWebMockUtil.bindMockWebRequest()
MockHttpServletRequest request = webRequest.currentRequest
linkParams.method = 'GET'

when: 'a resource is specified, ident() is used for id'
linkParams.resource = new Widget(id: 1, name: 'Some Widget')

then:
link == "/bar/widget/show/1"

then:
linkParams.resource.identCalled

when: "A controller is specified"
linkParams.controller = 'widgetAdmin'

then:
link == "/bar/widgetAdmin/show/1"
}

def 'link should take into affect namespace'() {
given:
final webRequest = GrailsWebMockUtil.bindMockWebRequest()
Expand Down Expand Up @@ -341,7 +365,8 @@ class LinkGeneratorSpec extends Specification {
def generator = cache ? new CachingLinkGenerator(baseUrl, context) : new DefaultLinkGenerator(baseUrl, context)
final callable = { String controller, String action, String namespace, String pluginName, String httpMethod, Map params ->
[createRelativeURL: { String c, String a, String n, String p, Map parameterValues, String encoding, String fragment ->
"${namespace ? '/' + namespace : ''}/$controller/$action".toString()

"${namespace ? '/' + namespace : ''}/$controller/$action${parameterValues.id? '/'+parameterValues.id:''}".toString()
}] as UrlCreator
}
generator.grailsUrlConverter = new CamelCaseUrlConverter()
Expand Down Expand Up @@ -381,11 +406,14 @@ class LinkGeneratorSpec extends Specification {
}
}

@Artefact('Domain')
class Widget {
Long id
String name
boolean identCalled = false

Long ident() {
identCalled = true
id
}

Expand Down

0 comments on commit 8871703

Please sign in to comment.