1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package edu.internet2.middleware.shibboleth.common.config;
18
19 import java.util.Date;
20 import java.util.List;
21
22 import javax.xml.datatype.Duration;
23
24 import org.opensaml.util.resource.Resource;
25 import org.opensaml.util.resource.ResourceException;
26 import org.opensaml.xml.util.DatatypeHelper;
27 import org.opensaml.xml.util.XMLHelper;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.beans.factory.BeanDefinitionStoreException;
31 import org.springframework.beans.factory.config.BeanDefinition;
32 import org.springframework.beans.factory.config.RuntimeBeanReference;
33 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
34 import org.springframework.beans.factory.support.ManagedList;
35 import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
36 import org.springframework.beans.factory.xml.NamespaceHandler;
37 import org.springframework.beans.factory.xml.ParserContext;
38 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
39 import org.springframework.core.io.InputStreamResource;
40 import org.w3c.dom.Element;
41
42
43
44
45 public final class SpringConfigurationUtils {
46
47
48 private static Logger log = LoggerFactory.getLogger(SpringConfigurationUtils.class);
49
50
51 private SpringConfigurationUtils() {
52 }
53
54
55
56
57
58
59
60
61
62
63 public static void populateRegistry(BeanDefinitionRegistry beanRegistry, List<Resource> configurationResources)
64 throws ResourceException {
65 XmlBeanDefinitionReader configReader = new XmlBeanDefinitionReader(beanRegistry);
66 configReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
67 configReader.setDocumentLoader(new SpringDocumentLoader());
68
69 int numOfResources = configurationResources.size();
70 Resource configurationResource;
71 org.springframework.core.io.Resource[] configSources = new org.springframework.core.io.Resource[numOfResources];
72 for (int i = 0; i < numOfResources; i++) {
73 configurationResource = configurationResources.get(i);
74 if (configurationResource != null && configurationResource.exists()) {
75 configSources[i] = new InputStreamResource(configurationResources.get(i).getInputStream(),
76 configurationResource.getLocation());
77 } else {
78 log.warn("Configuration resource not loaded because it does not exist: {}", configurationResource
79 .getLocation());
80 }
81 }
82
83 try {
84 configReader.loadBeanDefinitions(configSources);
85 } catch (BeanDefinitionStoreException e) {
86 throw new ResourceException("Unable to load Spring bean registry with configuration resources", e);
87 }
88 }
89
90
91
92
93
94
95
96
97
98
99 public static BeanDefinition parseInnerCustomElement(Element element, ParserContext parserContext) {
100 return createBeanDefinition(element, parserContext);
101 }
102
103
104
105
106
107
108
109
110
111
112 public static ManagedList parseInnerCustomElements(List<Element> elements, ParserContext parserContext) {
113 ManagedList beans = new ManagedList();
114 if (elements != null) {
115 for (Element element : elements) {
116 beans.add(parseInnerCustomElement(element, parserContext));
117 }
118 }
119
120 return beans;
121 }
122
123
124
125
126
127
128
129
130
131
132
133 public static RuntimeBeanReference parseCustomElement(Element element, ParserContext parserContext) {
134 return parseCustomElement(element, "id", parserContext);
135 }
136
137
138
139
140
141
142
143
144
145
146
147 public static RuntimeBeanReference parseCustomElement(Element element, String idAttribute,
148 ParserContext parserContext) {
149 createBeanDefinition(element, parserContext);
150 RuntimeBeanReference beanRef = new RuntimeBeanReference(element.getAttributeNS(null, idAttribute));
151 beanRef.setSource(element);
152 return beanRef;
153 }
154
155
156
157
158
159
160
161
162
163 private static BeanDefinition createBeanDefinition(Element element, ParserContext parserContext) {
164 BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
165 String namespaceUri = element.getNamespaceURI();
166
167 if (XMLHelper.hasXSIType(element)) {
168 namespaceUri = XMLHelper.getXSIType(element).getNamespaceURI();
169 }
170
171 NamespaceHandler handler = delegate.getReaderContext().getNamespaceHandlerResolver().resolve(namespaceUri);
172 if (handler == null) {
173 log.error("Unable to locate NamespaceHandler for namespace [" + namespaceUri + "]");
174 return null;
175 }
176 return handler.parse(element, new ParserContext(delegate.getReaderContext(), delegate));
177 }
178
179
180
181
182
183
184
185
186
187
188 public static RuntimeBeanReference parseCustomElementReference(Element element, String refAttribute,
189 ParserContext parserContext) {
190 String reference = DatatypeHelper.safeTrimOrNullString(element.getAttributeNS(null, refAttribute));
191 if (reference != null) {
192 return new RuntimeBeanReference(reference);
193 }
194
195 return null;
196 }
197
198
199
200
201
202
203
204
205
206
207 public static ManagedList parseCustomElements(List<Element> elements, ParserContext parserContext) {
208 return parseCustomElements(elements, "id", parserContext);
209 }
210
211
212
213
214
215
216
217
218
219
220 public static ManagedList parseCustomElements(List<Element> elements, String idAttribute,
221 ParserContext parserContext) {
222 if (elements == null) {
223 return null;
224 }
225
226 ManagedList definitions = new ManagedList(elements.size());
227 for (Element e : elements) {
228 definitions.add(parseCustomElement(e, idAttribute, parserContext));
229 }
230
231 return definitions;
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 @Deprecated
251 public static long parseDurationToMillis(String propertyName, String duration, int toMillisFactor)
252 throws IllegalArgumentException {
253 if (duration.startsWith("-")) {
254 throw new IllegalArgumentException("Negative durations are not supported");
255 }
256
257 long millis = 0;
258 if (duration.startsWith("P")) {
259 Duration xmlDuration = XMLHelper.getDataTypeFactory().newDuration(duration);
260 millis = xmlDuration.getTimeInMillis(new Date());
261 } else {
262 try {
263 millis = Long.parseLong(duration);
264 if (millis < 0) {
265 throw new IllegalArgumentException("Negative durations are not supported");
266 }
267 if (toMillisFactor > 0) {
268 millis *= toMillisFactor;
269 }
270 Duration xmlDuration = XMLHelper.getDataTypeFactory().newDuration(millis);
271 log.warn("Numerical duration form is deprecated. The property {} should use the duration notation: {}",
272 propertyName, xmlDuration.toString());
273 } catch (NumberFormatException e) {
274
275 }
276 }
277
278 return millis;
279 }
280 }