Support not (!) operator for profile selection

The following syntax is now supported

  <beans profile="p1,!p2">

  @Profile("p1", "!p2")

indicating that the <beans> element or annotated component should
be processed only if profile 'p1' is active or profile 'p2' is not
active.

Issue: SPR-8728
This commit is contained in:
Chris Beams
2012-05-27 08:10:40 +03:00
parent e72c49f4cf
commit bcd44f3798
6 changed files with 115 additions and 47 deletions

View File

@@ -31,6 +31,7 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import static java.lang.String.*;
import static org.springframework.util.StringUtils.*;
/**
@@ -300,31 +301,43 @@ public abstract class AbstractEnvironment implements ConfigurableEnvironment {
public boolean acceptsProfiles(String... profiles) {
Assert.notEmpty(profiles, "Must specify at least one profile");
boolean activeProfileFound = false;
Set<String> activeProfiles = this.doGetActiveProfiles();
Set<String> defaultProfiles = this.doGetDefaultProfiles();
for (String profile : profiles) {
this.validateProfile(profile);
if (activeProfiles.contains(profile)
|| (activeProfiles.isEmpty() && defaultProfiles.contains(profile))) {
activeProfileFound = true;
break;
if (profile != null && profile.length() > 0 && profile.charAt(0) == '!') {
return !this.isProfileActive(profile.substring(1));
}
if (this.isProfileActive(profile)) {
return true;
}
}
return activeProfileFound;
return false;
}
/**
* Return whether the given profile is active, or if active profiles are empty
* whether the profile should be active by default.
* @throws IllegalArgumentException per {@link #validateProfile(String)}
* @since 3.2
*/
protected boolean isProfileActive(String profile) {
this.validateProfile(profile);
return this.doGetActiveProfiles().contains(profile)
|| (this.doGetActiveProfiles().isEmpty() && this.doGetDefaultProfiles().contains(profile));
}
/**
* Validate the given profile, called internally prior to adding to the set of
* active or default profiles.
* <p>Subclasses may override to impose further restrictions on profile syntax.
* @throws IllegalArgumentException if the profile is null, empty or whitespace-only
* @throws IllegalArgumentException if the profile is null, empty, whitespace-only or
* begins with the profile NOT operator (!).
* @see #acceptsProfiles
* @see #addActiveProfile
* @see #setDefaultProfiles
*/
protected void validateProfile(String profile) {
Assert.hasText(profile, "Invalid profile [" + profile + "]: must contain text");
Assert.isTrue(profile.charAt(0) != '!',
"Invalid profile [" + profile + "]: must not begin with the ! operator");
}
public MutablePropertySources getPropertySources() {

View File

@@ -100,7 +100,10 @@ public interface Environment extends PropertyResolver {
/**
* Return whether one or more of the given profiles is active or, in the case of no
* explicit active profiles, whether one or more of the given profiles is included in
* the set of default profiles
* the set of default profiles. If a profile begins with '!' the logic is inverted,
* i.e. the method will return true if the given profile is <em>not</em> active. For
* example, {@code env.acceptsProfiles("p1", "!p2")} will return true if profile 'p1'
* is active or 'p2' is not active.
* @throws IllegalArgumentException if called with zero arguments
* @throws IllegalArgumentException if any profile is null, empty or whitespace-only
* @see #getActiveProfiles