001    package org.kuali.common.util.spring;
002    
003    import java.util.ArrayList;
004    import java.util.Collections;
005    import java.util.Iterator;
006    import java.util.List;
007    import java.util.Properties;
008    
009    import org.kuali.common.util.PropertyUtils;
010    import org.slf4j.Logger;
011    import org.slf4j.LoggerFactory;
012    import org.springframework.core.env.ConfigurableEnvironment;
013    import org.springframework.core.env.EnumerablePropertySource;
014    import org.springframework.core.env.Environment;
015    import org.springframework.core.env.MutablePropertySources;
016    import org.springframework.core.env.PropertySource;
017    
018    public class SpringUtils {
019    
020            private static final Logger logger = LoggerFactory.getLogger(SpringUtils.class);
021    
022            /**
023             * Get a fully resolved property value from the environment. If the property is not found or contains unresolvable placeholders an exception is thrown.
024             */
025            public static String getProperty(Environment env, String key) {
026                    String value = env.getRequiredProperty(key);
027                    return env.resolveRequiredPlaceholders(value);
028            }
029    
030            public static Properties getAllProperties(ConfigurableEnvironment env) {
031    
032                    // Extract the list of PropertySources from the environment
033                    List<PropertySource<?>> sources = getPropertySources(env);
034    
035                    // Convert the list of PropertySource's to a list of Properties objects
036                    List<Properties> propertiesList = getPropertiesList(sources);
037    
038                    // Spring provides PropertySource objects ordered from highest priority to lowest priority
039                    // We reverse the order here so we can iterate though the list of Properties objects and use
040                    // properties.putAll() as an easy way to make sure the highest priority property value always wins
041                    Collections.reverse(propertiesList);
042    
043                    // Combine them into a single Properties object
044                    return PropertyUtils.combine(propertiesList);
045            }
046    
047            public static List<PropertySource<?>> getPropertySources(ConfigurableEnvironment env) {
048                    MutablePropertySources mps = env.getPropertySources();
049                    List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>();
050                    Iterator<PropertySource<?>> itr = mps.iterator();
051                    while (itr.hasNext()) {
052                            PropertySource<?> source = itr.next();
053                            sources.add(source);
054                    }
055                    return sources;
056            }
057    
058            public static List<Properties> getPropertiesList(List<PropertySource<?>> sources) {
059                    List<Properties> list = new ArrayList<Properties>();
060                    // Extract property values from the sources and place them in a Properties object
061                    for (PropertySource<?> source : sources) {
062                            logger.debug("Adding [{}]", source.getName());
063                            if (source instanceof EnumerablePropertySource) {
064                                    EnumerablePropertySource<?> eps = (EnumerablePropertySource<?>) source;
065                                    Properties sourceProperties = getProperties(eps);
066                                    list.add(sourceProperties);
067                            } else {
068                                    logger.warn("Unable to obtain properties from property source [{}] -> [{}]", source.getName(), source.getClass().getName());
069                            }
070                    }
071                    return list;
072            }
073    
074            public static Properties getProperties(EnumerablePropertySource<?> source) {
075                    Properties properties = new Properties();
076                    String[] names = source.getPropertyNames();
077                    for (String name : names) {
078                            Object object = source.getProperty(name);
079                            if (object != null) {
080                                    String value = object.toString();
081                                    properties.setProperty(name, value);
082                            } else {
083                                    logger.warn("Property [{}] is null", name);
084                            }
085                    }
086                    return properties;
087            }
088    
089    }