View Javadoc
1   package org.kuali.common.util.spring.env;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   
5   import java.util.Map;
6   import java.util.Properties;
7   import java.util.Set;
8   
9   import org.kuali.common.util.PropertyUtils;
10  import org.kuali.common.util.log.LoggerUtils;
11  import org.slf4j.Logger;
12  import org.springframework.core.env.MapPropertySource;
13  
14  import com.google.common.collect.ImmutableSet;
15  import com.google.common.collect.Maps;
16  
17  /**
18   * <p>
19   * When {@code getProperty(name)} is called, {@code name} is checked. If no value is found, {@code name} is then converted into several aliases representing a few different ways it
20   * might be represented as an environment variable. All of the aliases are then also checked.
21   * </p>
22   * 
23   * <pre>
24   *   foo.barBaz -> env.FOO_BAR_BAZ
25   *                 FOO_BAR_BAZ
26   *                 env.foo_bar_baz
27   *                 foo_bar_baz
28   * </pre>
29   */
30  public class SysEnvPropertySource extends MapPropertySource {
31  
32  	private static final Map<String, ImmutableSet<String>> ALIAS_CACHE = Maps.newConcurrentMap();
33  	private static final String GLOBAL_PROPERTIES_PROPERTY_SOURCE_NAME = "systemPropertiesAndEnvironmentVariables";
34  	private static final Logger logger = LoggerUtils.make();
35  
36  	public SysEnvPropertySource() {
37  		this(GLOBAL_PROPERTIES_PROPERTY_SOURCE_NAME, PropertyUtils.getGlobalProperties());
38  	}
39  
40  	public SysEnvPropertySource(String name, Properties source) {
41  		this(name, convert(source));
42  	}
43  
44  	public SysEnvPropertySource(String name, Map<String, Object> source) {
45  		super(name, source);
46  	}
47  
48  	/**
49  	 * {@inheritDoc}
50  	 */
51  	@Override
52  	public Object getProperty(String name) {
53  		checkNotNull(name, "'name' cannot be null");
54  		Object value = super.getProperty(name);
55  		if (value != null) {
56  			return value;
57  		} else {
58  			Set<String> aliases = getAliases(name);
59  			return getProperty(aliases, name);
60  		}
61  	}
62  
63  	protected Object getProperty(Set<String> aliases, String original) {
64  		for (String alias : aliases) {
65  			Object value = super.getProperty(alias);
66  			if (value != null) {
67  				logger.debug(String.format("PropertySource [%s] does not contain '%s', but found equivalent '%s'", this.getName(), original, alias));
68  				return value;
69  			}
70  		}
71  		return null;
72  	}
73  
74  	/**
75  	 * <pre>
76  	 *   foo.barBaz -> env.FOO_BAR_BAZ
77  	 *                 FOO_BAR_BAZ
78  	 *                 env.foo_bar_baz
79  	 *                 foo_bar_baz
80  	 * </pre>
81  	 */
82  	protected ImmutableSet<String> getAliases(String name) {
83  		ImmutableSet<String> aliases = ALIAS_CACHE.get(name);
84  		if (aliases == null) {
85  			// foo.barBaz -> env.FOO_BAR_BAZ
86  			String env1 = EnvUtils.getEnvironmentVariableKey(name);
87  			// foo.barBaz -> FOO_BAR_BAZ
88  			String env2 = EnvUtils.toUnderscore(name).toUpperCase();
89  			// foo.barBaz -> env.foo_bar_baz
90  			String env3 = env1.toLowerCase();
91  			// foo.barBaz -> foo_bar_baz
92  			String env4 = env2.toLowerCase();
93  			aliases = ImmutableSet.of(env1, env2, env3, env4);
94  			ALIAS_CACHE.put(name, aliases);
95  		}
96  		return aliases;
97  	}
98  
99  	protected static Map<String, Object> convert(Properties properties) {
100 		Map<String, Object> map = Maps.newHashMap();
101 		for (String key : properties.stringPropertyNames()) {
102 			map.put(key, properties.getProperty(key));
103 		}
104 		return map;
105 	}
106 
107 	public void clearAliasCache() {
108 		ALIAS_CACHE.clear();
109 	}
110 
111 }