Skip to content

Commit 6078c27

Browse files
committed
Fixed evaluation of "!" operator in case of multiple profile expressions
Issue: SPR-11093
1 parent f707394 commit 6078c27

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

spring-beans/src/test/java/org/springframework/beans/factory/xml/ProfileXmlBeanDefinitionTests.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ public class ProfileXmlBeanDefinitionTests {
4141

4242
private static final String PROD_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-prodProfile.xml";
4343
private static final String DEV_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-devProfile.xml";
44+
private static final String NOT_DEV_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-notDevProfile.xml";
4445
private static final String ALL_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-noProfile.xml";
4546
private static final String MULTI_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-multiProfile.xml";
47+
private static final String MULTI_NOT_DEV_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-multiProfileNotDev.xml";
4648
private static final String MULTI_ELIGIBLE_SPACE_DELIMITED_XML = "ProfileXmlBeanDefinitionTests-spaceDelimitedProfile.xml";
47-
private static final String UNKOWN_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-unknownProfile.xml";
49+
private static final String UNKNOWN_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-unknownProfile.xml";
4850
private static final String DEFAULT_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-defaultProfile.xml";
4951
private static final String CUSTOM_DEFAULT_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-customDefaultProfile.xml";
5052
private static final String DEFAULT_AND_DEV_ELIGIBLE_XML = "ProfileXmlBeanDefinitionTests-defaultAndDevProfile.xml";
@@ -71,10 +73,15 @@ public void testProfilePermutations() {
7173
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
7274

7375
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, NONE_ACTIVE), not(containsTargetBean()));
74-
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, PROD_ACTIVE), not(containsTargetBean()));
7576
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, DEV_ACTIVE), containsTargetBean());
77+
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, PROD_ACTIVE), not(containsTargetBean()));
7678
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
7779

