View Javadoc

1   /**
2    * Copyright 2010-2012 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.property;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Properties;
21  
22  import org.apache.commons.lang3.StringUtils;
23  import org.jasypt.util.text.TextEncryptor;
24  import org.kuali.common.util.EncUtils;
25  import org.kuali.common.util.EncryptionStrength;
26  import org.kuali.common.util.PropertyUtils;
27  import org.kuali.common.util.property.processor.AddEnvPropertiesProcessor;
28  import org.kuali.common.util.property.processor.AddPrefixProcessor;
29  import org.kuali.common.util.property.processor.AddPropertiesProcessor;
30  import org.kuali.common.util.property.processor.AddSystemPropertiesProcessor;
31  import org.kuali.common.util.property.processor.EndsWithDecryptProcessor;
32  import org.kuali.common.util.property.processor.EndsWithEncryptProcessor;
33  import org.kuali.common.util.property.processor.GlobalOverrideProcessor;
34  import org.kuali.common.util.property.processor.HomeProcessor;
35  import org.kuali.common.util.property.processor.OrgProcessor;
36  import org.kuali.common.util.property.processor.PathProcessor;
37  import org.kuali.common.util.property.processor.PropertyProcessor;
38  import org.kuali.common.util.property.processor.ReformatKeysAsEnvVarsProcessor;
39  import org.kuali.common.util.property.processor.ResolvePlaceholdersProcessor;
40  import org.kuali.common.util.property.processor.TrimProcessor;
41  import org.kuali.common.util.property.processor.VersionProcessor;
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  import org.springframework.util.Assert;
45  import org.springframework.util.CollectionUtils;
46  import org.springframework.util.PropertyPlaceholderHelper;
47  
48  public class DefaultPropertyContext implements PropertyContext {
49  
50  	private static final Logger logger = LoggerFactory.getLogger(DefaultPropertyContext.class);
51  
52  	String encoding;
53  	List<String> includes;
54  	List<String> excludes;
55  	boolean addEnvironmentVariables;
56  	boolean addSystemProperties;
57  	boolean resolvePlaceholders;
58  	String prefix;
59  	PropertyStyle style = PropertyStyle.NORMAL;
60  	PropertyPlaceholderHelper helper = Constants.DEFAULT_PROPERTY_PLACEHOLDER_HELPER;
61  	PropertyEncryptionMode encryptionMode = PropertyEncryptionMode.NONE;
62  	EncryptionStrength encryptionStrength = EncryptionStrength.BASIC;
63  	String encryptionPassword;
64  	List<PropertyProcessor> processors;
65  	List<String> pathProperties;
66  	List<String> versionProperties;
67  	Properties properties;
68  	GlobalPropertiesMode globalPropertiesOverrideMode = GlobalPropertiesMode.BOTH;
69  	String orgGroupIdKey;
70  	String projectGroupIdKey;
71  
72  	protected List<PropertyProcessor> getDefaultProcessors() {
73  		List<PropertyProcessor> defaultProcessors = new ArrayList<PropertyProcessor>();
74  
75  		if (properties != null) {
76  			defaultProcessors.add(new AddPropertiesProcessor(properties));
77  		}
78  
79  		if (addEnvironmentVariables) {
80  			defaultProcessors.add(new AddEnvPropertiesProcessor());
81  		}
82  
83  		if (addSystemProperties) {
84  			defaultProcessors.add(new AddSystemPropertiesProcessor());
85  		}
86  
87  		if (!CollectionUtils.isEmpty(pathProperties)) {
88  			defaultProcessors.add(new PathProcessor(pathProperties));
89  		}
90  
91  		if (!CollectionUtils.isEmpty(versionProperties)) {
92  			defaultProcessors.add(new VersionProcessor(versionProperties));
93  		}
94  
95  		if (orgGroupIdKey != null && projectGroupIdKey != null) {
96  			defaultProcessors.add(new OrgProcessor(orgGroupIdKey, projectGroupIdKey));
97  			defaultProcessors.add(new HomeProcessor(orgGroupIdKey, projectGroupIdKey, globalPropertiesOverrideMode));
98  		}
99  
100 		addEncModifier(defaultProcessors);
101 
102 		// Make sure system/environment properties override everything else
103 		if (globalPropertiesOverrideMode != null) {
104 			defaultProcessors.add(new GlobalOverrideProcessor(globalPropertiesOverrideMode));
105 		}
106 
107 		// At this point no further properties will be added so we are safe to resolve place holders
108 		if (resolvePlaceholders) {
109 			Assert.notNull(helper, "helper is null");
110 			defaultProcessors.add(new ResolvePlaceholdersProcessor(helper));
111 		}
112 
113 		if (!StringUtils.isBlank(prefix)) {
114 			defaultProcessors.add(new AddPrefixProcessor(prefix));
115 		}
116 
117 		addStyleModifier(defaultProcessors);
118 
119 		boolean trim = !CollectionUtils.isEmpty(includes) || !CollectionUtils.isEmpty(excludes);
120 		if (trim) {
121 			defaultProcessors.add(new TrimProcessor(includes, excludes));
122 		}
123 
124 		return defaultProcessors;
125 	}
126 
127 	protected void addStyleModifier(List<PropertyProcessor> defaultProcessors) {
128 		if (style == null) {
129 			return;
130 		}
131 		switch (style) {
132 		case NORMAL:
133 			return;
134 		case ENVIRONMENT_VARIABLE:
135 			defaultProcessors.add(new ReformatKeysAsEnvVarsProcessor());
136 			return;
137 		default:
138 			throw new IllegalArgumentException(style + " is unknown");
139 		}
140 	}
141 
142 	protected void addEncModifier(List<PropertyProcessor> defaultProcessors) {
143 		if (encryptionMode == null) {
144 			return;
145 		}
146 		switch (encryptionMode) {
147 		case NONE:
148 			return;
149 		case ENCRYPT:
150 			TextEncryptor encryptor = EncUtils.getTextEncryptor(encryptionStrength, encryptionPassword);
151 			defaultProcessors.add(new EndsWithEncryptProcessor(encryptor));
152 			return;
153 		case DECRYPT:
154 			TextEncryptor decryptor = EncUtils.getTextEncryptor(encryptionStrength, encryptionPassword);
155 			defaultProcessors.add(new EndsWithDecryptProcessor(decryptor));
156 			return;
157 		default:
158 			throw new IllegalArgumentException("Encryption mode '" + encryptionMode + "' is unknown");
159 		}
160 	}
161 
162 	@Override
163 	public void initialize(Properties properties) {
164 		Properties global = PropertyUtils.getProperties(properties, globalPropertiesOverrideMode);
165 		resolveInternalStrings(global);
166 		List<PropertyProcessor> defaultProcessors = getDefaultProcessors();
167 		if (this.processors == null) {
168 			this.processors = defaultProcessors;
169 		} else {
170 			this.processors.addAll(0, defaultProcessors);
171 		}
172 	}
173 
174 	protected void resolveInternalStrings(Properties properties) {
175 		if (helper == null) {
176 			return;
177 		}
178 
179 		String newPrefix = getResolvedString(properties, this.prefix);
180 		if (!StringUtils.equals(newPrefix, this.prefix)) {
181 			logger.info("Resolved prefix [{}]->[{}]", this.prefix, newPrefix);
182 			this.prefix = newPrefix;
183 		}
184 
185 		String newEncryptionPassword = getResolvedString(properties, this.encryptionPassword);
186 		if (!StringUtils.equals(newEncryptionPassword, this.encryptionPassword)) {
187 			logger.info("Resolved encryption password");
188 			this.encryptionPassword = newEncryptionPassword;
189 		}
190 		resolveInternalList(properties, pathProperties);
191 		resolveInternalList(properties, versionProperties);
192 		resolveInternalList(properties, includes);
193 		resolveInternalList(properties, excludes);
194 	}
195 
196 	protected void resolveInternalList(Properties properties, List<String> list) {
197 		if (list == null) {
198 			return;
199 		}
200 		for (int i = 0; i < list.size(); i++) {
201 			String original = list.get(i);
202 			String resolved = helper.replacePlaceholders(original, properties);
203 			if (!StringUtils.equals(original, resolved)) {
204 				logger.info("Resolved [{}] -> [{}]", original, resolved);
205 				list.set(i, resolved);
206 			}
207 		}
208 	}
209 
210 	protected String getResolvedString(Properties properties, String original) {
211 		if (original == null) {
212 			return null;
213 		} else {
214 			return helper.replacePlaceholders(original, properties);
215 		}
216 	}
217 
218 	@Override
219 	public String getEncoding() {
220 		return encoding;
221 	}
222 
223 	public void setEncoding(String encoding) {
224 		this.encoding = encoding;
225 	}
226 
227 	public List<String> getIncludes() {
228 		return includes;
229 	}
230 
231 	public void setIncludes(List<String> includes) {
232 		this.includes = includes;
233 	}
234 
235 	public List<String> getExcludes() {
236 		return excludes;
237 	}
238 
239 	public void setExcludes(List<String> excludes) {
240 		this.excludes = excludes;
241 	}
242 
243 	public boolean isAddEnvironmentVariables() {
244 		return addEnvironmentVariables;
245 	}
246 
247 	public void setAddEnvironmentVariables(boolean includeEnvironmentVariables) {
248 		this.addEnvironmentVariables = includeEnvironmentVariables;
249 	}
250 
251 	public boolean isAddSystemProperties() {
252 		return addSystemProperties;
253 	}
254 
255 	public void setAddSystemProperties(boolean includeSystemProperties) {
256 		this.addSystemProperties = includeSystemProperties;
257 	}
258 
259 	public boolean isResolvePlaceholders() {
260 		return resolvePlaceholders;
261 	}
262 
263 	public void setResolvePlaceholders(boolean resolvePlaceholders) {
264 		this.resolvePlaceholders = resolvePlaceholders;
265 	}
266 
267 	public String getPrefix() {
268 		return prefix;
269 	}
270 
271 	public void setPrefix(String prefix) {
272 		this.prefix = prefix;
273 	}
274 
275 	public PropertyStyle getStyle() {
276 		return style;
277 	}
278 
279 	public void setStyle(PropertyStyle style) {
280 		this.style = style;
281 	}
282 
283 	public PropertyPlaceholderHelper getHelper() {
284 		return helper;
285 	}
286 
287 	public void setHelper(PropertyPlaceholderHelper helper) {
288 		this.helper = helper;
289 	}
290 
291 	public PropertyEncryptionMode getEncryptionMode() {
292 		return encryptionMode;
293 	}
294 
295 	public void setEncryptionMode(PropertyEncryptionMode encryptionMode) {
296 		this.encryptionMode = encryptionMode;
297 	}
298 
299 	public EncryptionStrength getEncryptionStrength() {
300 		return encryptionStrength;
301 	}
302 
303 	public void setEncryptionStrength(EncryptionStrength encryptionStrength) {
304 		this.encryptionStrength = encryptionStrength;
305 	}
306 
307 	public String getEncryptionPassword() {
308 		return encryptionPassword;
309 	}
310 
311 	public void setEncryptionPassword(String encryptionPassword) {
312 		this.encryptionPassword = encryptionPassword;
313 	}
314 
315 	@Override
316 	public List<PropertyProcessor> getProcessors() {
317 		return processors;
318 	}
319 
320 	public void setProcessors(List<PropertyProcessor> modifiers) {
321 		this.processors = modifiers;
322 	}
323 
324 	public List<String> getPathProperties() {
325 		return pathProperties;
326 	}
327 
328 	public void setPathProperties(List<String> pathProperties) {
329 		this.pathProperties = pathProperties;
330 	}
331 
332 	public List<String> getVersionProperties() {
333 		return versionProperties;
334 	}
335 
336 	public void setVersionProperties(List<String> versionProperties) {
337 		this.versionProperties = versionProperties;
338 	}
339 
340 	public Properties getProperties() {
341 		return properties;
342 	}
343 
344 	public void setProperties(Properties properties) {
345 		this.properties = properties;
346 	}
347 
348 	public GlobalPropertiesMode getGlobalPropertiesOverrideMode() {
349 		return globalPropertiesOverrideMode;
350 	}
351 
352 	public void setGlobalPropertiesOverrideMode(GlobalPropertiesMode globalPropertiesOverrideMode) {
353 		this.globalPropertiesOverrideMode = globalPropertiesOverrideMode;
354 	}
355 
356 	public String getOrgGroupIdKey() {
357 		return orgGroupIdKey;
358 	}
359 
360 	public void setOrgGroupIdKey(String orgGroupIdKey) {
361 		this.orgGroupIdKey = orgGroupIdKey;
362 	}
363 
364 	public String getProjectGroupIdKey() {
365 		return projectGroupIdKey;
366 	}
367 
368 	public void setProjectGroupIdKey(String projectGroupIdKey) {
369 		this.projectGroupIdKey = projectGroupIdKey;
370 	}
371 
372 }