Skip to content

Commit c0eeb8b

Browse files
committed
Introduce AbstractEnvironment#validateProfile
Consolidates validation for profiles and provides a mechanism for AbstractEnvironment subclasses to customize validation logic if desired.
1 parent e19a2e7 commit c0eeb8b

File tree

4 files changed

+111
-17
lines changed

4 files changed

+111
-17
lines changed

org.springframework.core/src/main/java/org/springframework/core/env/AbstractEnvironment.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
package org.springframework.core.env;
1818

1919
import static java.lang.String.format;
20-
import static org.springframework.util.StringUtils.commaDelimitedListToSet;
20+
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
2121
import static org.springframework.util.StringUtils.trimAllWhitespace;
2222

2323
import java.security.AccessControlException;
24-
import java.util.Arrays;
2524
import java.util.Collections;
2625
import java.util.LinkedHashSet;
2726
import java.util.Map;
@@ -182,7 +181,7 @@ protected Set<String> doGetActiveProfiles() {
182181
if (this.activeProfiles.isEmpty()) {
183182
String profiles = this.propertyResolver.getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
184183
if (StringUtils.hasText(profiles)) {
185-
this.activeProfiles = commaDelimitedListToSet(trimAllWhitespace(profiles));
184+
setActiveProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles)));
186185
}
187186
}
188187
return this.activeProfiles;
@@ -211,9 +210,9 @@ public String[] getDefaultProfiles() {
211210
*/
212211
protected Set<String> doGetDefaultProfiles() {
213212
if (this.defaultProfiles.equals(this.getReservedDefaultProfiles())) {
214-
String defaultProfiles = this.propertyResolver.getProperty(DEFAULT_PROFILES_PROPERTY_NAME);
215-
if (defaultProfiles != null) {
216-
this.defaultProfiles = commaDelimitedListToSet(trimAllWhitespace(defaultProfiles));
213+
String profiles = this.propertyResolver.getProperty(DEFAULT_PROFILES_PROPERTY_NAME);
214+
if (StringUtils.hasText(profiles)) {
215+
this.setDefaultProfiles(commaDelimitedListToStringArray(trimAllWhitespace(profiles)));
217216
}
218217
}
219218
return this.defaultProfiles;
@@ -228,7 +227,10 @@ protected Set<String> doGetDefaultProfiles() {
228227
*/
229228
public void setDefaultProfiles(String... profiles) {
230229
this.defaultProfiles.clear();
231-
this.defaultProfiles.addAll(Arrays.asList(profiles));
230+
for (String profile : profiles) {
231+
this.validateProfile(profile);
232+
this.defaultProfiles.add(profile);
233+
}
232234
}
233235

234236
public boolean acceptsProfiles(String... profiles) {
@@ -237,7 +239,7 @@ public boolean acceptsProfiles(String... profiles) {
237239
Set<String> activeProfiles = this.doGetActiveProfiles();
238240
Set<String> defaultProfiles = this.doGetDefaultProfiles();
239241
for (String profile : profiles) {
240-
Assert.hasText(profile, "profile must not be empty");
242+
this.validateProfile(profile);
241243
if (activeProfiles.contains(profile)
242244
|| (activeProfiles.isEmpty() && defaultProfiles.contains(profile))) {
243245
activeProfileFound = true;
@@ -247,6 +249,18 @@ public boolean acceptsProfiles(String... profiles) {
247249
return activeProfileFound;
248250
}
249251

252+
/**
253+
* Validate the given profile, called internally prior to adding to the set of
254+
* active or default profiles.
255+
* <p>Subclasses may override to impose further restrictions on profile syntax.
256+
* @throws IllegalArgumentException if the profile is null, empty or whitespace-only
257+
* @see #acceptsProfiles
258+
* @see #setDefaultProfiles
259+
*/
260+
protected void validateProfile(String profile) {
261+
Assert.hasText(profile, "Invalid profile [" + profile + "]: must contain text");
262+
}
263+
250264
public MutablePropertySources getPropertySources() {
251265
return this.propertySources;
252266
}

org.springframework.core/src/main/java/org/springframework/core/env/ConfigurableEnvironment.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,21 @@ public interface ConfigurableEnvironment extends Environment, ConfigurableProper
3434
* Specify the set of profiles active for this {@code Environment}. Profiles are
3535
* evaluated during container bootstrap to determine whether bean definitions
3636
* should be registered with the container.
37+
* <p>Any existing active profiles will be replaced with the given arguments; call
38+
* with zero arguments to clear the current set of active profiles.
3739
*
3840
* @see #setDefaultProfiles
3941
* @see org.springframework.context.annotation.Profile
4042
* @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
43+
* @throws IllegalArgumentException if any profile is null, empty or whitespace-only
4144
*/
4245
void setActiveProfiles(String... profiles);
4346

4447
/**
4548
* Specify the set of profiles to be made active by default if no other profiles
4649
* are explicitly made active through {@link #setActiveProfiles}.
4750
* @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME
51+
* @throws IllegalArgumentException if any profile is null, empty or whitespace-only
4852
*/
4953
void setDefaultProfiles(String... profiles);
5054

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,11 @@ public interface Environment extends PropertyResolver {
9797
String[] getDefaultProfiles();
9898

9999
/**
100-
* @return whether one or more of the given profiles is active, or in the case of no
100+
* Return whether one or more of the given profiles is active or, in the case of no
101101
* explicit active profiles, whether one or more of the given profiles is included in
102102
* the set of default profiles
103-
* @throws IllegalArgumentException unless at least one profile has been specified
104-
* @throws IllegalArgumentException if any profile is the empty string or consists
105-
* only of whitespace
103+
* @throws IllegalArgumentException if called with zero arguments
104+
* @throws IllegalArgumentException if any profile is null, empty or whitespace-only
106105
* @see #getActiveProfiles
107106
* @see #getDefaultProfiles
108107
*/

org.springframework.core/src/test/java/org/springframework/core/env/EnvironmentTests.java

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,54 @@ public void propertySourceOrder() {
7272
}
7373

7474
@Test
75-
public void activeProfiles() {
75+
public void activeProfilesIsEmptyByDefault() {
7676
assertThat(environment.getActiveProfiles().length, is(0));
77+
}
78+
79+
@Test
80+
public void defaultProfilesContainsDefaultProfileByDefault() {
81+
assertThat(environment.getDefaultProfiles().length, is(1));
82+
assertThat(environment.getDefaultProfiles()[0], equalTo("default"));
83+
}
84+
85+
@Test
86+
public void setActiveProfiles() {
7787
environment.setActiveProfiles("local", "embedded");
7888
String[] activeProfiles = environment.getActiveProfiles();
7989
assertThat(Arrays.asList(activeProfiles), hasItems("local", "embedded"));
8090
assertThat(activeProfiles.length, is(2));
8191
}
8292

93+
@Test(expected=IllegalArgumentException.class)
94+
public void setActiveProfiles_withNullProfileArray() {
95+
environment.setActiveProfiles((String[])null);
96+
}
97+
98+
@Test(expected=IllegalArgumentException.class)
99+
public void setActiveProfiles_withNullProfile() {
100+
environment.setActiveProfiles((String)null);
101+
}
102+
103+
@Test(expected=IllegalArgumentException.class)
104+
public void setActiveProfiles_withEmptyProfile() {
105+
environment.setActiveProfiles("");
106+
}
107+
108+
@Test(expected=IllegalArgumentException.class)
109+
public void setDefaultProfiles_withNullProfileArray() {
110+
environment.setDefaultProfiles((String[])null);
111+
}
112+
113+
@Test(expected=IllegalArgumentException.class)
114+
public void setDefaultProfiles_withNullProfile() {
115+
environment.setDefaultProfiles((String)null);
116+
}
117+
118+
@Test(expected=IllegalArgumentException.class)
119+
public void setDefaultProfiles_withEmptyProfile() {
120+
environment.setDefaultProfiles("");
121+
}
122+
83123
@Test
84124
public void reservedDefaultProfile() {
85125
assertThat(environment.getDefaultProfiles(), equalTo(new String[]{RESERVED_DEFAULT_PROFILE_NAME}));
@@ -100,23 +140,20 @@ public void getActiveProfiles_systemPropertiesEmpty() {
100140

101141
@Test
102142
public void getActiveProfiles_fromSystemProperties() {
103-
assertThat(environment.getActiveProfiles().length, is(0));
104143
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo");
105144
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItem("foo"));
106145
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME);
107146
}
108147

109148
@Test
110149
public void getActiveProfiles_fromSystemProperties_withMultipleProfiles() {
111-
assertThat(environment.getActiveProfiles().length, is(0));
112150
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "foo,bar");
113151
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItems("foo", "bar"));
114152
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME);
115153
}
116154

117155
@Test
118156
public void getActiveProfiles_fromSystemProperties_withMulitpleProfiles_withWhitespace() {
119-
assertThat(environment.getActiveProfiles().length, is(0));
120157
System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, " bar , baz "); // notice whitespace
121158
assertThat(Arrays.asList(environment.getActiveProfiles()), hasItems("bar", "baz"));
122159
System.getProperties().remove(ACTIVE_PROFILES_PROPERTY_NAME);
@@ -142,10 +179,26 @@ public void setDefaultProfiles() {
142179
}
143180

144181
@Test(expected=IllegalArgumentException.class)
145-
public void acceptsProfiles_mustSpecifyAtLeastOne() {
182+
public void acceptsProfiles_withEmptyArgumentList() {
146183
environment.acceptsProfiles();
147184
}
148185

186+
@Test(expected=IllegalArgumentException.class)
187+
public void acceptsProfiles_withNullArgumentList() {
188+
environment.acceptsProfiles((String[])null);
189+
}
190+
191+
@Test(expected=IllegalArgumentException.class)
192+
public void acceptsProfiles_withNullArgument() {
193+
environment.acceptsProfiles((String)null);
194+
}
195+
196+
@Test(expected=IllegalArgumentException.class)
197+
public void acceptsProfiles_withEmptyArgument() {
198+
environment.acceptsProfiles("");
199+
}
200+
201+
149202
@Test
150203
public void acceptsProfiles_activeProfileSetProgrammatically() {
151204
assertThat(environment.acceptsProfiles("p1", "p2"), is(false));
@@ -174,6 +227,30 @@ public void acceptsProfiles_defaultProfile() {
174227
assertThat(environment.acceptsProfiles("p1"), is(true));
175228
}
176229

230+
@Test
231+
public void environmentSubclass_withCustomProfileValidation() {
232+
ConfigurableEnvironment env = new AbstractEnvironment() {
233+
@Override
234+
protected void validateProfile(String profile) {
235+
super.validateProfile(profile);
236+
if (profile.contains("-")) {
237+
throw new IllegalArgumentException(
238+
"Invalid profile [" + profile + "]: must not contain dash character");
239+
}
240+
}
241+
};
242+
243+
env.addActiveProfile("validProfile"); // succeeds
244+
245+
try {
246+
env.addActiveProfile("invalid-profile");
247+
fail("expected validation exception");
248+
} catch (IllegalArgumentException ex) {
249+
assertThat(ex.getMessage(),
250+
equalTo("Invalid profile [invalid-profile]: must not contain dash character"));
251+
}
252+
}
253+
177254
@Test
178255
public void getSystemProperties_withAndWithoutSecurityManager() {
179256
System.setProperty(ALLOWED_PROPERTY_NAME, ALLOWED_PROPERTY_VALUE);

0 commit comments

Comments
 (0)