80+
assertThat(beanFactoryFor(NOT_DEV_ELIGIBLE_XML, NONE_ACTIVE), containsTargetBean());
81+
assertThat(beanFactoryFor(NOT_DEV_ELIGIBLE_XML, DEV_ACTIVE), not(containsTargetBean()));
82+
assertThat(beanFactoryFor(NOT_DEV_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
83+
assertThat(beanFactoryFor(NOT_DEV_ELIGIBLE_XML, MULTI_ACTIVE), not(containsTargetBean()));
84+
7885
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, NONE_ACTIVE), containsTargetBean());
7986
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, DEV_ACTIVE), containsTargetBean());
8087
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
@@ -86,13 +93,19 @@ public void testProfilePermutations() {
8693
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
8794
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
8895

96+
assertThat(beanFactoryFor(MULTI_NOT_DEV_ELIGIBLE_XML, NONE_ACTIVE), containsTargetBean());
97+
assertThat(beanFactoryFor(MULTI_NOT_DEV_ELIGIBLE_XML, UNKNOWN_ACTIVE), containsTargetBean());
98+
assertThat(beanFactoryFor(MULTI_NOT_DEV_ELIGIBLE_XML, DEV_ACTIVE), not(containsTargetBean()));
99+
assertThat(beanFactoryFor(MULTI_NOT_DEV_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
100+
assertThat(beanFactoryFor(MULTI_NOT_DEV_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
101+
89102
assertThat(beanFactoryFor(MULTI_ELIGIBLE_SPACE_DELIMITED_XML, NONE_ACTIVE), not(containsTargetBean()));
90103
assertThat(beanFactoryFor(MULTI_ELIGIBLE_SPACE_DELIMITED_XML, UNKNOWN_ACTIVE), not(containsTargetBean()));
91104
assertThat(beanFactoryFor(MULTI_ELIGIBLE_SPACE_DELIMITED_XML, DEV_ACTIVE), containsTargetBean());
92105
assertThat(beanFactoryFor(MULTI_ELIGIBLE_SPACE_DELIMITED_XML, PROD_ACTIVE), containsTargetBean());
93106
assertThat(beanFactoryFor(MULTI_ELIGIBLE_SPACE_DELIMITED_XML, MULTI_ACTIVE), containsTargetBean());
94107

95-
assertThat(beanFactoryFor(UNKOWN_ELIGIBLE_XML, MULTI_ACTIVE), not(containsTargetBean()));
108+
assertThat(beanFactoryFor(UNKNOWN_ELIGIBLE_XML, MULTI_ACTIVE), not(containsTargetBean()));
96109
}
97110

98111
@Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.springframework.org/schema/beans
5+
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
6+
profile="!dev,prod">
7+
8+
<bean id="foo" class="java.lang.String"/>
9+
</beans>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<beans xmlns="http://www.springframework.org/schema/beans"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://www.springframework.org/schema/beans
5+
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
6+
profile="!dev">
7+
8+
<bean id="foo" class="java.lang.String"/>
9+
</beans>

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,11 @@ public boolean acceptsProfiles(String... profiles) {
307307
Assert.notEmpty(profiles, "Must specify at least one profile");
308308
for (String profile : profiles) {
309309
if (profile != null && profile.length() > 0 && profile.charAt(0) == '!') {
310-
return !isProfileActive(profile.substring(1));
310+
if (!isProfileActive(profile.substring(1))) {
311+
return true;
312+
}
311313
}
312-
if (isProfileActive(profile)) {
314+
else if (isProfileActive(profile)) {
313315
return true;
314316
}
315317
}
@@ -338,9 +340,12 @@ protected boolean isProfileActive(String profile) {
338340
* @see #setDefaultProfiles
339341
*/
340342
protected void validateProfile(String profile) {
341-
Assert.hasText(profile, "Invalid profile [" + profile + "]: must contain text");
342-
Assert.isTrue(profile.charAt(0) != '!',
343-
"Invalid profile [" + profile + "]: must not begin with the ! operator");
343+
if (!StringUtils.hasText(profile)) {
344+
throw new IllegalArgumentException("Invalid profile [" + profile + "]: must contain text");
345+
}
346+
if (profile.charAt(0) == '!') {
347+
throw new IllegalArgumentException("Invalid profile [" + profile + "]: must not begin with ! operator");
348+
}
344349
}
345350

346351
@Override

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -77,10 +77,8 @@ public interface Environment extends PropertyResolver {
7777
* activated by setting {@linkplain AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
7878
* "spring.profiles.active"} as a system property or by calling
7979
* {@link ConfigurableEnvironment#setActiveProfiles(String...)}.
80-
*
8180
* <p>If no profiles have explicitly been specified as active, then any {@linkplain
8281
* #getDefaultProfiles() default profiles} will automatically be activated.
83-
*
8482
* @see #getDefaultProfiles
8583
* @see ConfigurableEnvironment#setActiveProfiles
8684
* @see AbstractEnvironment#ACTIVE_PROFILES_PROPERTY_NAME
@@ -90,7 +88,6 @@ public interface Environment extends PropertyResolver {
9088
/**
9189
* Return the set of profiles to be active by default when no active profiles have
9290
* been set explicitly.
93-
*
9491
* @see #getActiveProfiles
9592
* @see ConfigurableEnvironment#setDefaultProfiles
9693
* @see AbstractEnvironment#DEFAULT_PROFILES_PROPERTY_NAME
@@ -101,11 +98,11 @@ public interface Environment extends PropertyResolver {
10198
* Return whether one or more of the given profiles is active or, in the case of no
10299
* explicit active profiles, whether one or more of the given profiles is included in
103100
* the set of default profiles. If a profile begins with '!' the logic is inverted,
104-
* i.e. the method will return true if the given profile is <em>not</em> active. For
105-
* example, <pre class="code">env.acceptsProfiles("p1", "!p2")</pre> will return true if profile
106-
* 'p1' is active or 'p2' is not active.
101+
* i.e. the method will return true if the given profile is <em>not</em> active.
102+
* For example, <pre class="code">env.acceptsProfiles("p1", "!p2")</pre> will
103+
* return {@code true} if profile 'p1' is active or 'p2' is not active.
107104
* @throws IllegalArgumentException if called with zero arguments
108-
* @throws IllegalArgumentException if any profile is null, empty or whitespace-only
105+
* or if any profile is {@code null}, empty or whitespace-only
109106
* @see #getActiveProfiles
110107
* @see #getDefaultProfiles
111108
*/

0 commit comments

Comments
 (0)