001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.common.util.spring.env; 017 018import java.io.File; 019import java.util.Properties; 020 021import org.kuali.common.util.Assert; 022import org.kuali.common.util.ModeUtils; 023import org.kuali.common.util.spring.env.model.EnvironmentServiceContext; 024 025/** 026 * <p> 027 * By default, an exception is thrown if a value cannot be located (unless a default value has been supplied). 028 * </p> 029 * 030 * <p> 031 * By default, an exception is thrown if any placeholders cannot be resolved in any string values. 032 * </p> 033 * 034 * <p> 035 * By default, string values are resolved before being returned 036 * </p> 037 * 038 * <p> 039 * By default, environment variables are automatically checked if a normal property value cannot be found. 040 * 041 * For example, given the key <code>db.vendor</code> the service will also automatically check <code>env.DB_VENDOR</code> 042 * </p> 043 */ 044public final class BasicEnvironmentService implements EnvironmentService { 045 046 private final EnvironmentServiceContext context; 047 048 /** 049 * Uses system properties / environment variables to resolve values 050 */ 051 public BasicEnvironmentService() { 052 this(new EnvironmentServiceContext.Builder().build()); 053 } 054 055 /** 056 * Uses <code>properties</code> to resolve values 057 */ 058 public BasicEnvironmentService(Properties properties) { 059 this(new EnvironmentServiceContext.Builder().env(properties).build()); 060 } 061 062 /** 063 * Uses <code>context</code> to resolve values 064 */ 065 public BasicEnvironmentService(EnvironmentServiceContext context) { 066 Assert.noNulls(context); 067 this.context = context; 068 } 069 070 @Override 071 public boolean containsProperty(String key) { 072 Assert.noBlanks(key); 073 return context.getEnv().containsProperty(key); 074 } 075 076 @Override 077 public <T> T getProperty(EnvContext<T> context) { 078 079 // If context is null, we have issues 080 Assert.noNulls(context); 081 082 // Extract a value from Spring's Environment abstraction 083 T springValue = getSpringValue(context.getKey(), context.getType()); 084 085 // If that value is null, use whatever default value they gave us (this might also be null) 086 T returnValue = (springValue == null) ? context.getDefaultValue() : springValue; 087 088 // If we could not locate a value, we may need to error out 089 if (returnValue == null) { 090 ModeUtils.validate(this.context.getMissingPropertyMode(), getMissingPropertyMessage(context.getKey())); 091 } 092 093 // Return the value we've located 094 return returnValue; 095 } 096 097 @Override 098 public <T> T getProperty(String key, Class<T> type, T provided) { 099 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}