All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.taketoday.core.env.SystemEnvironmentPropertySource Maven / Gradle / Ivy

/*
 * Original Author -> Harry Yang ([email protected]) https://taketoday.cn
 * Copyright © TODAY & 2017 - 2021 All Rights Reserved.
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see [http://www.gnu.org/licenses/]
 */

package cn.taketoday.core.env;

import java.util.Map;

import cn.taketoday.lang.Assert;
import cn.taketoday.lang.Nullable;
import cn.taketoday.logging.Logger;
import cn.taketoday.logging.LoggerFactory;

/**
 * Specialization of {@link MapPropertySource} designed for use with
 * {@linkplain AbstractEnvironment#getSystemEnvironment() system environment variables}.
 * Compensates for constraints in Bash and other shells that do not allow for variables
 * containing the period character and/or hyphen character; also allows for uppercase
 * variations on property names for more idiomatic shell use.
 *
 * 

For example, a call to {@code getProperty("foo.bar")} will attempt to find a value * for the original property or any 'equivalent' property, returning the first found: *

    *
  • {@code foo.bar} - the original name
  • *
  • {@code foo_bar} - with underscores for periods (if any)
  • *
  • {@code FOO.BAR} - original, with upper case
  • *
  • {@code FOO_BAR} - with underscores and upper case
  • *
* Any hyphen variant of the above would work as well, or even mix dot/hyphen variants. * *

The same applies for calls to {@link #containsProperty(String)}, which returns * {@code true} if any of the above properties are present, otherwise {@code false}. * *

This feature is particularly useful when specifying active or default profiles as * environment variables. The following is not allowable under Bash: * *

context.profiles.active=p1 java -classpath ... MyApp
* * However, the following syntax is permitted and is also more conventional: * *
CONTEXT_PROFILES_ACTIVE=p1 java -classpath ... MyApp
* *

Enable debug- or trace-level logging for this class (or package) for messages * explaining when these 'property name resolutions' occur. * *

This property source is included by default in {@link StandardEnvironment} * and all its subclasses. * * @author Chris Beams * @author Juergen Hoeller * @see StandardEnvironment * @see AbstractEnvironment#getSystemEnvironment() * @see AbstractEnvironment#KEY_ACTIVE_PROFILES * @since 4.0 */ public class SystemEnvironmentPropertySource extends MapPropertySource { private static final Logger log = LoggerFactory.getLogger(SystemEnvironmentPropertySource.class); /** * Create a new {@code SystemEnvironmentPropertySource} with the given name and * delegating to the given {@code MapPropertySource}. */ public SystemEnvironmentPropertySource(String name, Map source) { super(name, source); } /** * Return {@code true} if a property with the given name or any underscore/uppercase variant * thereof exists in this property source. */ @Override public boolean containsProperty(String name) { return getProperty(name) != null; } /** * This implementation returns {@code true} if a property with the given name or * any underscore/uppercase variant thereof exists in this property source. */ @Override @Nullable public Object getProperty(String name) { String actualName = resolvePropertyName(name); if (log.isDebugEnabled() && !name.equals(actualName)) { log.debug("PropertySource '{}' does not contain property '{}', but found equivalent '{}'", getName(), name, actualName); } return super.getProperty(actualName); } /** * Check to see if this property source contains a property with the given name, or * any underscore / uppercase variation thereof. Return the resolved name if one is * found or otherwise the original name. Never returns {@code null}. */ protected final String resolvePropertyName(String name) { Assert.notNull(name, "Property name must not be null"); String resolvedName = checkPropertyName(name); if (resolvedName != null) { return resolvedName; } String uppercasedName = name.toUpperCase(); if (!name.equals(uppercasedName)) { resolvedName = checkPropertyName(uppercasedName); if (resolvedName != null) { return resolvedName; } } return name; } @Nullable private String checkPropertyName(String name) { // Check name as-is if (this.source.containsKey(name)) { return name; } // Check name with just dots replaced String noDotName = name.replace('.', '_'); if (!name.equals(noDotName) && this.source.containsKey(noDotName)) { return noDotName; } // Check name with just hyphens replaced String noHyphenName = name.replace('-', '_'); if (!name.equals(noHyphenName) && this.source.containsKey(noHyphenName)) { return noHyphenName; } // Check name with dots and hyphens replaced String noDotNoHyphenName = noDotName.replace('-', '_'); if (!noDotName.equals(noDotNoHyphenName) && this.source.containsKey(noDotNoHyphenName)) { return noDotNoHyphenName; } // Give up return null; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy