View Javadoc

1   package org.kuali.common.util.spring.env;
2   
3   import org.apache.commons.lang3.StringUtils;
4   import org.kuali.common.util.Assert;
5   import org.kuali.common.util.Mode;
6   import org.kuali.common.util.ModeUtils;
7   import org.springframework.core.env.Environment;
8   
9   /**
10   * <p>
11   * By default, an exception is thrown if a value cannot be located (unless a default value has been supplied).
12   * </p>
13   * 
14   * <p>
15   * By default, an exception is thrown if any placeholders cannot be resolved in any string values.
16   * </p>
17   * 
18   * <p>
19   * By default, environment variables are automatically checked if a normal property value cannot be found.
20   * 
21   * For example, given the key <code>db.vendor</code> the service will also automatically check <code>env.DB_VENDOR</code>
22   * </p>
23   */
24  public class DefaultEnvironmentService implements EnvironmentService {
25  
26  	public static final boolean DEFAULT_CHECK_ENVIRONMENT_VARIABLES = true;
27  	public static final boolean DEFAULT_RESOLVE_STRINGS = true;
28  	public static final Mode DEFAULT_MISSING_PROPERTY_MODE = Mode.ERROR;
29  	public static final String ENV_PREFIX = "env";
30  
31  	private final boolean checkEnvironmentVariables;
32  	private final boolean resolveStrings;
33  	private final Environment env;
34  	private final Mode missingPropertyMode;
35  
36  	public DefaultEnvironmentService(Environment env) {
37  		this(env, DEFAULT_CHECK_ENVIRONMENT_VARIABLES, DEFAULT_RESOLVE_STRINGS, DEFAULT_MISSING_PROPERTY_MODE);
38  	}
39  
40  	public DefaultEnvironmentService(Environment env, boolean checkEnvironmentVariables) {
41  		this(env, checkEnvironmentVariables, DEFAULT_RESOLVE_STRINGS, DEFAULT_MISSING_PROPERTY_MODE);
42  	}
43  
44  	public DefaultEnvironmentService(Environment env, boolean checkEnvironmentVariables, boolean resolveStrings, Mode missingPropertyMode) {
45  		Assert.noNulls(env, missingPropertyMode);
46  		this.env = env;
47  		this.missingPropertyMode = missingPropertyMode;
48  		this.checkEnvironmentVariables = checkEnvironmentVariables;
49  		this.resolveStrings = resolveStrings;
50  	}
51  
52  	@Override
53  	public boolean containsProperty(String key) {
54  		Assert.noBlanks(key);
55  		return env.containsProperty(key);
56  	}
57  
58  	@Override
59  	public <T> T getProperty(EnvContext<T> context) {
60  
61  		// If context is null, we have issues
62  		Assert.noNulls(context);
63  
64  		// Extract a value from Spring's Environment abstraction
65  		T springValue = getSpringValue(context.getKey(), context.getType());
66  
67  		// If that value is null, use whatever default value they gave us (this might also be null)
68  		T returnValue = (springValue == null) ? context.getDefaultValue() : springValue;
69  
70  		// If we could not locate a value, we may need to error out
71  		if (returnValue == null) {
72  			ModeUtils.validate(missingPropertyMode, getMissingPropertyMessage(context.getKey()));
73  		}
74  
75  		// Return the value we've located
76  		return returnValue;
77  	}
78  
79  	protected String getMissingPropertyMessage(String key) {
80  		if (checkEnvironmentVariables) {
81  			String envKey = getEnvironmentVariableKey(key);
82  			return "No value for [" + key + "] or [" + envKey + "]";
83  		} else {
84  			return "No value for [" + key + "]";
85  		}
86  	}
87  
88  	protected <T> T getSpringValue(String key, Class<T> type) {
89  		T value = env.getProperty(key, type);
90  		if (value == null && checkEnvironmentVariables) {
91  			String envKey = getEnvironmentVariableKey(key);
92  			return env.getProperty(envKey, type);
93  		} else {
94  			return value;
95  		}
96  	}
97  
98  	protected <T> Class<T> getSpringValueAsClass(String key, Class<T> type) {
99  		Class<T> value = env.getPropertyAsClass(key, type);
100 		if (value == null && checkEnvironmentVariables) {
101 			String envKey = getEnvironmentVariableKey(key);
102 			return env.getPropertyAsClass(envKey, type);
103 		} else {
104 			return value;
105 		}
106 	}
107 
108 	@Override
109 	public <T> Class<T> getClass(String key, Class<T> type) {
110 		return getClass(key, type, null);
111 	}
112 
113 	@Override
114 	public <T> Class<T> getClass(String key, Class<T> type, Class<T> defaultValue) {
115 		Class<T> springValue = getSpringValueAsClass(key, type);
116 		Class<T> returnValue = (springValue == null) ? defaultValue : springValue;
117 
118 		// If we could not locate a value, we may need to error out
119 		if (returnValue == null) {
120 			ModeUtils.validate(missingPropertyMode, getMissingPropertyMessage(key));
121 		}
122 
123 		// Return what we've got
124 		return returnValue;
125 	}
126 
127 	@Override
128 	public String getString(String key) {
129 		return getString(key, null);
130 	}
131 
132 	@Override
133 	public String getString(String key, String defaultValue) {
134 		String string = getProperty(EnvContext.newString(key, defaultValue));
135 		if (resolveStrings) {
136 			return env.resolveRequiredPlaceholders(string);
137 		} else {
138 			return string;
139 		}
140 	}
141 
142 	@Override
143 	public Boolean getBoolean(String key) {
144 		return getBoolean(key, null);
145 	}
146 
147 	@Override
148 	public Boolean getBoolean(String key, Boolean defaultValue) {
149 		return getProperty(EnvContext.newBoolean(key, defaultValue));
150 	}
151 
152 	@Override
153 	public Integer getInteger(String key, Integer defaultValue) {
154 		return getProperty(EnvContext.newInteger(key, defaultValue));
155 	}
156 
157 	@Override
158 	public Integer getInteger(String key) {
159 		return getInteger(key, null);
160 	}
161 
162 	/**
163 	 * <pre>
164 	 *  foo.bar -> env.FOO_BAR
165 	 * </pre>
166 	 */
167 	protected String getEnvironmentVariableKey(String key) {
168 		return ENV_PREFIX + "." + StringUtils.upperCase(StringUtils.replace(key, ".", "_"));
169 	}
170 
171 	public boolean isCheckEnvironmentVariables() {
172 		return checkEnvironmentVariables;
173 	}
174 
175 	public boolean isResolveStrings() {
176 		return resolveStrings;
177 	}
178 
179 	public Environment getEnv() {
180 		return env;
181 	}
182 
183 	public Mode getMissingPropertyMode() {
184 		return missingPropertyMode;
185 	}
186 
187 }