001package org.kuali.common.util.spring.env; 002 003import java.io.File; 004import java.util.Properties; 005 006import org.kuali.common.util.Assert; 007import org.kuali.common.util.ModeUtils; 008import org.kuali.common.util.spring.env.model.EnvironmentServiceContext; 009 010/** 011 * <p> 012 * By default, an exception is thrown if a value cannot be located (unless a default value has been supplied). 013 * </p> 014 * 015 * <p> 016 * By default, an exception is thrown if any placeholders cannot be resolved in any string values. 017 * </p> 018 * 019 * <p> 020 * By default, string values are resolved before being returned 021 * </p> 022 * 023 * <p> 024 * By default, environment variables are automatically checked if a normal property value cannot be found. 025 * 026 * For example, given the key <code>db.vendor</code> the service will also automatically check <code>env.DB_VENDOR</code> 027 * </p> 028 */ 029public final class BasicEnvironmentService implements EnvironmentService { 030 031 private final EnvironmentServiceContext context; 032 033 /** 034 * Uses system properties / environment variables to resolve values 035 */ 036 public BasicEnvironmentService() { 037 this(new EnvironmentServiceContext.Builder().build()); 038 } 039 040 /** 041 * Uses <code>properties</code> to resolve values 042 */ 043 public BasicEnvironmentService(Properties properties) { 044 this(new EnvironmentServiceContext.Builder().env(properties).build()); 045 } 046 047 /** 048 * Uses <code>context</code> to resolve values 049 */ 050 public BasicEnvironmentService(EnvironmentServiceContext context) { 051 Assert.noNulls(context); 052 this.context = context; 053 } 054 055 @Override 056 public boolean containsProperty(String key) { 057 Assert.noBlanks(key); 058 return context.getEnv().containsProperty(key); 059 } 060 061 @Override 062 public <T> T getProperty(EnvContext<T> context) { 063 064 // If context is null, we have issues 065 Assert.noNulls(context); 066 067 // Extract a value from Spring's Environment abstraction 068 T springValue = getSpringValue(context.getKey(), context.getType()); 069 070 // If that value is null, use whatever default value they gave us (this might also be null) 071 T returnValue = (springValue == null) ? context.getDefaultValue() : springValue; 072 073 // If we could not locate a value, we may need to error out 074 if (returnValue == null) { 075 ModeUtils.validate(this.context.getMissingPropertyMode(), getMissingPropertyMessage(context.getKey())); 076 } 077 078 // Return the value we've located 079 return returnValue; 080 } 081 082 @Override 083 public <T> T getProperty(String key, Class<T> type, T provided) { 084 return getProperty(EnvContext.newCtx(key, type, provided)); 085 } 086 087 @Override 088 public <T> T getProperty(String key, Class<T> type) { 089 return getProperty(EnvContext.newCtx(key, type, null)); 090 } 091 092 protected String getMissingPropertyMessage(String key) { 093 if (context.isCheckEnvironmentVariables()) { 094 String envKey = EnvUtils.getEnvironmentVariableKey(key); 095 return "No value for [" + key + "] or [" + envKey + "]"; 096 } else { 097 return "No value for [" + key + "]"; 098 } 099 } 100 101 protected <T> T getSpringValue(String key, Class<T> type) { 102 T value = context.getEnv().getProperty(key, type); 103 if (value == null && context.isCheckEnvironmentVariables()) { 104 String envKey = EnvUtils.getEnvironmentVariableKey(key); 105 return context.getEnv().getProperty(envKey, type); 106 } else { 107 return value; 108 } 109 } 110 111 protected <T> Class<T> getSpringValueAsClass(String key, Class<T> type) { 112 Class<T> value = context.getEnv().getPropertyAsClass(key, type); 113 if (value == null && context.isCheckEnvironmentVariables()) { 114 String envKey = EnvUtils.getEnvironmentVariableKey(key); 115 return context.getEnv().getPropertyAsClass(envKey, type); 116 } else { 117 return value; 118 } 119 } 120 121 @Override 122 public <T> Class<T> getClass(String key, Class<T> type) { 123 return getClass(key, type, null); 124 } 125 126 @Override 127 public <T> Class<T> getClass(String key, Class<T> type, Class<T> defaultValue) { 128 Class<T> springValue = getSpringValueAsClass(key, type); 129 Class<T> returnValue = (springValue == null) ? defaultValue : springValue; 130 131 // If we could not locate a value, we may need to error out 132 if (returnValue == null) { 133 ModeUtils.validate(context.getMissingPropertyMode(), getMissingPropertyMessage(key)); 134 } 135 136 // Return what we've got 137 return returnValue; 138 } 139 140 @Override 141 public String getString(String key) { 142 return getString(key, null); 143 } 144 145 @Override 146 public String getString(String key, String defaultValue) { 147 String string = getProperty(EnvContext.newString(key, defaultValue)); 148 if (context.isResolveStrings()) { 149 return context.getEnv().resolveRequiredPlaceholders(string); 150 } else { 151 return string; 152 } 153 } 154 155 @Override 156 public Boolean getBoolean(String key) { 157 return getBoolean(key, null); 158 } 159 160 @Override 161 public Boolean getBoolean(String key, Boolean defaultValue) { 162 return getProperty(EnvContext.newBoolean(key, defaultValue)); 163 } 164 165 @Override 166 public File getFile(String key) { 167 return getFile(key, null); 168 } 169 170 @Override 171 public File getFile(String key, File defaultValue) { 172 return getProperty(EnvContext.newFile(key, defaultValue)); 173 } 174 175 @Override 176 public Integer getInteger(String key, Integer defaultValue) { 177 return getProperty(EnvContext.newInteger(key, defaultValue)); 178 } 179 180 @Override 181 public Integer getInteger(String key) { 182 return getInteger(key, null); 183 } 184 185 public EnvironmentServiceContext getContext() { 186 return context; 187 } 188 189}