1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.common.util.service;
17
18 import java.io.File;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23
24 import org.kuali.common.util.Assert;
25 import org.kuali.common.util.CollectionUtils;
26 import org.kuali.common.util.LocationUtils;
27 import org.kuali.common.util.spring.SpringUtils;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.context.ConfigurableApplicationContext;
31 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
32 import org.springframework.context.support.ClassPathXmlApplicationContext;
33 import org.springframework.core.env.ConfigurableEnvironment;
34 import org.springframework.core.env.MutablePropertySources;
35 import org.springframework.core.env.PropertySource;
36
37 public class DefaultSpringService implements SpringService {
38
39 private static final Logger logger = LoggerFactory.getLogger(DefaultSpringService.class);
40
41 @Override
42 public void load(Class<?> annotatedClass) {
43 load(annotatedClass, null, null);
44 }
45
46 @Override
47 public void load(Class<?> annotatedClass, String beanName, Object bean, PropertySource<?> propertySource) {
48
49 Assert.notNull(annotatedClass, "annotatedClass is null");
50
51
52 SpringContext context = new SpringContext();
53 context.setAnnotatedClasses(CollectionUtils.asList(annotatedClass));
54 context.setPropertySourceContext(new PropertySourceContext(SpringUtils.asList(propertySource)));
55
56
57 context.setBeanNames(CollectionUtils.toEmptyList(beanName));
58 context.setBeans(CollectionUtils.toEmptyList(bean));
59
60
61 load(context);
62 }
63
64 @Override
65 public void load(Class<?> annotatedClass, String beanName, Object bean) {
66 load(annotatedClass, beanName, bean, null);
67 }
68
69 @Override
70 public void load(String location) {
71 load(location, null, null);
72 }
73
74 @Override
75 public void load(String location, String beanName, Object bean, PropertySource<?> propertySource) {
76
77 Assert.hasText(location, "location is null");
78
79
80 SpringContext context = new SpringContext();
81 context.setLocations(Arrays.asList(location));
82 context.setPropertySourceContext(new PropertySourceContext(SpringUtils.asList(propertySource)));
83
84
85 context.setBeanNames(CollectionUtils.toEmptyList(beanName));
86 context.setBeans(CollectionUtils.toEmptyList(bean));
87
88
89 load(context);
90 }
91
92 @Override
93 public void load(String location, String beanName, Object bean) {
94 load(location, beanName, bean, null);
95 }
96
97 @Override
98 public void load(SpringContext context) {
99
100
101 context.setBeanNames(CollectionUtils.toEmptyList(context.getBeanNames()));
102 context.setBeans(CollectionUtils.toEmptyList(context.getBeans()));
103 context.setAnnotatedClasses(CollectionUtils.toEmptyList(context.getAnnotatedClasses()));
104 context.setLocations(CollectionUtils.toEmptyList(context.getLocations()));
105
106
107 boolean empty = CollectionUtils.isEmpty(context.getLocations()) && CollectionUtils.isEmpty(context.getAnnotatedClasses());
108 Assert.isFalse(empty, "Both locations and annotatedClasses are empty");
109
110
111 Assert.isTrue(context.getBeanNames().size() == context.getBeans().size());
112
113
114 SpringUtils.validateExists(context.getLocations());
115
116
117 List<String> convertedLocations = getConvertedLocations(context.getLocations());
118
119
120 String[] locationsArray = CollectionUtils.toStringArray(convertedLocations);
121
122 ConfigurableApplicationContext parent = null;
123 ConfigurableApplicationContext xmlChild = null;
124 AnnotationConfigApplicationContext annotationChild = null;
125 try {
126 if (isParentContextRequired(context)) {
127
128 parent = SpringUtils.getContextWithPreRegisteredBeans(context.getBeanNames(), context.getBeans());
129 }
130
131 if (!CollectionUtils.isEmpty(context.getAnnotatedClasses())) {
132
133 annotationChild = getAnnotationContext(context, parent);
134
135 addPropertySources(context, annotationChild);
136
137 }
138
139 if (!CollectionUtils.isEmpty(context.getLocations())) {
140
141 xmlChild = new ClassPathXmlApplicationContext(locationsArray, false, parent);
142
143 addPropertySources(context, xmlChild);
144 }
145
146
147 SpringUtils.refreshQuietly(annotationChild);
148 SpringUtils.refreshQuietly(xmlChild);
149 } finally {
150
151
152
153
154 }
155 }
156
157 protected AnnotationConfigApplicationContext getAnnotationContext(SpringContext context, ConfigurableApplicationContext parent) {
158 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
159 if (parent != null) {
160 ctx.setParent(parent);
161 }
162 for (Class<?> annotatedClass : context.getAnnotatedClasses()) {
163 ctx.register(annotatedClass);
164 }
165 return ctx;
166 }
167
168 protected void addPropertySources(SpringContext context, ConfigurableApplicationContext applicationContext) {
169 PropertySourceContext psc = context.getPropertySourceContext();
170 ConfigurableEnvironment env = applicationContext.getEnvironment();
171 if (psc.isRemoveExistingSources()) {
172 logger.debug("Removing all existing property sources");
173 SpringUtils.removeAllPropertySources(env);
174 }
175
176 if (CollectionUtils.isEmpty(psc.getSources())) {
177 return;
178 }
179 List<PropertySource<?>> propertySources = psc.getSources();
180 MutablePropertySources sources = env.getPropertySources();
181 if (psc.isLastOneInWins()) {
182 Collections.reverse(propertySources);
183 }
184 PropertySourceAddPriority priority = psc.getPriority();
185 for (PropertySource<?> propertySource : propertySources) {
186 Object[] args = { propertySource.getName(), propertySource.getClass().getName(), priority };
187 logger.debug("Adding property source - [{}] -> [{}] Priority=[{}]", args);
188 switch (priority) {
189 case FIRST:
190 sources.addFirst(propertySource);
191 break;
192 case LAST:
193 sources.addLast(propertySource);
194 break;
195 default:
196 throw new IllegalStateException(priority + " is an unknown priority");
197 }
198 }
199 }
200
201
202
203
204 protected boolean isParentContextRequired(SpringContext context) {
205 if (!CollectionUtils.isEmpty(context.getBeanNames())) {
206 return true;
207 } else if (!CollectionUtils.isEmpty(context.getBeans())) {
208 return true;
209 } else {
210 return false;
211 }
212 }
213
214
215
216
217 protected List<String> getConvertedLocations(List<String> locations) {
218 List<String> converted = new ArrayList<String>();
219 for (String location : locations) {
220 if (LocationUtils.isExistingFile(location)) {
221 File file = new File(location);
222
223 String url = LocationUtils.getCanonicalURLString(file);
224 converted.add(url);
225 } else {
226 converted.add(location);
227 }
228 }
229 return converted;
230 }
231
232 }