diff --git a/.github/workflows/groovy-joint-workflow.yml b/.github/workflows/groovy-joint-workflow.yml index e03c284817d..bfc1558d516 100644 --- a/.github/workflows/groovy-joint-workflow.yml +++ b/.github/workflows/groovy-joint-workflow.yml @@ -38,7 +38,7 @@ jobs: groovyVersion: ${{ steps.groovy-version.outputs.value }} steps: - name: Set up JDK - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4 + uses: actions/setup-java@v4 with: distribution: 'adopt' java-version: '11.0.6' @@ -52,11 +52,8 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: Checkout Groovy 3_0_X (Grails 5 and later) + if: startsWith('refs/head/6.', github.ref) || startsWith('6.', github.base_ref) || startsWith('refs/head/5.', github.ref) || startsWith('5.', github.base_ref) run: cd .. && git clone --depth 1 https://github.com/apache/groovy.git -b GROOVY_3_0_X --single-branch - if: github.ref == 'refs/heads/6.2.x' || github.base_ref == '6.2.x' || github.ref == 'refs/heads/6.1.x' || github.base_ref == '6.1.x' || github.ref == 'refs/heads/6.0.x' || github.base_ref == '6.0.x' || github.ref == 'refs/heads/5.3.x' || github.base_ref == '5.3.x' || github.ref == 'refs/heads/5.2.x' || github.base_ref == '5.2.x' || github.ref == 'refs/heads/5.1.x' || github.base_ref == '5.1.x' || github.ref == 'refs/heads/5.0.x' || github.base_ref == '5.0.x' || github.ref == 'refs/heads/master' || github.base_ref == 'master' - - name: Checkout Groovy 2_5_X (Grails 4.0.x) - run: cd .. && git clone --depth 1 https://github.com/grails/grails-core.git -b GROOVY_2_5_X --single-branch - if: github.ref == 'refs/heads/4.1.x' || github.base_ref == '4.1.x' || github.ref == 'refs/heads/4.0.x' || github.base_ref == '4.0.x' - name: Set CI_GROOVY_VERSION for Grails id: groovy-version run: | @@ -130,7 +127,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4 + uses: actions/setup-java@v4 with: distribution: 'adopt' java-version: '11' diff --git a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluator.java b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluator.java index 146f67b2dd5..b592ba2cda0 100644 --- a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluator.java +++ b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluator.java @@ -1130,7 +1130,9 @@ private UrlMapping getURLMappingForNamedArgs(Map namedArguments, UrlMapping urlMapping; if (uri != null) { try { - urlMapping = new RegexUrlMapping(urlData, new URI(uri.toString()), constraints, grailsApplication); + urlMapping = isResponseCode ? + new ResponseCodeUrlMapping(urlData, new URI(uri.toString()), constraints, grailsApplication) : + new RegexUrlMapping(urlData, new URI(uri.toString()), constraints, grailsApplication); } catch (URISyntaxException e) { throw new UrlMappingException("Cannot map to invalid URI: " + e.getMessage(), e); } diff --git a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/ResponseCodeUrlMapping.java b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/ResponseCodeUrlMapping.java index 35fb7e3eb3b..faef3361f28 100644 --- a/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/ResponseCodeUrlMapping.java +++ b/grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/ResponseCodeUrlMapping.java @@ -19,6 +19,7 @@ import grails.gorm.validation.ConstrainedProperty; import grails.web.mapping.UrlMappingData; import grails.web.mapping.UrlMappingInfo; +import java.net.URI; import org.springframework.util.Assert; import java.util.Collections; @@ -46,6 +47,14 @@ public ResponseCodeUrlMapping(UrlMappingData urlData, Object controllerName, Obj "Constraints can't be used for response code url mapping"); } + public ResponseCodeUrlMapping(UrlMappingData urlData, URI uri, ConstrainedProperty[] constraints, GrailsApplication grailsApplication) { + super(uri, constraints, grailsApplication); + this.urlData = (ResponseCodeMappingData) urlData; + + Assert.isTrue(constraints == null || constraints.length == 0, + "Constraints can't be used for response code url mapping"); + } + public UrlMappingInfo match(String uri) { return null; } diff --git a/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluatorSpec.groovy b/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluatorSpec.groovy new file mode 100644 index 00000000000..60bbf601e44 --- /dev/null +++ b/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/DefaultUrlMappingEvaluatorSpec.groovy @@ -0,0 +1,33 @@ +package org.grails.web.mapping + +import grails.web.mapping.UrlMapping +import spock.lang.Specification + +class DefaultUrlMappingEvaluatorSpec extends Specification { + + void "test evaluate mapping: #logicalUrls to view: #viewName, controller: #controllerName, action: #actionName, uri: #forwardURI as #clazz.simpleName"() { + given: + DefaultUrlMappingEvaluator defaultUrlMappingEvaluator = new DefaultUrlMappingEvaluator(null) + + when: + List mappings = defaultUrlMappingEvaluator.evaluateMappings closure + + then: + mappings.size() == 1 + mappings[0].urlData.logicalUrls == logicalUrls + mappings[0].class == clazz + mappings[0].viewName == viewName + mappings[0].controllerName == controllerName + mappings[0].actionName == actionName + mappings[0].forwardURI == forwardURI + + where: + closure | logicalUrls | viewName | controllerName | actionName | forwardURI | clazz + ({ '/lorem/ipsum'(view: '/foobar') }) | ['/lorem/ipsum'] | '/foobar' | null | null | null | RegexUrlMapping.class + ({ '/lorem/ipsum'(controller: 'foo', action: 'bar') }) | ['/lorem/ipsum'] | null | 'foo' | 'bar' | null | RegexUrlMapping.class + ({ '/lorem/ipsum'(uri: '/foo/bar') }) | ['/lorem/ipsum'] | null | null | null | new URI('/foo/bar') | RegexUrlMapping.class + ({ '404'(view: '/foobar') }) | ['404'] | '/foobar' | null | null | null | ResponseCodeUrlMapping.class + ({ '404'(controller: 'foo', action: 'bar') }) | ['404'] | null | 'foo' | 'bar' | null | ResponseCodeUrlMapping.class + ({ '404'(uri: '/foo/bar') }) | ['404'] | null | null | null | new URI('/foo/bar') | ResponseCodeUrlMapping.class + } +}