1 package org.kuali.common.util.spring;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.Comparator;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Properties;
11
12 import org.codehaus.plexus.util.StringUtils;
13 import org.kuali.common.util.Assert;
14 import org.kuali.common.util.LocationUtils;
15 import org.kuali.common.util.LoggerLevel;
16 import org.kuali.common.util.LoggerUtils;
17 import org.kuali.common.util.Project;
18 import org.kuali.common.util.ProjectUtils;
19 import org.kuali.common.util.PropertyUtils;
20 import org.kuali.common.util.Str;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import org.springframework.beans.factory.BeanFactoryUtils;
24 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
25 import org.springframework.context.ConfigurableApplicationContext;
26 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
27 import org.springframework.context.support.GenericXmlApplicationContext;
28 import org.springframework.core.env.ConfigurableEnvironment;
29 import org.springframework.core.env.EnumerablePropertySource;
30 import org.springframework.core.env.Environment;
31 import org.springframework.core.env.MutablePropertySources;
32 import org.springframework.core.env.PropertiesPropertySource;
33 import org.springframework.core.env.PropertySource;
34
35 public class SpringUtils {
36
37 private static final Logger logger = LoggerFactory.getLogger(SpringUtils.class);
38
39
40
41
42
43
44
45
46 public static String getDefaultPropertyContextLocation(String gav) {
47 Assert.hasText(gav, "gav has no text");
48 Project p = ProjectUtils.getProject(gav);
49 return "classpath:" + Str.getPath(p.getGroupId()) + "/" + p.getArtifactId() + "-properties-context.xml";
50 }
51
52
53
54
55 public static void validateExists(List<String> locations) {
56 StringBuilder sb = new StringBuilder();
57 for (String location : locations) {
58 if (!LocationUtils.exists(location)) {
59 sb.append("Location [" + location + "] does not exist\n");
60 }
61 }
62 if (sb.length() > 0) {
63 throw new IllegalArgumentException(sb.toString());
64 }
65 }
66
67 public static ConfigurableApplicationContext getContextWithPreRegisteredBeans(List<String> beanNames, List<Object> beans) {
68 Assert.isTrue(beanNames.size() == beans.size());
69 GenericXmlApplicationContext appContext = new GenericXmlApplicationContext();
70 appContext.refresh();
71 ConfigurableListableBeanFactory factory = appContext.getBeanFactory();
72 for (int i = 0; i < beanNames.size(); i++) {
73 String beanName = beanNames.get(i);
74 Object bean = beans.get(i);
75 logger.debug("Registering bean - [{}] -> [{}]", beanName, bean.getClass().getName());
76 factory.registerSingleton(beanName, bean);
77 }
78 return appContext;
79 }
80
81
82
83
84 public static void refreshQuietly(ConfigurableApplicationContext context) {
85 if (context != null) {
86 context.refresh();
87 }
88 }
89
90
91
92
93 public static void closeQuietly(ConfigurableApplicationContext context) {
94 if (context != null) {
95 context.close();
96 }
97 }
98
99 public static ConfigurableApplicationContext getContextWithPreRegisteredBean(String beanName, Object bean) {
100 return getContextWithPreRegisteredBeans(Arrays.asList(beanName), Arrays.asList(bean));
101 }
102
103 public static List<PropertySource<?>> getPropertySources(Class<?> annotatedClass) {
104 ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(annotatedClass);
105 return extractPropertySourcesAndClose(context);
106 }
107
108 public static List<PropertySource<?>> extractPropertySourcesAndClose(ConfigurableApplicationContext context) {
109
110 List<PropertySource<?>> sources = getPropertySources(context);
111
112
113 closeQuietly(context);
114
115
116 return sources;
117 }
118
119
120
121
122 public static List<PropertySource<?>> getPropertySources(String location) {
123 ConfigurableApplicationContext context = new GenericXmlApplicationContext(location);
124 return extractPropertySourcesAndClose(context);
125 }
126
127
128
129
130 public static List<PropertySource<?>> getPropertySources(ConfigurableApplicationContext context) {
131
132 return getPropertySources(context, new PropertySourceNameComparator());
133 }
134
135 public static <T> Map<String, T> getAllBeans(List<String> locations, Class<T> type) {
136 String[] locationsArray = locations.toArray(new String[locations.size()]);
137 ConfigurableApplicationContext ctx = new GenericXmlApplicationContext(locationsArray);
138 Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
139 ctx.close();
140 return map;
141 }
142
143 public static <T> Map<String, T> getAllBeans(String location, Class<T> type) {
144 ConfigurableApplicationContext ctx = new GenericXmlApplicationContext(location);
145 Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
146 ctx.close();
147 return map;
148 }
149
150 public static <T> Map<String, T> getAllBeans(ConfigurableApplicationContext ctx, Class<T> type) {
151 return BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, type);
152 }
153
154
155
156
157 public static List<PropertySource<?>> getPropertySources(ConfigurableApplicationContext context, Comparator<PropertySource<?>> comparator) {
158
159 @SuppressWarnings("rawtypes")
160 Map<String, PropertySource> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, PropertySource.class);
161
162
163 List<PropertySource<?>> list = new ArrayList<PropertySource<?>>();
164 for (PropertySource<?> source : map.values()) {
165 list.add(source);
166 }
167
168
169 Collections.sort(list, comparator);
170
171
172 return list;
173 }
174
175
176
177
178 public static List<PropertySource<?>> asList(PropertySource<?>... sources) {
179 List<PropertySource<?>> list = new ArrayList<PropertySource<?>>();
180 if (sources == null) {
181 return list;
182 }
183 for (PropertySource<?> element : sources) {
184 if (element != null) {
185 list.add(element);
186 }
187 }
188 return list;
189 }
190
191 public static void showPropertySources(List<PropertySource<?>> propertySources) {
192 List<String> columns = Arrays.asList("Name", "Impl", "Source");
193 List<Object[]> rows = new ArrayList<Object[]>();
194 for (PropertySource<?> propertySource : propertySources) {
195 String name = propertySource.getName();
196 String impl = propertySource.getClass().getName();
197 String source = propertySource.getSource().getClass().getName();
198 Object[] row = { name, impl, source };
199 rows.add(row);
200 }
201 LoggerUtils.logTable(columns, rows, LoggerLevel.INFO, logger, true);
202 }
203
204 public static void showPropertySources(ConfigurableEnvironment env) {
205 showPropertySources(getPropertySources(env));
206 }
207
208
209
210
211 public static String getProperty(Environment env, String key) {
212 String value = env.getRequiredProperty(key);
213 return env.resolveRequiredPlaceholders(value);
214 }
215
216
217
218
219
220 public static Properties getAllEnumerableProperties(ConfigurableEnvironment env) {
221
222
223 List<PropertySource<?>> sources = getPropertySources(env);
224
225
226
227 Collections.reverse(sources);
228
229
230 PropertySourceConversionResult result = convertEnumerablePropertySources(sources);
231
232
233 return PropertyUtils.combine(result.getPropertiesList());
234 }
235
236
237
238
239 public static void reconfigurePropertySources(ConfigurableEnvironment env, String name, Properties properties) {
240
241 removeAllPropertySources(env);
242
243
244 MutablePropertySources mps = env.getPropertySources();
245
246
247 Assert.isTrue(mps.size() == 0);
248
249
250 PropertiesPropertySource pps = new PropertiesPropertySource(name, properties);
251
252
253 mps.addFirst(pps);
254 }
255
256
257
258
259 public static void removeAllPropertySources(ConfigurableEnvironment env) {
260 MutablePropertySources mps = env.getPropertySources();
261 List<PropertySource<?>> sources = getPropertySources(env);
262 for (PropertySource<?> source : sources) {
263 String name = source.getName();
264 mps.remove(name);
265 }
266 }
267
268
269
270
271 public static List<PropertySource<?>> getPropertySources(ConfigurableEnvironment env) {
272 MutablePropertySources mps = env.getPropertySources();
273 List<PropertySource<?>> sources = new ArrayList<PropertySource<?>>();
274 Iterator<PropertySource<?>> itr = mps.iterator();
275 while (itr.hasNext()) {
276 PropertySource<?> source = itr.next();
277 sources.add(source);
278 }
279 return sources;
280 }
281
282
283
284
285 public static PropertySourceConversionResult convertEnumerablePropertySources(List<PropertySource<?>> sources) {
286 PropertySourceConversionResult result = new PropertySourceConversionResult();
287 List<Properties> list = new ArrayList<Properties>();
288 List<PropertySource<?>> converted = new ArrayList<PropertySource<?>>();
289 List<PropertySource<?>> skipped = new ArrayList<PropertySource<?>>();
290
291 for (PropertySource<?> source : sources) {
292 logger.debug("Adding [{}]", source.getName());
293 if (source instanceof EnumerablePropertySource) {
294 EnumerablePropertySource<?> eps = (EnumerablePropertySource<?>) source;
295 Properties sourceProperties = convert(eps);
296 list.add(sourceProperties);
297 converted.add(source);
298 } else {
299 logger.debug("Unable to obtain properties from property source [{}] -> [{}]", source.getName(), source.getClass().getName());
300 skipped.add(source);
301 }
302 }
303 result.setConverted(converted);
304 result.setSkipped(skipped);
305 result.setPropertiesList(list);
306 return result;
307 }
308
309
310
311
312 public static Properties convert(EnumerablePropertySource<?> source) {
313 Properties properties = new Properties();
314 String[] names = source.getPropertyNames();
315 for (String name : names) {
316 Object object = source.getProperty(name);
317 if (object != null) {
318 String value = object.toString();
319 properties.setProperty(name, value);
320 } else {
321 logger.warn("Property [{}] is null", name);
322 }
323 }
324 return properties;
325 }
326
327
328
329
330 public static boolean isTrue(Environment env, String property) {
331 String value = env.getProperty(property);
332 if (StringUtils.isBlank(value)) {
333 return false;
334 } else {
335 return new Boolean(value);
336 }
337 }
338
339 }