View Javadoc
1   /**
2    * Copyright 2010-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.common.util.spring.env;
17  
18  import java.io.File;
19  import java.util.Properties;
20  
21  import org.kuali.common.util.Assert;
22  import org.kuali.common.util.ModeUtils;
23  import org.kuali.common.util.spring.env.model.EnvironmentServiceContext;
24  
25  /**
26   * <p>
27   * By default, an exception is thrown if a value cannot be located (unless a default value has been supplied).
28   * </p>
29   * 
30   * <p>
31   * By default, an exception is thrown if any placeholders cannot be resolved in any string values.
32   * </p>
33   * 
34   * <p>
35   * By default, string values are resolved before being returned
36   * </p>
37   * 
38   * <p>
39   * By default, environment variables are automatically checked if a normal property value cannot be found.
40   * 
41   * For example, given the key <code>db.vendor</code> the service will also automatically check <code>env.DB_VENDOR</code>
42   * </p>
43   */
44  public final class BasicEnvironmentService implements EnvironmentService {
45  
46  	private final EnvironmentServiceContext context;
47  
48  	/**
49  	 * Uses system properties / environment variables to resolve values
50  	 */
51  	public BasicEnvironmentService() {
52  		this(new EnvironmentServiceContext.Builder().build());
53  	}
54  
55  	/**
56  	 * Uses <code>properties</code> to resolve values
57  	 */
58  	public BasicEnvironmentService(Properties properties) {
59  		this(new EnvironmentServiceContext.Builder().env(properties).build());
60  	}
61  
62  	/**
63  	 * Uses <code>context</code> to resolve values
64  	 */
65  	public BasicEnvironmentService(EnvironmentServiceContext context) {
66  		Assert.noNulls(context);
67  		this.context = context;
68  	}
69  
70  	@Override
71  	public boolean containsProperty(String key) {
72  		Assert.noBlanks(key);
73  		return context.getEnv().containsProperty(key);
74  	}
75  
76  	@Override
77  	public <T> T getProperty(EnvContext<T> context) {
78  
79  		// If context is null, we have issues
80  		Assert.noNulls(context);
81  
82  		// Extract a value from Spring's Environment abstraction
83  		T springValue = getSpringValue(context.getKey(), context.getType());
84  
85  		// If that value is null, use whatever default value they gave us (this might also be null)
86  		T returnValue = (springValue == null) ? context.getDefaultValue() : springValue;
87  
88  		// If we could not locate a value, we may need to error out
89  		if (returnValue == null) {
90  			ModeUtils.validate(this.context.getMissingPropertyMode(), getMissingPropertyMessage(context.getKey()));
91  		}
92  
93  		// Return the value we've located
94  		return returnValue;
95  	}
96  
97  	@Override
98  	public <T> T getProperty(String key, Class<T> type, T provided) {
99  		return getProperty(EnvContext.newCtx(key, type, provided));
100 	}
101 
102 	@Override
103 	public <T> T getProperty(String key, Class<T> type) {
104 		return getProperty(EnvContext.newCtx(key, type, null));
105 	}
106 
107 	protected String getMissingPropertyMessage(String key) {
108 		if (context.isCheckEnvironmentVariables()) {
109 			String envKey = EnvUtils.getEnvironmentVariableKey(key);
110 			return "No value for [" + key + "] or [" + envKey + "]";
111 		} else {
112 			return "No value for [" + key + "]";
113 		}
114 	}
115 
116 	protected <T> T getSpringValue(String key, Class<T> type) {
117 		T value = context.getEnv().getProperty(key, type);
118 		if (value == null && context.isCheckEnvironmentVariables()) {
119 			String envKey = EnvUtils.getEnvironmentVariableKey(key);
120 			return context.getEnv().getProperty(envKey, type);
121 		} else {
122 			return value;
123 		}
124 	}
125 
126 	protected <T> Class<T> getSpringValueAsClass(String key, Class<T> type) {
127 		Class<T> value = context.getEnv().getPropertyAsClass(key, type);
128 		if (value == null && context.isCheckEnvironmentVariables()) {
129 			String envKey = EnvUtils.getEnvironmentVariableKey(key);
130 			return context.getEnv().getPropertyAsClass(envKey, type);
131 		} else {
132 			return value;
133 		}
134 	}
135 
136 	@Override
137 	public <T> Class<T> getClass(String key, Class<T> type) {
138 		return getClass(key, type, null);
139 	}
140 
141 	@Override
142 	public <T> Class<T> getClass(String key, Class<T> type, Class<T> defaultValue) {
143 		Class<T> springValue = getSpringValueAsClass(key, type);
144 		Class<T> returnValue = (springValue == null) ? defaultValue : springValue;
145 
146 		// If we could not locate a value, we may need to error out
147 		if (returnValue == null) {
148 			ModeUtils.validate(context.getMissingPropertyMode(), getMissingPropertyMessage(key));
149 		}
150 
151 		// Return what we've got
152 		return returnValue;
153 	}
154 
155 	@Override
156 	public String getString(String key) {
157 		return getString(key, null);
158 	}
159 
160 	@Override
161 	public String getString(String key, String defaultValue) {
162 		String string = getProperty(EnvContext.newString(key, defaultValue));
163 		if (context.isResolveStrings()) {
164 			return context.getEnv().resolveRequiredPlaceholders(string);
165 		} else {
166 			return string;
167 		}
168 	}
169 
170 	@Override
171 	public Boolean getBoolean(String key) {
172 		return getBoolean(key, null);
173 	}
174 
175 	@Override
176 	public Boolean getBoolean(String key, Boolean defaultValue) {
177 		return getProperty(EnvContext.newBoolean(key, defaultValue));
178 	}
179 
180 	@Override
181 	public File getFile(String key) {
182 		return getFile(key, null);
183 	}
184 
185 	@Override
186 	public File getFile(String key, File defaultValue) {
187 		return getProperty(EnvContext.newFile(key, defaultValue));
188 	}
189 
190 	@Override
191 	public Integer getInteger(String key, Integer defaultValue) {
192 		return getProperty(EnvContext.newInteger(key, defaultValue));
193 	}
194 
195 	@Override
196 	public Integer getInteger(String key) {
197 		return getInteger(key, null);
198 	}
199 
200 	public EnvironmentServiceContext getContext() {
201 		return context;
202 	}
203 
204 }