001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 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 */ 016 017package org.springframework.boot.context.properties.bind; 018 019import org.springframework.core.env.ConfigurableEnvironment; 020import org.springframework.core.env.Environment; 021import org.springframework.core.env.PropertySource; 022import org.springframework.core.env.PropertySources; 023import org.springframework.util.Assert; 024import org.springframework.util.PropertyPlaceholderHelper; 025import org.springframework.util.SystemPropertyUtils; 026 027/** 028 * {@link PlaceholdersResolver} to resolve placeholders from {@link PropertySources}. 029 * 030 * @author Phillip Webb 031 * @author Madhura Bhave 032 * @since 2.0.0 033 */ 034public class PropertySourcesPlaceholdersResolver implements PlaceholdersResolver { 035 036 private final Iterable<PropertySource<?>> sources; 037 038 private final PropertyPlaceholderHelper helper; 039 040 public PropertySourcesPlaceholdersResolver(Environment environment) { 041 this(getSources(environment), null); 042 } 043 044 public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources) { 045 this(sources, null); 046 } 047 048 public PropertySourcesPlaceholdersResolver(Iterable<PropertySource<?>> sources, 049 PropertyPlaceholderHelper helper) { 050 this.sources = sources; 051 this.helper = (helper != null) ? helper 052 : new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX, 053 SystemPropertyUtils.PLACEHOLDER_SUFFIX, 054 SystemPropertyUtils.VALUE_SEPARATOR, true); 055 } 056 057 @Override 058 public Object resolvePlaceholders(Object value) { 059 if (value != null && value instanceof String) { 060 return this.helper.replacePlaceholders((String) value, 061 this::resolvePlaceholder); 062 } 063 return value; 064 } 065 066 protected String resolvePlaceholder(String placeholder) { 067 if (this.sources != null) { 068 for (PropertySource<?> source : this.sources) { 069 Object value = source.getProperty(placeholder); 070 if (value != null) { 071 return String.valueOf(value); 072 } 073 } 074 } 075 return null; 076 } 077 078 private static PropertySources getSources(Environment environment) { 079 Assert.notNull(environment, "Environment must not be null"); 080 Assert.isInstanceOf(ConfigurableEnvironment.class, environment, 081 "Environment must be a ConfigurableEnvironment"); 082 return ((ConfigurableEnvironment) environment).getPropertySources(); 083 } 084 085}