1 16 17 package org.springframework.beans.factory.config; 18 19 import java.util.HashSet ; 20 import java.util.Properties ; 21 import java.util.Set ; 22 23 import org.springframework.beans.BeansException; 24 import org.springframework.beans.factory.BeanDefinitionStoreException; 25 import org.springframework.beans.factory.BeanFactory; 26 import org.springframework.beans.factory.BeanFactoryAware; 27 import org.springframework.beans.factory.BeanNameAware; 28 import org.springframework.core.Constants; 29 30 92 public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer 93 implements BeanNameAware, BeanFactoryAware { 94 95 96 public static final String DEFAULT_PLACEHOLDER_PREFIX = "${"; 97 98 99 public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}"; 100 101 102 103 public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0; 104 105 109 public static final int SYSTEM_PROPERTIES_MODE_FALLBACK = 1; 110 111 115 public static final int SYSTEM_PROPERTIES_MODE_OVERRIDE = 2; 116 117 118 private static final Constants constants = new Constants(PropertyPlaceholderConfigurer.class); 119 120 private String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX; 121 122 private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX; 123 124 private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK; 125 126 private boolean searchSystemEnvironment = true; 127 128 private boolean ignoreUnresolvablePlaceholders = false; 129 130 private String beanName; 131 132 private BeanFactory beanFactory; 133 134 135 140 public void setPlaceholderPrefix(String placeholderPrefix) { 141 this.placeholderPrefix = placeholderPrefix; 142 } 143 144 149 public void setPlaceholderSuffix(String placeholderSuffix) { 150 this.placeholderSuffix = placeholderSuffix; 151 } 152 153 160 public void setSystemPropertiesModeName(String constantName) throws IllegalArgumentException { 161 this.systemPropertiesMode = constants.asNumber(constantName).intValue(); 162 } 163 164 176 public void setSystemPropertiesMode(int systemPropertiesMode) { 177 this.systemPropertiesMode = systemPropertiesMode; 178 } 179 180 198 public void setSearchSystemEnvironment(boolean searchSystemEnvironment) { 199 this.searchSystemEnvironment = searchSystemEnvironment; 200 } 201 202 206 public void setIgnoreUnresolvablePlaceholders(boolean ignoreUnresolvablePlaceholders) { 207 this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; 208 } 209 210 218 public void setBeanName(String beanName) { 219 this.beanName = beanName; 220 } 221 222 230 public void setBeanFactory(BeanFactory beanFactory) { 231 this.beanFactory = beanFactory; 232 } 233 234 235 protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) 236 throws BeansException { 237 238 BeanDefinitionVisitor visitor = new PlaceholderResolvingBeanDefinitionVisitor(props); 239 String [] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); 240 for (int i = 0; i < beanNames.length; i++) { 241 if (!(beanNames[i].equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) { 244 BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]); 245 try { 246 visitor.visitBeanDefinition(bd); 247 } 248 catch (BeanDefinitionStoreException ex) { 249 throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanNames[i], ex.getMessage()); 250 } 251 } 252 } 253 } 254 255 267 protected String parseStringValue(String strVal, Properties props, Set visitedPlaceholders) 268 throws BeanDefinitionStoreException { 269 270 StringBuffer buf = new StringBuffer (strVal); 271 272 276 int startIndex = strVal.indexOf(this.placeholderPrefix); 277 while (startIndex != -1) { 278 int endIndex = buf.toString().indexOf( 279 this.placeholderSuffix, startIndex + this.placeholderPrefix.length()); 280 if (endIndex != -1) { 281 String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex); 282 if (!visitedPlaceholders.add(placeholder)) { 283 throw new BeanDefinitionStoreException( 284 "Circular placeholder reference '" + placeholder + "' in property definitions"); 285 } 286 String propVal = resolvePlaceholder(placeholder, props, this.systemPropertiesMode); 287 if (propVal != null) { 288 propVal = parseStringValue(propVal, props, visitedPlaceholders); 291 buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); 292 if (logger.isTraceEnabled()) { 293 logger.trace("Resolved placeholder '" + placeholder + "'"); 294 } 295 startIndex = buf.toString().indexOf(this.placeholderPrefix, startIndex + propVal.length()); 296 } 297 else if (this.ignoreUnresolvablePlaceholders) { 298 startIndex = buf.toString().indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); 300 } 301 else { 302 throw new BeanDefinitionStoreException("Could not resolve placeholder '" + placeholder + "'"); 303 } 304 visitedPlaceholders.remove(placeholder); 305 } 306 else { 307 startIndex = -1; 308 } 309 } 310 311 return buf.toString(); 312 } 313 314 330 protected String resolvePlaceholder(String placeholder, Properties props, int systemPropertiesMode) { 331 String propVal = null; 332 if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) { 333 propVal = resolveSystemProperty(placeholder); 334 } 335 if (propVal == null) { 336 propVal = resolvePlaceholder(placeholder, props); 337 } 338 if (propVal == null && systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) { 339 propVal = resolveSystemProperty(placeholder); 340 } 341 return propVal; 342 } 343 344 357 protected String resolvePlaceholder(String placeholder, Properties props) { 358 return props.getProperty(placeholder); 359 } 360 361 370 protected String resolveSystemProperty(String key) { 371 try { 372 String value = System.getProperty(key); 373 if (value == null && this.searchSystemEnvironment) { 374 value = System.getenv(key); 375 } 376 return value; 377 } 378 catch (Throwable ex) { 379 if (logger.isDebugEnabled()) { 380 logger.debug("Could not access system property '" + key + "': " + ex); 381 } 382 return null; 383 } 384 } 385 386 387 392 private class PlaceholderResolvingBeanDefinitionVisitor extends BeanDefinitionVisitor { 393 394 private final Properties props; 395 396 public PlaceholderResolvingBeanDefinitionVisitor(Properties props) { 397 this.props = props; 398 } 399 400 protected String resolveStringValue(String strVal) throws BeansException { 401 return parseStringValue(strVal, this.props, new HashSet ()); 402 } 403 } 404 405 } 406 | Popular Tags |