Skip to content

Commit 71650c0

Browse files
committed
Fixed evaluation of "!" operator in case of multiple profile expressions
Issue: SPR-11093 (cherry picked from commit 6078c27)
1 parent c89985c commit 71650c0

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>
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
@@ -301,9 +301,11 @@ public boolean acceptsProfiles(String... profiles) {
301301
Assert.notEmpty(profiles, "Must specify at least one profile");
302302
for (String profile : profiles) {
303303
if (profile != null && profile.length() > 0 && profile.charAt(0) == '!') {
304-
return !isProfileActive(profile.substring(1));
304+
if (!isProfileActive(profile.substring(1))) {
305+
return true;
306+
}
305307
}
306-
if (isProfileActive(profile)) {
308+
else if (isProfileActive(profile)) {
307309
return true;
308310
}
309311
}
@@ -332,9 +334,12 @@ protected boolean isProfileActive(String profile) {
332334
* @see #setDefaultProfiles
333335
*/
334336
protected void validateProfile(String profile) {
335-
Assert.hasText(profile, "Invalid profile [" + profile + "]: must contain text");
336-
Assert.isTrue(profile.charAt(0) != '!',
337-
"Invalid profile [" + profile + "]: must not begin with the ! operator");
337+
if (!StringUtils.hasText(profile)) {
338+
throw new IllegalArgumentException("Invalid profile [" + profile + "]: must contain text");
339+
}
340+
if (profile.charAt(0) == '!') {
341+
throw new IllegalArgumentException("Invalid profile [" + profile + "]: must not begin with ! operator");
342+
}
338343
}
339344

340345
public MutablePropertySources getPropertySources() {

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>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)