From 87cb7f7f1cbf3b8b0acdb51455dde3555fe76189 Mon Sep 17 00:00:00 2001 From: Puneet Behl Date: Thu, 18 Jan 2024 19:01:02 +0530 Subject: [PATCH 1/5] Update to 7.0.0-SNAPSHOT --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1dab75eb724..bb0e8f3bcaf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -projectVersion=6.2.0-SNAPSHOT +projectVersion=7.0.0-SNAPSHOT antVersion=1.10.14 aspectjVersion=1.9.21 asyncVersion=5.0.2 From a9eafe654a3fa0f6b25e0a5f62ca32ded74bb7be Mon Sep 17 00:00:00 2001 From: Mattias Reichel Date: Tue, 6 Feb 2024 09:03:17 +0100 Subject: [PATCH 2/5] feat: Update Java version to 17 (#13352) * feat: Update Java version to 17 BREAKING CHANGE: Requires Java 17 as a minimum version * chore(build): Update Github workflows to Java 17 * chore(build): Remove Java 21 from build workflow * Update groovy-joint-workflow.yml * ci: Build Grails with Java 17 in joint workflow * chore(build): Refactor jvmArgs for tests Make it more clear why these arguments are added by extracting them to a variable with a descriptive name. --------- Co-authored-by: Puneet Behl --- .github/workflows/gradle.yml | 6 ++--- .github/workflows/groovy-joint-workflow.yml | 4 ++-- .github/workflows/release.yml | 2 +- .github/workflows/retry-release.yml | 2 +- build.gradle | 22 ++++++++++++------- .../groovy/grails/util/GrailsUtilTests.java | 2 +- 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8e00dbf3fdc..5c68d7367da 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['11', '14'] + java: ['17'] env: WORKSPACE: ${{ github.workspace }} steps: @@ -47,11 +47,11 @@ jobs: uses: actions/checkout@v4 with: token: ${{ secrets.GH_TOKEN }} - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4 with: distribution: 'adopt' - java-version: 11 + java-version: 17 - name: Publish Artifacts (repo.grails.org) id: publish uses: gradle/gradle-build-action@v2 diff --git a/.github/workflows/groovy-joint-workflow.yml b/.github/workflows/groovy-joint-workflow.yml index 0335733a6ad..c95952fc259 100644 --- a/.github/workflows/groovy-joint-workflow.yml +++ b/.github/workflows/groovy-joint-workflow.yml @@ -50,7 +50,7 @@ jobs: ~/.m2/repository key: cache-local-groovy-maven-${{ github.sha }} - name: Checkout Groovy 3_0_X (Grails 5 and later) - if: startsWith(github.ref, 'refs/heads/6.') || startsWith(github.base_ref, '6.') || startsWith(github.ref, 'refs/heads/5.') || startsWith(github.base_ref, '5.') + if: startsWith(github.ref, 'refs/heads/7.') || startsWith(github.base_ref, '7.') || startsWith(github.ref, 'refs/heads/6.') || startsWith(github.base_ref, '6.') || startsWith(github.ref, 'refs/heads/5.') || startsWith(github.base_ref, '5.') run: cd .. && git clone --depth 1 https://github.com/apache/groovy.git -b GROOVY_3_0_X --single-branch - name: Set CI_GROOVY_VERSION for Grails id: groovy-version @@ -128,7 +128,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Cache local Maven repository & Groovy uses: actions/cache@v3 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fbc09ee89a0..c8b0eae3a36 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-java@v4 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Extract Target Branch id: extract_branch run: | diff --git a/.github/workflows/retry-release.yml b/.github/workflows/retry-release.yml index 897bcba6a68..815437b304c 100644 --- a/.github/workflows/retry-release.yml +++ b/.github/workflows/retry-release.yml @@ -29,7 +29,7 @@ jobs: uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4 with: distribution: 'adopt' - java-version: 11 + java-version: 17 - name: Extract Target Branch id: extract_branch run: | diff --git a/build.gradle b/build.gradle index 955c78fc039..dff43817e87 100644 --- a/build.gradle +++ b/build.gradle @@ -444,8 +444,8 @@ subprojects { project -> if(project.name == 'grails-dependencies') return if(project.name == 'grails-bom') return - sourceCompatibility = "1.11" - targetCompatibility = "1.11" + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 if(project.name =~ /^(grails-web|grails-plugin-|grails-test-suite|grails-test)/) { dependencies { @@ -533,11 +533,17 @@ subprojects { project -> } } - def debugArguments = ['-Xmx2g', '-Xdebug', '-Xnoagent', '-Djava.compiler=NONE', - '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005'] - - tasks.withType(Test) { + def debugArguments = [ + '-Xmx2g', '-Xdebug', '-Xnoagent', '-Djava.compiler=NONE', + '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005' + ] + def java17moduleReflectionCompatibilityArguments = [ + '--add-opens=java.base/java.lang=ALL-UNNAMED', + '--add-opens=java.base/java.util=ALL-UNNAMED' + ] + tasks.withType(Test).configureEach { useJUnitPlatform() + jvmArgs += java17moduleReflectionCompatibilityArguments } test { @@ -566,14 +572,14 @@ subprojects { project -> maxHeapSize = '1024m' } if(System.getProperty("debug.tests")) { - jvmArgs debugArguments + jvmArgs += debugArguments } } task singleTest(type: Test) { // task for running a single test with -DsingleTest.single=TestName singleTest if(System.getProperty("debug.tests")) { - jvmArgs debugArguments + jvmArgs += debugArguments } } diff --git a/grails-core/src/test/groovy/grails/util/GrailsUtilTests.java b/grails-core/src/test/groovy/grails/util/GrailsUtilTests.java index b46538cc662..9aa06c7dc04 100644 --- a/grails-core/src/test/groovy/grails/util/GrailsUtilTests.java +++ b/grails-core/src/test/groovy/grails/util/GrailsUtilTests.java @@ -29,7 +29,7 @@ public class GrailsUtilTests { @Test public void testGrailsVersion() { - assertEquals("6.2.0-SNAPSHOT", GrailsUtil.getGrailsVersion()); + assertEquals("7.0.0-SNAPSHOT", GrailsUtil.getGrailsVersion()); } @AfterEach From 53dbde3ef0a0794e9f6234192cd4a2e9dcaa8eea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:40:41 +0530 Subject: [PATCH 3/5] fix(deps): update dependency com.github.ben-manes.caffeine:caffeine to v3 (#13373) * Update actions/cache action to v4 (#13367) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update gspVersion to v6.1.3 (#13365) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency org.jsoup:jsoup to v1.17.2 (#13363) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency org.asciidoctor:asciidoctorj to v2.5.11 (#13361) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update grails-testing-support monorepo to v3.1.2 (#13364) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update datastoreVersion to v8.0.4 (#13360) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update plugin com.gradle.enterprise to v3.16.2 (#13366) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update apache-tomcat monorepo to v9.0.85 (#13359) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency org.grails:grails-datastore-gorm-hibernate5 to v8.0.3 (#13362) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix: Groovy 3.0.20 compatibility (#13371) * fix(deps): update dependency com.github.ben-manes.caffeine:caffeine to v3 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Mattias Reichel --- .github/workflows/groovy-joint-workflow.yml | 4 ++-- gradle.properties | 8 ++++---- .../src/main/groovy/org/grails/cli/GrailsCli.groovy | 3 ++- .../groovy/org/grails/cli/profile/AbstractProfile.groovy | 4 ++-- grails-test-suite-persistence/build.gradle | 2 +- grails-test-suite-uber/build.gradle | 2 +- grails-test-suite-web/build.gradle | 2 +- .../converters/AbstractStructuredBindingEditor.groovy | 2 +- settings.gradle | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/groovy-joint-workflow.yml b/.github/workflows/groovy-joint-workflow.yml index c95952fc259..78818282aea 100644 --- a/.github/workflows/groovy-joint-workflow.yml +++ b/.github/workflows/groovy-joint-workflow.yml @@ -43,7 +43,7 @@ jobs: distribution: 'adopt' java-version: '11.0.6' - name: Cache local Maven repository & Groovy - uses: actions/cache@v3 + uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4 with: path: | ~/groovy @@ -130,7 +130,7 @@ jobs: distribution: 'adopt' java-version: '17' - name: Cache local Maven repository & Groovy - uses: actions/cache@v3 + uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4 with: path: | ~/groovy diff --git a/gradle.properties b/gradle.properties index bb0e8f3bcaf..579c62a6576 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,16 +2,16 @@ projectVersion=7.0.0-SNAPSHOT antVersion=1.10.14 aspectjVersion=1.9.21 asyncVersion=5.0.2 -caffeineVersion=2.9.3 +caffeineVersion=3.1.8 cglibVersion=2.2.2 commonsLangVersion=2.6 -datastoreVersion=8.0.3 +datastoreVersion=8.0.4 directoryWatcherVersion=0.9.9 gdocEngineVersion=1.0.1 gradleNexusPluginVersion=2.3.1 gradleNexusStagingPluginVersion=0.12.0 groovyVersion=3.0.11 -gspVersion=6.1.2 +gspVersion=6.1.3 h2.version=2.2.224 h2Version=2.2.224 hibernateDatastoreVersion=8.0.2 @@ -43,7 +43,7 @@ springLoadedVersion=1.2.8.RELEASE springVersion=5.3.31 spring.version=5.3.30 testingSupportVersion=3.1.1 -testingSupportVersionForTests=3.1.1 +testingSupportVersionForTests=3.1.2 tomcatLog4jVersion=8.5.2 tomcatVersion=9.0.85 viewsVersion=3.1.1 diff --git a/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy b/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy index 62df78c0740..dfa9874ab2a 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/GrailsCli.groovy @@ -27,6 +27,7 @@ import groovy.transform.CompileStatic import jline.UnixTerminal import jline.console.UserInterruptException import jline.console.completer.ArgumentCompleter +import jline.console.completer.Completer import jline.internal.NonBlockingInputStream import org.gradle.tooling.BuildActionExecuter import org.gradle.tooling.BuildCancelledException @@ -417,7 +418,7 @@ class GrailsCli { new RegexCompletor("!\\w+"), new EscapingFileNameCompletor()) ) - completers.addAll((profile.getCompleters(projectContext) ?: []) as Collection) + completers.addAll((profile.getCompleters(projectContext) ?: []) as Collection) consoleReader.addCompleter(aggregateCompleter) return console } diff --git a/grails-shell/src/main/groovy/org/grails/cli/profile/AbstractProfile.groovy b/grails-shell/src/main/groovy/org/grails/cli/profile/AbstractProfile.groovy index 20fbd13a23d..0644bbf6f0b 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/profile/AbstractProfile.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/profile/AbstractProfile.groovy @@ -166,8 +166,8 @@ abstract class AbstractProfile implements Profile { } } - defaultFeaturesNames.addAll(defaultFeatures) - requiredFeatureNames.addAll(requiredFeatures) + defaultFeaturesNames.addAll(defaultFeatures as Set) + requiredFeatureNames.addAll(requiredFeatures as Set) } diff --git a/grails-test-suite-persistence/build.gradle b/grails-test-suite-persistence/build.gradle index cf2988e9b14..612cea70650 100644 --- a/grails-test-suite-persistence/build.gradle +++ b/grails-test-suite-persistence/build.gradle @@ -16,7 +16,7 @@ dependencies { project(':grails-spring') testImplementation "org.grails:grails-datastore-gorm-validation:$datastoreVersion" - testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.2", { + testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.3", { exclude group: 'org.grails', module:'grails-datastore-gorm' exclude group: 'org.grails', module:'grails-datastore-core' exclude group: 'org.springframework', module:'spring-core' diff --git a/grails-test-suite-uber/build.gradle b/grails-test-suite-uber/build.gradle index 330bfc21931..626571a42c6 100644 --- a/grails-test-suite-uber/build.gradle +++ b/grails-test-suite-uber/build.gradle @@ -28,7 +28,7 @@ dependencies { project(":grails-plugin-databinding"), project(':grails-spring') - testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.2", { + testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.3", { exclude group: 'org.grails', module:'grails-datastore-gorm' exclude group: 'org.grails', module:'grails-datastore-core' exclude group: 'org.springframework', module:'spring-core' diff --git a/grails-test-suite-web/build.gradle b/grails-test-suite-web/build.gradle index 8dbe6ac55f6..7f1569b8f08 100644 --- a/grails-test-suite-web/build.gradle +++ b/grails-test-suite-web/build.gradle @@ -29,7 +29,7 @@ dependencies { project(':grails-spring') testImplementation "org.grails.plugins:converters:$legacyConvertersVersion" - testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.2", { + testImplementation "org.grails:grails-datastore-gorm-hibernate5:8.0.3", { exclude group: 'org.grails', module:'grails-datastore-gorm' exclude group: 'org.grails', module:'grails-datastore-core' exclude group: 'org.springframework', module:'spring-core' diff --git a/grails-web-databinding/src/main/groovy/org/grails/web/databinding/converters/AbstractStructuredBindingEditor.groovy b/grails-web-databinding/src/main/groovy/org/grails/web/databinding/converters/AbstractStructuredBindingEditor.groovy index d52f65e3a20..b7fc8a885dd 100644 --- a/grails-web-databinding/src/main/groovy/org/grails/web/databinding/converters/AbstractStructuredBindingEditor.groovy +++ b/grails-web-databinding/src/main/groovy/org/grails/web/databinding/converters/AbstractStructuredBindingEditor.groovy @@ -73,6 +73,6 @@ abstract class AbstractStructuredBindingEditor implements TypedStructuredBind valuesMap[propName] = bindingSource.getPropertyValue(key) } } - valuesMap + valuesMap as Map } } diff --git a/settings.gradle b/settings.gradle index bd3500c886d..c1eec29fce0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,5 @@ plugins { - id "com.gradle.enterprise" version "3.16.1" + id "com.gradle.enterprise" version "3.16.2" id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12.1' } From 3c08bc81e15c548420e6b1286479cc36b6010577 Mon Sep 17 00:00:00 2001 From: Guillermo Calvo Date: Fri, 29 Mar 2024 09:38:04 +0100 Subject: [PATCH 4/5] remove: deprecated type `NavigableMap.NullSafeNavigator` (#13448) * Remove unused imports * Remove deprecated type `NavigableMap.NullSafeNavigator` * [tests] Replace key navigation with map access * [tests] Replace Grail's null-safe navigation with Groovy's operator `?.` * [tests] Delete tests that check Grail's safe navigation * Bump grails-testing-support to version 3.2.2 --- gradle.properties | 2 +- .../groovy/grails/util/BuildSettings.groovy | 2 - .../org/grails/config/CodeGenConfig.groovy | 2 +- .../org/grails/config/NavigableMap.groovy | 171 +----------------- .../groovy/grails/config/ConfigMapSpec.groovy | 15 +- .../grails/config/GrailsConfigSpec.groovy | 5 +- .../GrailsApplicationPostProcessor.groovy | 13 -- .../config/NavigableMapPropertySource.groovy | 2 +- .../plugins/AbstractGrailsPluginManager.java | 14 -- .../config/PropertySourceConfigSpec.groovy | 129 ------------- .../GrailsPlaceholderConfigurerSpec.groovy | 10 +- .../NavigableMapPropertySourceSpec.groovy | 6 +- .../config/PropertySourcesConfigSpec.groovy | 2 +- .../YamlPropertySourceLoaderSpec.groovy | 4 +- ...TransactionManagerPostProcessorSpec.groovy | 8 +- .../grails/web/codecs/HTMLCodecTests.groovy | 4 +- .../grails/web/mime/MimeUtilitySpec.groovy | 2 +- .../grails/cli/profile/ResourceProfile.groovy | 3 +- ...efaultConstraintsUnitTestMixinTests.groovy | 4 +- ...eUnitTestMixinWithCustomViewDirSpec.groovy | 2 +- .../grails/rest/web/RespondMethodSpec.groovy | 2 +- .../web/binding/JSONBindingToNullTests.groovy | 2 +- .../CommandObjectNoDataSpec.groovy | 2 +- .../commandobjects/CommandObjectsSpec.groovy | 2 +- .../controllers/ContentNegotiationSpec.groovy | 4 +- .../mime/ContentFormatControllerTests.groovy | 4 +- .../web/mime/WithFormatContentTypeSpec.groovy | 2 +- 27 files changed, 42 insertions(+), 376 deletions(-) diff --git a/gradle.properties b/gradle.properties index 579c62a6576..f51ea40fdca 100644 --- a/gradle.properties +++ b/gradle.properties @@ -43,7 +43,7 @@ springLoadedVersion=1.2.8.RELEASE springVersion=5.3.31 spring.version=5.3.30 testingSupportVersion=3.1.1 -testingSupportVersionForTests=3.1.2 +testingSupportVersionForTests=3.2.2 tomcatLog4jVersion=8.5.2 tomcatVersion=9.0.85 viewsVersion=3.1.1 diff --git a/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy b/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy index 53354a60f77..09899b9fd16 100644 --- a/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy +++ b/grails-bootstrap/src/main/groovy/grails/util/BuildSettings.groovy @@ -17,8 +17,6 @@ package grails.util import grails.io.IOUtils import groovy.transform.CompileStatic -import org.grails.config.NavigableMap -import org.yaml.snakeyaml.Yaml import java.util.regex.Pattern diff --git a/grails-bootstrap/src/main/groovy/org/grails/config/CodeGenConfig.groovy b/grails-bootstrap/src/main/groovy/org/grails/config/CodeGenConfig.groovy index 8083efdead3..5832fd4ce65 100644 --- a/grails-bootstrap/src/main/groovy/org/grails/config/CodeGenConfig.groovy +++ b/grails-bootstrap/src/main/groovy/org/grails/config/CodeGenConfig.groovy @@ -178,7 +178,7 @@ class CodeGenConfig implements Cloneable, ConfigMap { } protected T convertToType(Object value, Class requiredType) { - if(value == null || value instanceof NavigableMap.NullSafeNavigator) { + if(value == null) { return null } else if(requiredType.isInstance(value)) { diff --git a/grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy b/grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy index 64d82e5a9d2..7119e383491 100644 --- a/grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy +++ b/grails-bootstrap/src/main/groovy/org/grails/config/NavigableMap.groovy @@ -290,7 +290,7 @@ class NavigableMap implements Map, Cloneable { public Object getProperty(String name) { if (!containsKey(name)) { - return new NullSafeNavigator(this, [name].asImmutable()) + return null } Object result = get(name) if (!(result instanceof NavigableMap)) { @@ -427,173 +427,4 @@ class NavigableMap implements Map, Cloneable { boolean equals(Object obj) { return delegateMap.equals(obj) } - - /** - * @deprecated This class will be removed in future. Use {@code config.getProperty(String key, Class targetType)} instead of dot based navigation. - */ - @Deprecated - @CompileStatic - static class NullSafeNavigator implements Map{ - final NavigableMap parent - final List path - - NullSafeNavigator(NavigableMap parent, List path) { - this.parent = parent - this.path = path - if (LOG.isWarnEnabled()) { - LOG.warn("Accessing config key '{}' through dot notation is deprecated, and it will be removed in a future release. Use 'config.getProperty(key, targetClass)' instead.", path) - } - } - - Object getAt(Object key) { - getProperty(String.valueOf(key)) - } - - void setAt(Object key, Object value) { - setProperty(String.valueOf(key), value) - } - - @Override - int size() { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.size() - } - return 0 - } - - @Override - boolean isEmpty() { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.isEmpty() - } - return true - } - - boolean containsKey(Object key) { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap == null) return false - else { - return parentMap.containsKey(key) - } - } - - @Override - boolean containsValue(Object value) { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.containsValue(value) - } - return false - } - - @Override - Object get(Object key) { - return getAt(key) - } - - @Override - Object put(String key, Object value) { - throw new UnsupportedOperationException("Configuration cannot be modified"); - } - - @Override - Object remove(Object key) { - throw new UnsupportedOperationException("Configuration cannot be modified"); - } - - @Override - void putAll(Map m) { - throw new UnsupportedOperationException("Configuration cannot be modified"); - } - - @Override - void clear() { - throw new UnsupportedOperationException("Configuration cannot be modified"); - } - - @Override - Set keySet() { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.keySet() - } - return Collections.emptySet() - } - - @Override - Collection values() { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.values() - } - return Collections.emptySet() - } - - @Override - Set> entrySet() { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap != null) { - return parentMap.entrySet() - } - return Collections.emptySet() - } - - Object getProperty(String name) { - NavigableMap parentMap = parent.navigateSubMap(path, false) - if(parentMap == null) { - return new NullSafeNavigator(parent, ((path + [name]) as List).asImmutable()) - } else { - return parentMap.get(name) - } - } - - public void setProperty(String name, Object value) { - NavigableMap parentMap = parent.navigateSubMap(path, true) - parentMap.setProperty(name, value) - } - - public boolean asBoolean() { - false - } - - public Object invokeMethod(String name, Object args) { - throw new NullPointerException("Cannot invoke method " + name + "() on NullSafeNavigator"); - } - - public boolean equals(Object to) { - return to == null || DefaultGroovyMethods.is(this, to) - } - - public Iterator iterator() { - return Collections.EMPTY_LIST.iterator() - } - - public Object plus(String s) { - return toString() + s - } - - public Object plus(Object o) { - throw new NullPointerException("Cannot invoke method plus on NullSafeNavigator") - } - - public boolean is(Object other) { - return other == null || DefaultGroovyMethods.is(this, other) - } - - public Object asType(Class c) { - if(c==Boolean || c==boolean) return false - return null - } - - public String toString() { - return null - } - -// public int hashCode() { -// throw new NullPointerException("Cannot invoke method hashCode() on NullSafeNavigator"); -// } - } - } diff --git a/grails-bootstrap/src/test/groovy/grails/config/ConfigMapSpec.groovy b/grails-bootstrap/src/test/groovy/grails/config/ConfigMapSpec.groovy index 6f2e98df87e..4ed76c5f2eb 100644 --- a/grails-bootstrap/src/test/groovy/grails/config/ConfigMapSpec.groovy +++ b/grails-bootstrap/src/test/groovy/grails/config/ConfigMapSpec.groovy @@ -62,8 +62,7 @@ test.another = true given: NavigableMap configMap = new NavigableMap() when: - configMap.a.b.c = 1 - configMap.a.b.d = 2 + configMap.a = [b: [c: 1, d: 2]] then: configMap.toFlatConfig() == ['a.b.c': 1, 'a.b.d': 2] } @@ -73,8 +72,7 @@ test.another = true given: NavigableMap configMap = new NavigableMap() when: - configMap.a.b.c = 1 - configMap.a.b.d = 2 + configMap.a = [b: [c: 1, d: 2]] then:"hasCode() doesn't cause a Stack Overflow error" configMap.hashCode() == configMap.hashCode() } @@ -83,8 +81,7 @@ test.another = true given: NavigableMap configMap = new NavigableMap() when: - configMap.a.b.c = [1, 2, 3] - configMap.a.b.d = 2 + configMap.a = [b: [c: [1, 2, 3], d: 2]] then: configMap.toFlatConfig() == ['a.b.c': [1, 2, 3], @@ -98,8 +95,7 @@ test.another = true given: NavigableMap configMap = new NavigableMap() when: - configMap.a.b.c = [1, 2, 3] - configMap.a.b.d = 2 + configMap.a = [b: [c: [1, 2, 3], d: 2]] then: configMap.toProperties() == ['a.b.c': '1,2,3', @@ -112,8 +108,7 @@ test.another = true def "should support cloning"() { given: NavigableMap configMap = new NavigableMap() - configMap.a.b.c = [1, 2, 3] - configMap.a.b.d = 2 + configMap.a = [b: [c: [1, 2, 3], d: 2]] when: NavigableMap cloned = configMap.clone() then: diff --git a/grails-bootstrap/src/test/groovy/grails/config/GrailsConfigSpec.groovy b/grails-bootstrap/src/test/groovy/grails/config/GrailsConfigSpec.groovy index a3dfe199eb2..73842370280 100644 --- a/grails-bootstrap/src/test/groovy/grails/config/GrailsConfigSpec.groovy +++ b/grails-bootstrap/src/test/groovy/grails/config/GrailsConfigSpec.groovy @@ -1,7 +1,6 @@ package grails.config import org.grails.config.CodeGenConfig -import org.grails.config.NavigableMap import spock.lang.Specification class GrailsConfigSpec extends Specification{ @@ -115,9 +114,9 @@ class GrailsConfigSpec extends Specification{ CodeGenConfig config = new CodeGenConfig([a: [b: [c: [d: 1, e: 2]]]]) when: config.a.b = null - config.a.b.c = 1 + config.a.b = [c: 1] then: - config.configMap == [a: [b: [c: 1]], 'a.b.c':1] + config.configMap == [a: [b: [c: 1]], 'a.b.c':1, 'a.b': [c: 1]] } def "should support casting to Map"() { diff --git a/grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy b/grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy index 9de746d7e8f..1bfe5f4cd37 100644 --- a/grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy +++ b/grails-core/src/main/groovy/grails/boot/config/GrailsApplicationPostProcessor.groovy @@ -17,7 +17,6 @@ import groovy.util.logging.Slf4j import io.micronaut.context.env.AbstractPropertySourceLoader import io.micronaut.context.env.PropertySource import io.micronaut.spring.context.env.MicronautEnvironment -import org.grails.config.NavigableMap import org.grails.config.PrefixedMapPropertySource import org.grails.config.PropertySourcesConfig import org.grails.core.exceptions.GrailsConfigurationException @@ -128,18 +127,6 @@ class GrailsApplicationPostProcessor implements BeanDefinitionRegistryPostProces return applicationContext.getResource(source); } }); - conversionService.addConverter(new Converter() { - @Override - public String convert(NavigableMap.NullSafeNavigator source) { - return null; - } - }); - conversionService.addConverter(new Converter() { - @Override - public Object convert(NavigableMap.NullSafeNavigator source) { - return null; - } - }); } def propertySources = environment.getPropertySources() def plugins = pluginManager.allPlugins diff --git a/grails-core/src/main/groovy/org/grails/config/NavigableMapPropertySource.groovy b/grails-core/src/main/groovy/org/grails/config/NavigableMapPropertySource.groovy index 412a25578a1..b76f1e7fead 100644 --- a/grails-core/src/main/groovy/org/grails/config/NavigableMapPropertySource.groovy +++ b/grails-core/src/main/groovy/org/grails/config/NavigableMapPropertySource.groovy @@ -53,7 +53,7 @@ class NavigableMapPropertySource extends MapPropertySource { def value = super.getProperty(name) if (value instanceof OriginTrackedValue) { return ((OriginTrackedValue)value).value - } else if(value instanceof NavigableMap || value instanceof NavigableMap.NullSafeNavigator) { + } else if(value instanceof NavigableMap) { return null } return value diff --git a/grails-core/src/main/groovy/org/grails/plugins/AbstractGrailsPluginManager.java b/grails-core/src/main/groovy/org/grails/plugins/AbstractGrailsPluginManager.java index f0643f4f9c7..302180a0668 100644 --- a/grails-core/src/main/groovy/org/grails/plugins/AbstractGrailsPluginManager.java +++ b/grails-core/src/main/groovy/org/grails/plugins/AbstractGrailsPluginManager.java @@ -18,13 +18,11 @@ import grails.artefact.Enhanced; import grails.plugins.Plugin; import grails.plugins.PluginFilter; -import org.grails.config.NavigableMap; import grails.plugins.GrailsPlugin; import grails.plugins.GrailsPluginManager; import grails.plugins.GrailsVersionUtils; import grails.util.Environment; import grails.util.GrailsNameUtils; -import grails.util.Metadata; import groovy.lang.ExpandoMetaClass; import groovy.lang.GroovySystem; import groovy.lang.MetaClassRegistry; @@ -143,22 +141,10 @@ public void doRuntimeConfiguration(RuntimeSpringConfiguration springConfig) { if(autowireCapableBeanFactory instanceof ConfigurableListableBeanFactory) { ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory)autowireCapableBeanFactory; ConversionService existingConversionService = beanFactory.getConversionService(); - ConverterRegistry converterRegistry; if(existingConversionService == null) { GenericConversionService conversionService = new GenericConversionService(); - converterRegistry = conversionService; beanFactory.setConversionService(conversionService); } - else { - converterRegistry = (ConverterRegistry)existingConversionService; - } - - converterRegistry.addConverter(new Converter() { - @Override - public Object convert(NavigableMap.NullSafeNavigator source) { - return null; - } - }); } checkInitialised(); for (GrailsPlugin plugin : pluginList) { diff --git a/grails-core/src/test/groovy/grails/config/PropertySourceConfigSpec.groovy b/grails-core/src/test/groovy/grails/config/PropertySourceConfigSpec.groovy index ecf0e4c1e13..a440d7b47bd 100644 --- a/grails-core/src/test/groovy/grails/config/PropertySourceConfigSpec.groovy +++ b/grails-core/src/test/groovy/grails/config/PropertySourceConfigSpec.groovy @@ -113,94 +113,6 @@ class PropertySourceConfigSpec extends Specification { config.'a.d' == 1 } - void "should support null safe navigation for getting"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig() - - expect: - config.a.b.c as Boolean == false - config.a.b.c as Map == null - } - - void "should support null safe navigation for setting"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig() - - when: - config.a.b.c = 1 - - then: - config.a == [b: [c: 1]] - config.'a.b' == [c: 1] - config.'a.b.c' == 1 - } - - void "should support merging values when map already exists"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig() - - when: - config.a.b.c = 1 - - then: - config.a == [b: [c: 1]] - config.'a.b' == ['c': 1] - config.'a.b.c' == 1 - - when: - config.merge([a: [d: 2]]) - - then: - config.a == [b: [c: 1], d: 2] - config.'a.b' == ['c': 1] - config.'a.b.c' == 1 - config.'a.d' == 2 - - when: - config.a.b.e = 3 - - then: - config.a == [b: [c: 1, e: 3], d: 2] - config.'a.b' == [c: 1, e: 3] - config.'a.b.c' == 1 - config.'a.d' == 2 - config.'a.b.e' == 3 - } - - void "should support setting map in null safe navigation"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig() - - when: - config.a.b.c = [d: 3, e: [f: 4]] - - then: - config.a == [b: [c: [d: 3, e: [f: 4]]]] - config.'a.b' == [c: [d: 3, e: [f: 4]]] - config.'a.b.c.d' == 3 - config.'a.b.c.e.f' == 4 - config.'a.b.c.e' == [f: 4] - config.'a.b.c' == [d: 3, e: [f: 4]] - } - - void "should support removing values when key is set to null"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig([a: [b: [c: [d: 1, e: 2]]]]) - - when: - config.a.b = null - config.a.b.c = 1 - - then: - config.a == [b: [c: 1]] - config.'a.b.c' == 1 - } - void "should support casting to boolean"() { given: @@ -215,45 +127,4 @@ class PropertySourceConfigSpec extends Specification { then: config as boolean == false } - - void "should support with"() { - given: - PropertySourcesConfig config = new PropertySourcesConfig() - - when: - config.a.b.c.with { - d = 1 - e = 2 - } - - then: - config.a == [b: [c: [d: 1, e: 2]]] - config.'a.b.c' == [d: 1, e: 2] - config.'a.b' == [c: [d: 1, e: 2]] - config.'a.b.c.d' == 1 - config.'a.b.c.e' == 2 - } - - void "null safe navigation should be supported without creating keys"() { - - given: - PropertySourcesConfig config = new PropertySourcesConfig() - def subconfigReference = config.a.b.c.d.e - - expect: - config.size() == 0 - - when: - subconfigReference.f.g = 1 - - then: - config.'a.b.c.d.e.f.g' == 1 - config.'a.b.c.d.e.f' == [g: 1] - config.'a.b.c.d.e' == [f: [g: 1]] - config.'a.b.c.d' == [e: [f: [g: 1]]] - config.'a.b.c' == [d: [e: [f: [g: 1]]]] - config.'a.b' == [c: [d: [e: [f: [g: 1]]]]] - config.'a' == [b: [c: [d: [e: [f: [g: 1]]]]]] - subconfigReference.f == [g: 1] - } } diff --git a/grails-core/src/test/groovy/grails/spring/GrailsPlaceholderConfigurerSpec.groovy b/grails-core/src/test/groovy/grails/spring/GrailsPlaceholderConfigurerSpec.groovy index 32fca260797..9c63e04dcf2 100644 --- a/grails-core/src/test/groovy/grails/spring/GrailsPlaceholderConfigurerSpec.groovy +++ b/grails-core/src/test/groovy/grails/spring/GrailsPlaceholderConfigurerSpec.groovy @@ -18,7 +18,7 @@ class GrailsPlaceholderConfigurerSpec extends Specification { void "Test that property placeholder configuration works for simple properties"() { when:"A bean is defined with a placeholder" def application = new DefaultGrailsApplication() - application.config.foo.bar="test" + application.config.foo = [bar: "test"] def bb = new BeanBuilder() bb.beans { addBeanFactoryPostProcessor(new GrailsPlaceholderConfigurer('${', application.config.toProperties())) @@ -37,8 +37,8 @@ class GrailsPlaceholderConfigurerSpec extends Specification { void "Test that property placeholder configuration doesn't throw an error if invalid placeholders are configured"() { when:"A bean is defined with a placeholder" def application = new DefaultGrailsApplication() - application.config.bar.foo="test" - application.config.more.stuff='another ${place.holder}' + application.config.bar = [foo: "test"] + application.config.more = [stuff: 'another ${place.holder}'] def bb = new BeanBuilder() bb.beans { addBeanFactoryPostProcessor(new GrailsPlaceholderConfigurer('${', application.config.toProperties())) @@ -56,8 +56,8 @@ class GrailsPlaceholderConfigurerSpec extends Specification { void "Test that property placeholder configuration works for simple properties with a custom placeholder prefix"() { when:"A bean is defined with a placeholder" def application = new DefaultGrailsApplication() - application.config.foo.bar="test" - application.config.grails.spring.placeholder.prefix='£{' + application.config.foo = [bar: "test"] + application.config['grails.spring.placeholder.prefix']='£{' application.setConfig(application.config) def bb = new BeanBuilder() bb.beans { diff --git a/grails-core/src/test/groovy/org/grails/config/NavigableMapPropertySourceSpec.groovy b/grails-core/src/test/groovy/org/grails/config/NavigableMapPropertySourceSpec.groovy index 759216043bb..f1425c962dd 100644 --- a/grails-core/src/test/groovy/org/grails/config/NavigableMapPropertySourceSpec.groovy +++ b/grails-core/src/test/groovy/org/grails/config/NavigableMapPropertySourceSpec.groovy @@ -26,13 +26,13 @@ class NavigableMapPropertySourceSpec extends Specification { def "Ensure navigable maps are not returned from a NavigableMapPropertySource"() { given:"A navigable map" def map = new NavigableMap() - map.foo.bar = "myval" + map.foo = [bar: "myval"] when:"A NavigableMapPropertySource is created" def ps = new NavigableMapPropertySource("test", map) then:"Nulls are returned for submaps" - map.keySet() == ['foo', 'foo.bar' ] as Set + map.keySet() == ['foo.bar', 'foo'] as Set ps.getPropertyNames() == ['foo.bar'] as String[] - ps.getNavigablePropertyNames() == ['foo' , 'foo.bar'] as String[] + ps.getNavigablePropertyNames() == ['foo.bar', 'foo'] as String[] ps.getProperty('foo') == null ps.getNavigableProperty('foo') instanceof NavigableMap diff --git a/grails-core/src/test/groovy/org/grails/config/PropertySourcesConfigSpec.groovy b/grails-core/src/test/groovy/org/grails/config/PropertySourcesConfigSpec.groovy index 1829820e4ef..3887a0a091b 100644 --- a/grails-core/src/test/groovy/org/grails/config/PropertySourcesConfigSpec.groovy +++ b/grails-core/src/test/groovy/org/grails/config/PropertySourcesConfigSpec.groovy @@ -41,7 +41,7 @@ class PropertySourcesConfigSpec extends Specification { config.one == 1 config.two == 2 config.three.four == 34 - !config.four.five + !config?.four?.five config.getProperty('one', String) == '1' config.getProperty('three.four', String) == '34' config.getProperty('three', String) == null diff --git a/grails-core/src/test/groovy/org/grails/config/YamlPropertySourceLoaderSpec.groovy b/grails-core/src/test/groovy/org/grails/config/YamlPropertySourceLoaderSpec.groovy index 4fffbadf955..ea6028c29af 100644 --- a/grails-core/src/test/groovy/org/grails/config/YamlPropertySourceLoaderSpec.groovy +++ b/grails-core/src/test/groovy/org/grails/config/YamlPropertySourceLoaderSpec.groovy @@ -26,7 +26,7 @@ class YamlPropertySourceLoaderSpec extends Specification { config.one == 2 config.two == 3 config.three.four == 45 - !config.four.five + !config.four?.five config.getProperty('one', String) == '2' config.getProperty('three.four', String) == '45' config.getProperty('three', String) == null @@ -51,7 +51,7 @@ class YamlPropertySourceLoaderSpec extends Specification { then: "These will not be navigable due to false parseFlatKeys" config.one == 2 config.two == 3 - !config.four.five + !config.four?.five config.getProperty('one', String) == '2' config.getProperty('three.four', String) == '45' config.getProperty('three', String) == null diff --git a/grails-core/src/test/groovy/org/grails/transaction/ChainedTransactionManagerPostProcessorSpec.groovy b/grails-core/src/test/groovy/org/grails/transaction/ChainedTransactionManagerPostProcessorSpec.groovy index fa8433dccd8..5e919cac54f 100644 --- a/grails-core/src/test/groovy/org/grails/transaction/ChainedTransactionManagerPostProcessorSpec.groovy +++ b/grails-core/src/test/groovy/org/grails/transaction/ChainedTransactionManagerPostProcessorSpec.groovy @@ -66,8 +66,8 @@ class ChainedTransactionManagerPostProcessorSpec extends Specification { given: def bb = new BeanBuilder() def config = new PropertySourcesConfig() - config.dataSources.ds1.transactional = false - config.dataSources.ds2.transactional = false + config['dataSources.ds1.transactional'] = false + config['dataSources.ds2.transactional'] = false bb.beans { chainedTransactionManagerPostProcessor(ChainedTransactionManagerPostProcessor, config) transactionManager(ChainedTransactionManagerTests.TestPlatformTransactionManager, "transactionManager") @@ -86,8 +86,8 @@ class ChainedTransactionManagerPostProcessorSpec extends Specification { given: def bb = new BeanBuilder() def config = new PropertySourcesConfig() - config.dataSources.ds1.transactional = false - config.dataSources.ds2.transactional = true + config['dataSources.ds1.transactional'] = false + config['dataSources.ds2.transactional'] = true bb.beans { chainedTransactionManagerPostProcessor(ChainedTransactionManagerPostProcessor, config) transactionManager(ChainedTransactionManagerTests.TestPlatformTransactionManager, "transactionManager") diff --git a/grails-plugin-codecs/src/test/groovy/org/grails/web/codecs/HTMLCodecTests.groovy b/grails-plugin-codecs/src/test/groovy/org/grails/web/codecs/HTMLCodecTests.groovy index 5a0c46fa6b3..96795019c85 100644 --- a/grails-plugin-codecs/src/test/groovy/org/grails/web/codecs/HTMLCodecTests.groovy +++ b/grails-plugin-codecs/src/test/groovy/org/grails/web/codecs/HTMLCodecTests.groovy @@ -11,7 +11,7 @@ class HTMLCodecTests { def getEncoderXml() { def htmlCodec = new HTMLCodec() def grailsApplication = new DefaultGrailsApplication() - grailsApplication.config.grails.views.gsp.htmlcodec = 'xml' + grailsApplication.config['grails.views.gsp.htmlcodec'] = 'xml' grailsApplication.configChanged() htmlCodec.setGrailsApplication(grailsApplication) htmlCodec.afterPropertiesSet() @@ -21,7 +21,7 @@ class HTMLCodecTests { def getEncoderHtml() { def htmlCodec = new HTMLCodec() def grailsApplication = new DefaultGrailsApplication() - grailsApplication.config.grails.views.gsp.htmlcodec = 'html' + grailsApplication.config['grails.views.gsp.htmlcodec'] = 'html' grailsApplication.configChanged() htmlCodec.setGrailsApplication(grailsApplication) htmlCodec.afterPropertiesSet() diff --git a/grails-plugin-mimetypes/src/test/groovy/grails/web/mime/MimeUtilitySpec.groovy b/grails-plugin-mimetypes/src/test/groovy/grails/web/mime/MimeUtilitySpec.groovy index a99fd378b86..4b619fe90f6 100644 --- a/grails-plugin-mimetypes/src/test/groovy/grails/web/mime/MimeUtilitySpec.groovy +++ b/grails-plugin-mimetypes/src/test/groovy/grails/web/mime/MimeUtilitySpec.groovy @@ -13,7 +13,7 @@ class MimeUtilitySpec extends Specification { MimeUtility getMimeUtility() { def ga = new DefaultGrailsApplication() - ga.config.grails.mime.types = [ html: ['text/html','application/xhtml+xml'], + ga.config['grails.mime.types'] = [ html: ['text/html','application/xhtml+xml'], xml: ['text/xml', 'application/xml'], text: 'text/plain', js: 'text/javascript', diff --git a/grails-shell/src/main/groovy/org/grails/cli/profile/ResourceProfile.groovy b/grails-shell/src/main/groovy/org/grails/cli/profile/ResourceProfile.groovy index b5007e5e232..cc9cfb07d73 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/profile/ResourceProfile.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/profile/ResourceProfile.groovy @@ -16,9 +16,8 @@ package org.grails.cli.profile import groovy.transform.CompileStatic -import org.grails.config.NavigableMap import org.grails.io.support.Resource -import org.yaml.snakeyaml.Yaml + /** * A profile that operates against abstract {@link Resource} references * diff --git a/grails-test-suite-uber/src/test/groovy/grails/test/mixin/DomainClassWithDefaultConstraintsUnitTestMixinTests.groovy b/grails-test-suite-uber/src/test/groovy/grails/test/mixin/DomainClassWithDefaultConstraintsUnitTestMixinTests.groovy index b15cb733d41..f1699630fbf 100644 --- a/grails-test-suite-uber/src/test/groovy/grails/test/mixin/DomainClassWithDefaultConstraintsUnitTestMixinTests.groovy +++ b/grails-test-suite-uber/src/test/groovy/grails/test/mixin/DomainClassWithDefaultConstraintsUnitTestMixinTests.groovy @@ -6,8 +6,8 @@ import spock.lang.Specification class DomainClassWithDefaultConstraintsUnitTestMixinTests extends Specification implements DomainUnitTest { - Closure doWithConfig() {{ c -> - c.grails.gorm.default.constraints = { + Closure doWithConfig() {{ config -> + config['grails.gorm.default.constraints'] = { '*'(nullable:true) } }} diff --git a/grails-test-suite-uber/src/test/groovy/grails/test/mixin/GroovyPageUnitTestMixinWithCustomViewDirSpec.groovy b/grails-test-suite-uber/src/test/groovy/grails/test/mixin/GroovyPageUnitTestMixinWithCustomViewDirSpec.groovy index e90dad82052..b0a7804a9da 100644 --- a/grails-test-suite-uber/src/test/groovy/grails/test/mixin/GroovyPageUnitTestMixinWithCustomViewDirSpec.groovy +++ b/grails-test-suite-uber/src/test/groovy/grails/test/mixin/GroovyPageUnitTestMixinWithCustomViewDirSpec.groovy @@ -9,7 +9,7 @@ class GroovyPageUnitTestMixinWithCustomViewDirSpec extends Specification impleme Closure doWithConfig() {{ c -> def customViewDir = new File('.', 'src/test/resources/customviews') - c.grails.gsp.view.dir = customViewDir.absolutePath + c['grails.gsp.view.dir'] = customViewDir.absolutePath }} @Issue('GRAILS=11543') diff --git a/grails-test-suite-web/src/test/groovy/grails/rest/web/RespondMethodSpec.groovy b/grails-test-suite-web/src/test/groovy/grails/rest/web/RespondMethodSpec.groovy index 6180c290c38..ee0188ee8fe 100644 --- a/grails-test-suite-web/src/test/groovy/grails/rest/web/RespondMethodSpec.groovy +++ b/grails-test-suite-web/src/test/groovy/grails/rest/web/RespondMethodSpec.groovy @@ -32,7 +32,7 @@ class RespondMethodSpec extends Specification implements ControllerUnitTest // unit tests in real applications will not need to do // this because the real Config.groovy will be loaded - config.grails.mime.types = [html : ['text/html', 'application/xhtml+xml'], + config['grails.mime.types'] = [html : ['text/html', 'application/xhtml+xml'], xml : ['text/xml', 'application/xml'], text : 'text/plain', js : 'text/javascript', diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/binding/JSONBindingToNullTests.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/binding/JSONBindingToNullTests.groovy index 8c19717ced6..0f57d47d9db 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/binding/JSONBindingToNullTests.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/binding/JSONBindingToNullTests.groovy @@ -12,7 +12,7 @@ import spock.lang.Specification class JSONBindingToNullTests extends Specification implements ControllerUnitTest, DomainUnitTest { Closure doWithConfig() {{ config -> - config.grails.mime.types = [ html: ['text/html','application/xhtml+xml'], + config['grails.mime.types'] = [ html: ['text/html','application/xhtml+xml'], xml: ['text/xml', 'application/xml'], text: 'text/plain', js: 'text/javascript', diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectNoDataSpec.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectNoDataSpec.groovy index aaebc13ca69..63c8909e75e 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectNoDataSpec.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectNoDataSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Specification class CommandObjectNoDataSpec extends Specification implements GrailsWebUnitTest { Closure doWithConfig() {{ config -> - config.grails.gorm.default.constraints = { + config['grails.gorm.default.constraints'] = { isProg inList: ['Emerson', 'Lake', 'Palmer'] } }} diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectsSpec.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectsSpec.groovy index a7c14fe59c7..ac90beeaf59 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectsSpec.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/commandobjects/CommandObjectsSpec.groovy @@ -14,7 +14,7 @@ class CommandObjectsSpec extends Specification implements ControllerUnitTest - config.grails.gorm.default.constraints = { + config['grails.gorm.default.constraints'] = { isProg inList: ['Emerson', 'Lake', 'Palmer'] } }} diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/controllers/ContentNegotiationSpec.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/controllers/ContentNegotiationSpec.groovy index 3930f9237c7..56cfd2ad7f4 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/controllers/ContentNegotiationSpec.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/controllers/ContentNegotiationSpec.groovy @@ -13,8 +13,8 @@ import spock.lang.Unroll class ContentNegotiationSpec extends Specification implements ControllerUnitTest { Closure doWithConfig() {{ config -> - config.grails.mime.use.accept.header=true - config.grails.mime.types = [ // the first one is the default format + config['grails.mime.use.accept.header'] = true + config['grails.mime.types'] = [ // the first one is the default format html: ['text/html','application/xhtml+xml'], all: '*/*', atom: 'application/atom+xml', diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/mime/ContentFormatControllerTests.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/mime/ContentFormatControllerTests.groovy index dc33a42f305..64b43810af7 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/mime/ContentFormatControllerTests.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/mime/ContentFormatControllerTests.groovy @@ -15,8 +15,8 @@ import spock.lang.Specification class ContentFormatControllerTests extends Specification implements ControllerUnitTest, DomainUnitTest { Closure doWithConfig() {{ c -> - c.grails.mime.use.accept.header = true - c.grails.mime.types = [html: ['text/html', 'application/xhtml+xml'], + c['grails.mime.use.accept.header'] = true + c['grails.mime.types'] = [html: ['text/html', 'application/xhtml+xml'], xml : ['text/xml', 'application/xml'], text: 'text/plain', js : 'text/javascript', diff --git a/grails-test-suite-web/src/test/groovy/org/grails/web/mime/WithFormatContentTypeSpec.groovy b/grails-test-suite-web/src/test/groovy/org/grails/web/mime/WithFormatContentTypeSpec.groovy index 6051a0fadd6..b8d4c39c5f1 100644 --- a/grails-test-suite-web/src/test/groovy/org/grails/web/mime/WithFormatContentTypeSpec.groovy +++ b/grails-test-suite-web/src/test/groovy/org/grails/web/mime/WithFormatContentTypeSpec.groovy @@ -11,7 +11,7 @@ class WithFormatContentTypeSpec extends Specification implements ControllerUnitT Closure doWithConfig() {{ config -> // unit tests in real applications will not need to do // this because the real Config.groovy will be loaded - config.grails.mime.types = [(MimeType.ALL.extension): MimeType.ALL.name, + config['grails.mime.types'] = [(MimeType.ALL.extension): MimeType.ALL.name, (MimeType.FORM.extension): MimeType.FORM.name, (MimeType.MULTIPART_FORM.extension): MimeType.MULTIPART_FORM.name, (MimeType.JSON.extension): MimeType.JSON.name] From 6480702b84e56b92ae9f7d81699c91ee86123f2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 23:15:12 +0530 Subject: [PATCH 5/5] fix(deps): update dependency org.fusesource.jansi:jansi to v2 (#13436) * fix(deps): update dependency org.fusesource.jansi:jansi to v2 * fix(ansi): remove the usages of deprecated methods Use `AnsiConsole.systemInstall()` and `AnsiConsole.systemUninstall()`. * fix(grailsconsole): bind system out and err stream --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Puneet Behl --- gradle.properties | 2 +- .../grails/build/logging/GrailsConsole.java | 159 ++++++++---------- .../build/logging/GrailsEclipseConsole.java | 21 +-- .../AnsiConsoleUrlMappingsRendererSpec.groovy | 67 ++++---- 4 files changed, 104 insertions(+), 145 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1b85188497c..1376e0d7c40 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,7 +16,7 @@ h2.version=2.2.224 h2Version=2.2.224 hibernateDatastoreVersion=8.0.2 jakartaAnnotationApiVersion=2.0.0 -jansiVersion=1.18 +jansiVersion=2.4.1 javaParserCoreVersion=3.25.9 javaxAnnotationApiVersion=1.3.2 jaxbApiVersion=2.3.1 diff --git a/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsConsole.java b/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsConsole.java index f77eec47701..36b53306720 100644 --- a/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsConsole.java +++ b/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsConsole.java @@ -15,18 +15,7 @@ */ package grails.build.logging; -import static org.fusesource.jansi.Ansi.ansi; -import static org.fusesource.jansi.Ansi.Color.DEFAULT; -import static org.fusesource.jansi.Ansi.Color.RED; -import static org.fusesource.jansi.Ansi.Color.YELLOW; -import static org.fusesource.jansi.Ansi.Erase.FORWARD; import grails.util.Environment; - -import java.io.*; -import java.util.Collection; -import java.util.List; -import java.util.Stack; - import jline.Terminal; import jline.TerminalFactory; import jline.UnixTerminal; @@ -37,17 +26,25 @@ import jline.internal.Log; import jline.internal.ShutdownHooks; import jline.internal.TerminalLineSettings; - import org.apache.tools.ant.BuildException; -import org.grails.build.interactive.CandidateListCompletionHandler; -import org.grails.build.logging.GrailsConsoleErrorPrintStream; -import org.grails.build.logging.GrailsConsolePrintStream; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.runtime.StackTraceUtils; import org.codehaus.groovy.runtime.typehandling.NumberMath; import org.fusesource.jansi.Ansi; import org.fusesource.jansi.Ansi.Color; import org.fusesource.jansi.AnsiConsole; +import org.grails.build.interactive.CandidateListCompletionHandler; +import org.grails.build.logging.GrailsConsoleErrorPrintStream; +import org.grails.build.logging.GrailsConsolePrintStream; + +import java.io.*; +import java.util.Collection; +import java.util.List; +import java.util.Stack; + +import static org.fusesource.jansi.Ansi.Color.*; +import static org.fusesource.jansi.Ansi.Erase.FORWARD; +import static org.fusesource.jansi.Ansi.ansi; /** * Utility class for delivering console output in a nicely formatted way. @@ -77,7 +74,7 @@ public class GrailsConsole implements ConsoleLogger { private int cursorMove; private Thread shutdownHookThread; private Character defaultInputMask = null; - + /** * Whether to enable verbose mode */ @@ -120,7 +117,7 @@ public class GrailsConsole implements ConsoleLogger { @Override public String toString() { if (size() == 1) return peek() + CATEGORY_SEPARATOR; - return DefaultGroovyMethods.join((Iterable)this, CATEGORY_SEPARATOR) + CATEGORY_SEPARATOR; + return DefaultGroovyMethods.join((Iterable) this, CATEGORY_SEPARATOR) + CATEGORY_SEPARATOR; } }; @@ -135,7 +132,7 @@ public String toString() { private boolean userInputActive; public void addShutdownHook() { - if( !Environment.isFork() ) { + if (!Environment.isFork()) { shutdownHookThread = new Thread(new Runnable() { @Override public void run() { @@ -145,14 +142,14 @@ public void run() { Runtime.getRuntime().addShutdownHook(shutdownHookThread); } } - + public void removeShutdownHook() { - if(shutdownHookThread != null) { + if (shutdownHookThread != null) { Runtime.getRuntime().removeShutdownHook(shutdownHookThread); } } - - + + protected GrailsConsole() throws IOException { cursorMove = 1; @@ -162,13 +159,14 @@ protected GrailsConsole() throws IOException { maxIndicatorString = new StringBuilder(indicator).append(indicator).append(indicator).append(indicator).append(indicator); } - + /** * Use in testing when System.out, System.err or System.in change + * * @throws IOException */ public void reinitialize(InputStream systemIn, PrintStream systemOut, PrintStream systemErr) throws IOException { - if(reader != null) { + if (reader != null) { reader.shutdown(); } initialize(systemIn, systemOut, systemErr); @@ -180,7 +178,7 @@ protected void initialize(InputStream systemIn, PrintStream systemOut, PrintStre redirectSystemOutAndErr(true); System.setProperty(ShutdownHooks.JLINE_SHUTDOWNHOOK, "false"); - + if (isInteractiveEnabled()) { reader = createConsoleReader(systemIn); reader.setBellEnabled(false); @@ -193,38 +191,28 @@ protected void initialize(InputStream systemIn, PrintStream systemOut, PrintStre if (history != null) { reader.setHistory(history); } - } - else if (isActivateTerminal()) { + } else if (isActivateTerminal()) { terminal = createTerminal(); } } protected void bindSystemOutAndErr(PrintStream systemOut, PrintStream systemErr) { originalSystemOut = unwrapPrintStream(systemOut); - out = wrapInPrintStream(originalSystemOut); + out = originalSystemOut; originalSystemErr = unwrapPrintStream(systemErr); - err = wrapInPrintStream(originalSystemErr); + err = originalSystemErr; } - + private PrintStream unwrapPrintStream(PrintStream printStream) { - if(printStream instanceof GrailsConsolePrintStream) { - return ((GrailsConsolePrintStream)printStream).getTargetOut(); + if (printStream instanceof GrailsConsolePrintStream) { + return ((GrailsConsolePrintStream) printStream).getTargetOut(); } - if(printStream instanceof GrailsConsoleErrorPrintStream) { - return ((GrailsConsoleErrorPrintStream)printStream).getTargetOut(); + if (printStream instanceof GrailsConsoleErrorPrintStream) { + return ((GrailsConsoleErrorPrintStream) printStream).getTargetOut(); } return printStream; } - private PrintStream wrapInPrintStream(PrintStream printStream) { - OutputStream ansiWrapped = ansiWrap(printStream); - if(ansiWrapped instanceof PrintStream) { - return (PrintStream)ansiWrapped; - } else { - return new PrintStream(ansiWrapped, true); - } - } - public PrintStream getErr() { return err; } @@ -271,7 +259,7 @@ protected ConsoleReader createConsoleReader(InputStream systemIn) throws IOExcep */ protected Terminal createTerminal() { terminal = TerminalFactory.create(); - if(isWindows()) { + if (isWindows()) { terminal.setEchoEnabled(true); } return terminal; @@ -279,7 +267,7 @@ protected Terminal createTerminal() { public void resetCompleters() { final ConsoleReader reader = getReader(); - if(reader != null) { + if (reader != null) { Collection completers = reader.getCompleters(); for (Completer completer : completers) { reader.removeCompleter(completer); @@ -292,6 +280,7 @@ public void resetCompleters() { } } } + /** * Prepares a history file to be used by the ConsoleReader. This file * will live in the home directory of the user. @@ -301,24 +290,13 @@ protected History prepareHistory() throws IOException { if (!file.exists()) { try { file.createNewFile(); - } - catch (IOException ignored) { + } catch (IOException ignored) { // can't create the file, so no history for you } } return file.canWrite() ? new FileHistory(file) : null; } - /** - * Hook method that allows controlling whether or not output streams should be wrapped by - * AnsiConsole.wrapOutputStream. Unfortunately, Eclipse consoles will look to the AnsiWrap - * like they do not understand ansi, even if we were to implement support in Eclipse to' - * handle it and the wrapped stream will not pass the ansi chars on to Eclipse). - */ - protected OutputStream ansiWrap(OutputStream out) { - return AnsiConsole.wrapOutputStream(out); - } - public boolean isWindows() { return System.getProperty("os.name").toLowerCase().indexOf("windows") != -1; } @@ -327,20 +305,23 @@ public static synchronized GrailsConsole getInstance() { if (instance == null) { try { final GrailsConsole console = createInstance(); + AnsiConsole.systemInstall(); console.addShutdownHook(); setInstance(console); } catch (IOException e) { throw new RuntimeException("Cannot create grails console: " + e.getMessage(), e); + } finally { + AnsiConsole.systemUninstall(); } } return instance; } - + public static synchronized void removeInstance() { if (instance != null) { instance.removeShutdownHook(); instance.restoreOriginalSystemOutAndErr(); - if(instance.getReader() != null) { + if (instance.getReader() != null) { instance.getReader().shutdown(); } instance = null; @@ -358,7 +339,7 @@ protected void restoreTerminal() { } catch (Exception e) { // ignore } - if(terminal instanceof UnixTerminal) { + if (terminal instanceof UnixTerminal) { // workaround for GRAILS-11494 try { new TerminalLineSettings().set("sane"); @@ -369,11 +350,10 @@ protected void restoreTerminal() { } protected void persistHistory() { - if(history instanceof Flushable) { + if (history instanceof Flushable) { try { - ((Flushable)history).flush(); - } - catch (Throwable e) { + ((Flushable) history).flush(); + } catch (Throwable e) { // ignore exception } } @@ -388,7 +368,7 @@ protected void redirectSystemOutAndErr(boolean force) { if (force || !(System.out instanceof GrailsConsolePrintStream)) { System.setOut(new GrailsConsolePrintStream(out)); } - if (force || !(System.err instanceof GrailsConsoleErrorPrintStream )) { + if (force || !(System.err instanceof GrailsConsoleErrorPrintStream)) { System.setErr(new GrailsConsoleErrorPrintStream(err)); } } @@ -438,7 +418,6 @@ public boolean isVerbose() { } /** - * * @return Whether to show stack traces */ public boolean isStacktrace() { @@ -508,8 +487,7 @@ public void indicateProgress() { updateStatus(lastMessage + indicator); } } - } - else { + } else { out.print(indicator); } } @@ -525,7 +503,7 @@ public void indicateProgress(int number, int total) { progressIndicatorActive = true; String currMsg = lastMessage; try { - updateStatus(currMsg + ' '+ number + " of " + total); + updateStatus(currMsg + ' ' + number + " of " + total); } finally { lastMessage = currMsg; } @@ -548,8 +526,7 @@ public void indicateProgressPercentage(long number, long total) { if (!isAnsiEnabled()) { out.print(".."); out.print(percentage + '%'); - } - else { + } else { updateStatus(currMsg + ' ' + percentage + '%'); } } finally { @@ -570,8 +547,7 @@ public void indicateProgress(int number) { try { if (isAnsiEnabled()) { updateStatus(currMsg + ' ' + number); - } - else { + } else { out.print(".."); out.print(number); } @@ -621,9 +597,9 @@ private void outputMessage(String msg, int replaceCount) { } private Ansi moveDownToSkipPrompt() { - return ansi() - .cursorDown(1) - .cursorLeft(PROMPT.length()); + return ansi() + .cursorDown(1) + .cursorLeft(PROMPT.length()); } private void postPrintMessage() { @@ -691,17 +667,16 @@ public boolean isAnsiEnabled() { /** * Use to log an error * - * @param msg The message + * @param msg The message * @param error The error */ @Override public void error(String msg, Throwable error) { try { - if ((verbose||stacktrace) && error != null) { + if ((verbose || stacktrace) && error != null) { printStackTrace(msg, error); error(ERROR, msg); - } - else { + } else { error(ERROR, msg + STACKTRACE_MESSAGE); } } finally { @@ -752,8 +727,7 @@ public void log(String msg) { } if (msg.endsWith(LINE_SEPARATOR)) { printStream.print(msg); - } - else { + } else { printStream.println(msg); } cursorMove = 0; @@ -785,8 +759,7 @@ public void append(String msg) { } if (msg.endsWith(LINE_SEPARATOR)) { printStream.print(msg); - } - else { + } else { printStream.println(msg); } cursorMove = 0; @@ -831,6 +804,7 @@ public void echoStatus() { * Replacement for AntBuilder.input() to eliminate dependency of * GrailsScriptRunner on the Ant libraries. Prints a message and * returns whatever the user enters (once they press <return>). + * * @param msg The message/question to display. * @return The line of text entered by the user. May be a blank * string. @@ -868,6 +842,7 @@ private String doUserInput(String msg, boolean secure) { /** * Shows the prompt to request user input + * * @param prompt The prompt to use * @return The user input prompt */ @@ -898,6 +873,7 @@ private String readLine(String prompt, boolean secure) { /** * Shows the prompt to request user input + * * @return The user input prompt */ public String showPrompt() { @@ -927,9 +903,10 @@ public String userInput(String message, List validResponses) { * displayed again and the method waits for more input. It will * display the message a maximum of three times before it gives up * and returns null. - * @param message The message/question to display. + * + * @param message The message/question to display. * @param validResponses An array of responses that the user is - * allowed to enter. Displayed after the message. + * allowed to enter. Displayed after the message. * @return The line of text entered by the user, or null * if the user never entered a valid string. */ @@ -1001,16 +978,14 @@ public void error(String label, String message) { cursorMove = 0; try { if (isAnsiEnabled()) { - Ansi ansi = outputErrorLabel(userInputActive ? moveDownToSkipPrompt() : ansi(), label).a(message).reset(); + Ansi ansi = outputErrorLabel(userInputActive ? moveDownToSkipPrompt() : ansi(), label).a(message).reset(); if (message.endsWith(LINE_SEPARATOR)) { out.print(ansi); - } - else { + } else { out.println(ansi); } - } - else { + } else { out.print(label); out.print(" "); logSimpleError(message); @@ -1024,7 +999,7 @@ private void verifySystemOut() { // something bad may have overridden the system out redirectSystemOutAndErr(false); } - + public void restoreOriginalSystemOutAndErr() { System.setOut(originalSystemOut); System.setErr(originalSystemErr); diff --git a/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsEclipseConsole.java b/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsEclipseConsole.java index ca42c6d81cc..5f69165ded5 100644 --- a/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsEclipseConsole.java +++ b/grails-bootstrap/src/main/groovy/grails/build/logging/GrailsEclipseConsole.java @@ -15,12 +15,11 @@ */ package grails.build.logging; -import java.io.IOException; -import java.io.OutputStream; - import jline.Terminal; import jline.UnsupportedTerminal; +import java.io.IOException; + /** * This class is meant to keep changes made in support of Eclipse separate from * the standard GrailsConsole implementation. @@ -54,22 +53,6 @@ public GrailsEclipseConsole() throws IOException { super(); } - @Override - protected OutputStream ansiWrap(OutputStream out) { - if (DEBUG) { - try { - out.write(("<<<"+ECLIPSE_SUPPORTS_ANSI_PROP+":"+eclipseSupportsAnsi()+">>>\n").getBytes("UTF-8")); - } catch (IOException e) { - } - } - //This method is called from the super constructor so eclipseSupportsAnsi field - //must be lazy initialised (it can't be initialised before we get called!) - if (eclipseSupportsAnsi()) { - return out; // expose unfiltered output to eclipse - } - return super.ansiWrap(out); - } - private boolean eclipseSupportsAnsi() { if (eclipseSupportsAnsi == null) { eclipseSupportsAnsi = boolProp(ECLIPSE_SUPPORTS_ANSI_PROP); diff --git a/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/reporting/AnsiConsoleUrlMappingsRendererSpec.groovy b/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/reporting/AnsiConsoleUrlMappingsRendererSpec.groovy index bfecdef1675..03c155fab32 100644 --- a/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/reporting/AnsiConsoleUrlMappingsRendererSpec.groovy +++ b/grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/reporting/AnsiConsoleUrlMappingsRendererSpec.groovy @@ -13,26 +13,26 @@ import spock.lang.Specification /** * @author Graeme Rocher */ -class AnsiConsoleUrlMappingsRendererSpec extends Specification{ +class AnsiConsoleUrlMappingsRendererSpec extends Specification { void "Test render URL mappings for 3 level resource"() { - given:"A URL mappings renderer" - def sw = new ByteArrayOutputStream() - def ps = new PrintStream(sw) - def renderer = new AnsiConsoleUrlMappingsRenderer(ps) - renderer.isAnsiEnabled = false - def urlMappingsHolder = getUrlMappingsHolder { - "/books"(resources:'book') { - '/authors'(resources:'author') { - '/publisher'(resource:'publisher') - } + given: "A URL mappings renderer" + def sw = new ByteArrayOutputStream() + def ps = new PrintStream(sw) + def renderer = new AnsiConsoleUrlMappingsRenderer(ps) + renderer.isAnsiEnabled = false + def urlMappingsHolder = getUrlMappingsHolder { + "/books"(resources: 'book') { + '/authors'(resources: 'author') { + '/publisher'(resource: 'publisher') } } - when:"The URL mappings are rendered" - renderer.render(urlMappingsHolder.urlMappings.toList()) - println sw.toString() - then:"The output is correct" - sw.toString() == '''Controller: author + } + when: "The URL mappings are rendered" + renderer.render(urlMappingsHolder.urlMappings.toList()) + println sw.toString() + then: "The output is correct" + sw.toString() == '''Controller: author | GET | /books/${bookId}/authors/create | Action: create | | GET | /books/${bookId}/authors/${id}/edit | Action: edit | | POST | /books/${bookId}/authors | Action: save | @@ -65,25 +65,25 @@ Controller: publisher } void "Test render URL mappings to target stream"() { - given:"A URL mappings renderer" - def sw = new ByteArrayOutputStream() - def ps = new PrintStream(sw) - def renderer = new AnsiConsoleUrlMappingsRenderer(ps) - renderer.isAnsiEnabled = false - def urlMappingsHolder = getUrlMappingsHolder { - "/$controller/$action?/$id?(.$format)?"() - "/images/$name**.jpg"(controller:"image") - "/foo"(resources:"foo") - "500"(controller:"errors") - "/"(view:"/index") + given: "A URL mappings renderer" + def sw = new ByteArrayOutputStream() + def ps = new PrintStream(sw) + def renderer = new AnsiConsoleUrlMappingsRenderer(ps) + renderer.isAnsiEnabled = false + def urlMappingsHolder = getUrlMappingsHolder { + "/$controller/$action?/$id?(.$format)?"() + "/images/$name**.jpg"(controller: "image") + "/foo"(resources: "foo") + "500"(controller: "errors") + "/"(view: "/index") - } + } - when:"The URL mappings are rendered" - renderer.render(urlMappingsHolder.urlMappings.toList()) - println sw.toString() - then:"The output is correct" - sw.toString() == '''Dynamic Mappings + when: "The URL mappings are rendered" + renderer.render(urlMappingsHolder.urlMappings.toList()) + println sw.toString() + then: "The output is correct" + sw.toString() == '''Dynamic Mappings | * | / | View: /index | | * | /${controller}/${action}?/${id}?(.${format)? | Action: (default action) | @@ -105,6 +105,7 @@ Controller: image '''.denormalize() } + UrlMappingsHolder getUrlMappingsHolder(Closure mappings) { def ctx = new MockApplicationContext() ctx.registerMockBean(GrailsApplication.APPLICATION_ID, new DefaultGrailsApplication())