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.Assert;
010 import org.kuali.common.util.PropertyUtils;
011 import org.slf4j.Logger;
012 import org.slf4j.LoggerFactory;
013 import org.springframework.core.env.ConfigurableEnvironment;
014 import org.springframework.core.env.EnumerablePropertySource;
015 import org.springframework.core.env.Environment;
016 import org.springframework.core.env.MutablePropertySources;
017 import org.springframework.core.env.PropertiesPropertySource;
018 import org.springframework.core.env.PropertySource;
019
020 public class SpringUtils {
021
022 private static final Logger logger = LoggerFactory.getLogger(SpringUtils.class);
023
024 public static void showPropertySources(ConfigurableEnvironment env) {
025 List<PropertySource<?>> propertySources = getPropertySources(env);
026 for (PropertySource<?> propertySource : propertySources) {
027 String name = propertySource.getName();
028 String impl = propertySource.getClass().getName();
029 String source = propertySource.getSource().getClass().getName();
030 Object[] args = { name, impl, source };
031 logger.info("Name: {} Impl: [{}] Source: [{}]", args);
032 }
033 }
034
035 /**
036 * Get a fully resolved property value from the environment. If the property is not found or contains unresolvable placeholders an exception is thrown.
037 */
038 public static String getProperty(Environment env, String key) {
039 String value = env.getRequiredProperty(key);
040 return env.resolveRequiredPlaceholders(value);
041 }
042
043 /**
044 * Examine <code>ConfigurableEnvironment</code> for <code>PropertySource</code>'s that extend <code>EnumerablePropertySource</code> and aggregate them into a single
045 * <code>Properties</code> object
046 */
047 public static Properties getAllEnumerableProperties(ConfigurableEnvironment env) {
048
049 // Extract the list of PropertySources from the environment
050 List<PropertySource<?>> sources = getPropertySources(env);
051
052 // Convert the list of PropertySource's to a list of Properties objects
053 List<Properties> propertiesList = convertEnumerablePropertySources(sources);
054
055 // Spring provides PropertySource objects ordered from highest priority to lowest priority
056 // We reverse the order here so we can iterate though the list of Properties objects using
057 // properties.putAll() as a simple "last one in wins" strategy to make sure the highest priority
058 // property value always wins
059 Collections.reverse(propertiesList);
060
061 // Combine them into a single Properties object
062 return PropertyUtils.combine(propertiesList);
063 }
064
065 /**
066 * Remove any existing property sources and add one property source backed by the properties passed in
067 */
068 public static void reconfigurePropertySources(ConfigurableEnvironment env, String name, Properties properties) {
069 // Remove all existing property sources
070 removeAllPropertySources(env);
071
072 // MutablePropertySources allow us to manipulate the list of property sources
073 MutablePropertySources mps = env.getPropertySources();
074
075 // Make sure there are no existing property sources
076 Assert.isTrue(mps.size() == 0);
077
078 // Create a property source backed by the properties object passed in
079 PropertiesPropertySource pps = new PropertiesPropertySource(name, properties);
080
081 // Add it to the environment
082 mps.addFirst(pps);
083 }
084
085 /**
086 * Remove any existing property sources
087 */
088 public static void removeAllPropertySources(ConfigurableEnvironment env) {
089 MutablePropertySources mps = env.getPropertySources();
090 List<PropertySource<?>> sources = getPropertySources(env);
091 for (PropertySource<?> source : sources) {
092 String name = source.getName();
093 mps.remove(name);
094 }
095 }
096
097 /**
098 * Get all PropertySource objects from the environment as a List.
099 */
100 public static List<PropertySource<?>> getPropertySources(ConfigurableEnvironment env) {
101 MutablePropertySources mps = env.getPropertySources();
102 List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>();
103 Iterator<PropertySource<?>> itr = mps.iterator();
104 while (itr.hasNext()) {
105 PropertySource<?> source = itr.next();
106 sources.add(source);
107 }
108 return sources;
109 }
110
111 /**
112 * Convert any PropertySources that extend EnumerablePropertySource into Properties object's
113 */
114 public static List<Properties> convertEnumerablePropertySources(List<PropertySource<?>> sources) {
115 List<Properties> list = new ArrayList<Properties>();
116 // Extract property values from the sources and place them in a Properties object
117 for (PropertySource<?> source : sources) {
118 logger.debug("Adding [{}]", source.getName());
119 if (source instanceof EnumerablePropertySource) {
120 EnumerablePropertySource<?> eps = (EnumerablePropertySource<?>) source;
121 Properties sourceProperties = convert(eps);
122 list.add(sourceProperties);
123 } else {
124 logger.warn("Unable to obtain properties from property source [{}] -> [{}]", source.getName(), source.getClass().getName());
125 }
126 }
127 return list;
128 }
129
130 /**
131 * Convert an EnumerablePropertySource into a Properties object.
132 */
133 public static Properties convert(EnumerablePropertySource<?> source) {
134 Properties properties = new Properties();
135 String[] names = source.getPropertyNames();
136 for (String name : names) {
137 Object object = source.getProperty(name);
138 if (object != null) {
139 String value = object.toString();
140 properties.setProperty(name, value);
141 } else {
142 logger.warn("Property [{}] is null", name);
143 }
144 }
145 return properties;
146 }
147
148 }