Skip to content

Commit d023b94

Browse files
committed
Introduce Environment.matchesProfiles() for profile expressions
Environment.acceptsProfiles(String...) was deprecated in 5.1 in conjunction with gh-17063 which introduced a new acceptsProfiles(Profiles) method to replace it. The deprecated method only supports OR semantics; whereas, the new method supports profile expressions. Thus, the goal was to encourage people to use the more powerful profile expressions instead of the limited OR support with profile names. However, there are use cases where it is difficult (if not impossible) to provide a Profiles instance, and there are use cases where it is simply preferable to provide profile expressions directly as strings. To address these issues, this commit introduces a new matchesProfiles() method in Environment that accepts a var-args list of profile expressions. Closes gh-30206
1 parent 47ba819 commit d023b94

File tree

2 files changed

+138
-3
lines changed

2 files changed

+138
-3
lines changed

spring-core/src/main/java/org/springframework/core/env/Environment.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
*
5858
* @author Chris Beams
5959
* @author Phillip Webb
60+
* @author Sam Brannen
6061
* @since 3.1
6162
* @see PropertyResolver
6263
* @see EnvironmentCapable
@@ -108,20 +109,42 @@ public interface Environment extends PropertyResolver {
108109
* whitespace only
109110
* @see #getActiveProfiles
110111
* @see #getDefaultProfiles
112+
* @see #matchesProfiles(String...)
111113
* @see #acceptsProfiles(Profiles)
112-
* @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)}
114+
* @deprecated as of 5.1 in favor of {@link #acceptsProfiles(Profiles)} or
115+
* {@link #matchesProfiles(String...)}
113116
*/
114117
@Deprecated
115118
boolean acceptsProfiles(String... profiles);
116119

120+
/**
121+
* Determine whether one of the given profile expressions matches the
122+
* {@linkplain #getActiveProfiles() active profiles} — or in the case
123+
* of no explicit active profiles, whether one of the given profile expressions
124+
* matches the {@linkplain #getDefaultProfiles() default profiles}.
125+
* <p>Profile expressions allow for complex, boolean profile logic to be
126+
* expressed &mdash; for example {@code "p1 & p2"}, {@code "(p1 & p2) | p3"},
127+
* etc. See {@link Profiles#of(String...)} for details on the supported
128+
* expression syntax.
129+
* <p>This method is a convenient shortcut for
130+
* {@code env.acceptsProfiles(Profiles.of(profileExpressions))}.
131+
* @since 5.3.28
132+
* @see Profiles#of(String...)
133+
* @see #acceptsProfiles(Profiles)
134+
*/
135+
default boolean matchesProfiles(String... profileExpressions) {
136+
return acceptsProfiles(Profiles.of(profileExpressions));
137+
}
138+
117139
/**
118140
* Determine whether the given {@link Profiles} predicate matches the
119141
* {@linkplain #getActiveProfiles() active profiles} &mdash; or in the case
120142
* of no explicit active profiles, whether the given {@code Profiles} predicate
121143
* matches the {@linkplain #getDefaultProfiles() default profiles}.
122-
* <p>If you wish to check a single profile expression, consider using
123-
* {@link #acceptsProfiles(String)} instead.
144+
* <p>If you wish provide profile expressions directly as strings, use
145+
* {@link #matchesProfiles(String...)} instead.
124146
* @since 5.1
147+
* @see #matchesProfiles(String...)
125148
* @see Profiles#of(String...)
126149
*/
127150
boolean acceptsProfiles(Profiles profiles);

spring-core/src/test/java/org/springframework/core/env/StandardEnvironmentTests.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,116 @@ void withProfileExpression() {
450450

451451
}
452452

453+
@Nested
454+
class MatchesProfilesTests {
455+
456+
@Test
457+
@SuppressWarnings("deprecation")
458+
void withEmptyArgumentList() {
459+
assertThatIllegalArgumentException().isThrownBy(environment::matchesProfiles);
460+
}
461+
462+
@Test
463+
@SuppressWarnings("deprecation")
464+
void withNullArgumentList() {
465+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String[]) null));
466+
}
467+
468+
@Test
469+
@SuppressWarnings("deprecation")
470+
void withNullArgument() {
471+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles((String) null));
472+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", null));
473+
}
474+
475+
@Test
476+
@SuppressWarnings("deprecation")
477+
void withEmptyArgument() {
478+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles(""));
479+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", ""));
480+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", " "));
481+
}
482+
483+
@Test
484+
@SuppressWarnings("deprecation")
485+
void withInvalidNotOperator() {
486+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1", "!"));
487+
}
488+
489+
@Test
490+
@SuppressWarnings("deprecation")
491+
void withInvalidCompoundExpressionGrouping() {
492+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 | p2 & p3"));
493+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & p2 | p3"));
494+
assertThatIllegalArgumentException().isThrownBy(() -> environment.matchesProfiles("p1 & (p2 | p3) | p4"));
495+
}
496+
497+
@Test
498+
@SuppressWarnings("deprecation")
499+
void activeProfileSetProgrammatically() {
500+
assertThat(environment.matchesProfiles("p1", "p2")).isFalse();
501+
502+
environment.setActiveProfiles("p1");
503+
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
504+
505+
environment.setActiveProfiles("p2");
506+
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
507+
508+
environment.setActiveProfiles("p1", "p2");
509+
assertThat(environment.matchesProfiles("p1", "p2")).isTrue();
510+
}
511+
512+
@Test
513+
@SuppressWarnings("deprecation")
514+
void activeProfileSetViaProperty() {
515+
assertThat(environment.matchesProfiles("p1")).isFalse();
516+
517+
environment.getPropertySources().addFirst(new MockPropertySource().withProperty(ACTIVE_PROFILES_PROPERTY_NAME, "p1"));
518+
assertThat(environment.matchesProfiles("p1")).isTrue();
519+
}
520+
521+
@Test
522+
@SuppressWarnings("deprecation")
523+
void defaultProfile() {
524+
assertThat(environment.matchesProfiles("pd")).isFalse();
525+
526+
environment.setDefaultProfiles("pd");
527+
assertThat(environment.matchesProfiles("pd")).isTrue();
528+
529+
environment.setActiveProfiles("p1");
530+
assertThat(environment.matchesProfiles("pd")).isFalse();
531+
assertThat(environment.matchesProfiles("p1")).isTrue();
532+
}
533+
534+
@Test
535+
@SuppressWarnings("deprecation")
536+
void withNotOperator() {
537+
assertThat(environment.matchesProfiles("p1")).isFalse();
538+
assertThat(environment.matchesProfiles("!p1")).isTrue();
539+
540+
environment.addActiveProfile("p1");
541+
assertThat(environment.matchesProfiles("p1")).isTrue();
542+
assertThat(environment.matchesProfiles("!p1")).isFalse();
543+
}
544+
545+
@Test
546+
void withProfileExpressions() {
547+
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();
548+
549+
environment.addActiveProfile("p1");
550+
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
551+
assertThat(environment.matchesProfiles("p1 & p2")).isFalse();
552+
553+
environment.addActiveProfile("p2");
554+
assertThat(environment.matchesProfiles("p1 & p2")).isTrue();
555+
assertThat(environment.matchesProfiles("p1 | p2")).isTrue();
556+
assertThat(environment.matchesProfiles("foo | p1", "p2")).isTrue();
557+
assertThat(environment.matchesProfiles("foo | p2", "p1")).isTrue();
558+
assertThat(environment.matchesProfiles("foo | (p2 & p1)")).isTrue();
559+
assertThat(environment.matchesProfiles("p2 & (foo | p1)")).isTrue();
560+
assertThat(environment.matchesProfiles("foo", "(p2 & p1)")).isTrue();
561+
}
562+
563+
}
564+
453565
}

0 commit comments

Comments
 (0)