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