diff --git a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java index 4fac607d8f..d4f5443797 100644 --- a/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java +++ b/spring-core/src/main/java/org/springframework/core/env/ProfilesParser.java @@ -24,10 +24,10 @@ import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.function.Predicate; +import java.util.stream.Collectors; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Internal parser used by {@link Profiles#of}. @@ -189,7 +189,14 @@ final class ProfilesParser { @Override public String toString() { - return StringUtils.collectionToDelimitedString(this.expressions, " or "); + if (this.expressions.size() == 1) { + return this.expressions.iterator().next(); + } + return this.expressions.stream().map(this::wrap).collect(Collectors.joining(" | ")); + } + + private String wrap(String str) { + return "(" + str + ")"; } } diff --git a/spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java b/spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java index 01454ad10e..da58631640 100644 --- a/spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java +++ b/spring-core/src/test/java/org/springframework/core/env/ProfilesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 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. @@ -272,6 +272,12 @@ class ProfilesTests { assertComplexExpression(profiles); } + @Test + void ofComplexExpressionEnclosedInParentheses() { + Profiles profiles = Profiles.of("((spring & framework) | (spring & java))"); + assertComplexExpression(profiles); + } + private void assertComplexExpression(Profiles profiles) { assertThat(profiles.matches(activeProfiles("spring"))).isFalse(); assertThat(profiles.matches(activeProfiles("spring", "framework"))).isTrue(); @@ -291,8 +297,27 @@ class ProfilesTests { assertThat(Profiles.of("spring")).hasToString("spring"); assertThat(Profiles.of("(spring & framework) | (spring & java)")).hasToString("(spring & framework) | (spring & java)"); assertThat(Profiles.of("(spring&framework)|(spring&java)")).hasToString("(spring&framework)|(spring&java)"); - assertThat(Profiles.of("spring & framework", "java | kotlin")).hasToString("spring & framework or java | kotlin"); - assertThat(Profiles.of("java | kotlin", "spring & framework")).hasToString("java | kotlin or spring & framework"); + assertThat(Profiles.of("spring & framework", "java | kotlin")).hasToString("(spring & framework) | (java | kotlin)"); + assertThat(Profiles.of("java | kotlin", "spring & framework")).hasToString("(java | kotlin) | (spring & framework)"); + assertThat(Profiles.of("java | kotlin", "spring & framework", "cat | dog")).hasToString("(java | kotlin) | (spring & framework) | (cat | dog)"); + } + + @Test + void toStringGeneratesValidCompositeProfileExpression() { + assertThatToStringGeneratesValidCompositeProfileExpression("spring"); + assertThatToStringGeneratesValidCompositeProfileExpression("(spring & kotlin) | (spring & java)"); + assertThatToStringGeneratesValidCompositeProfileExpression("spring & kotlin", "spring & java"); + assertThatToStringGeneratesValidCompositeProfileExpression("spring & kotlin", "spring & java", "cat | dog"); + } + + private static void assertThatToStringGeneratesValidCompositeProfileExpression(String... profileExpressions) { + Profiles profiles = Profiles.of(profileExpressions); + assertThat(profiles.matches(activeProfiles("spring", "java"))).isTrue(); + assertThat(profiles.matches(activeProfiles("kotlin"))).isFalse(); + + Profiles compositeProfiles = Profiles.of(profiles.toString()); + assertThat(compositeProfiles.matches(activeProfiles("spring", "java"))).isTrue(); + assertThat(compositeProfiles.matches(activeProfiles("kotlin"))).isFalse(); } @Test