1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.lang.reflect.Constructor;
25
26 import javax.xml.namespace.QName;
27 import javax.xml.transform.Source;
28 import javax.xml.transform.dom.DOMSource;
29 import javax.xml.transform.stream.StreamSource;
30 import javax.xml.validation.Schema;
31 import javax.xml.validation.SchemaFactory;
32
33 import org.opensaml.xml.io.Marshaller;
34 import org.opensaml.xml.io.Unmarshaller;
35 import org.opensaml.xml.parse.BasicParserPool;
36 import org.opensaml.xml.parse.XMLParserException;
37 import org.opensaml.xml.util.DatatypeHelper;
38 import org.opensaml.xml.util.XMLConstants;
39 import org.opensaml.xml.util.XMLHelper;
40 import org.opensaml.xml.validation.Validator;
41 import org.opensaml.xml.validation.ValidatorSuite;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.w3c.dom.Attr;
45 import org.w3c.dom.Document;
46 import org.w3c.dom.Element;
47 import org.w3c.dom.NodeList;
48 import org.xml.sax.SAXException;
49
50
51
52
53 public class XMLConfigurator {
54
55
56 private final Logger log = LoggerFactory.getLogger(XMLConfigurator.class);
57
58
59 private boolean retainXMLConfiguration;
60
61
62 private BasicParserPool parserPool;
63
64
65 private Schema configurationSchema;
66
67
68
69
70
71
72 public XMLConfigurator() throws ConfigurationException {
73 this(false);
74 }
75
76
77
78
79
80
81
82
83
84
85 public XMLConfigurator(boolean retainXML) throws ConfigurationException {
86 retainXMLConfiguration = retainXML;
87 parserPool = new BasicParserPool();
88 SchemaFactory factory = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
89 Source schemaSource = new StreamSource(XMLConfigurator.class
90 .getResourceAsStream(XMLConstants.XMLTOOLING_SCHEMA_LOCATION));
91 try {
92 configurationSchema = factory.newSchema(schemaSource);
93
94 parserPool.setIgnoreComments(true);
95 parserPool.setIgnoreElementContentWhitespace(true);
96 parserPool.setSchema(configurationSchema);
97 } catch (SAXException e) {
98 throw new ConfigurationException("Unable to read XMLTooling configuration schema", e);
99 }
100 }
101
102
103
104
105
106
107
108
109
110 public void load(File configurationFile) throws ConfigurationException {
111 if (configurationFile == null || !configurationFile.canRead()) {
112 log.error("Unable to read configuration file {}", configurationFile);
113 }
114
115 try {
116 if (configurationFile.isDirectory()) {
117 File[] configurations = configurationFile.listFiles();
118 for (int i = 0; i < configurations.length; i++) {
119 log.debug("Parsing configuration file {}", configurations[i].getAbsolutePath());
120 load(new FileInputStream(configurations[i]));
121 }
122 } else {
123
124 log.debug("Parsing configuration file {}", configurationFile.getAbsolutePath());
125 load(new FileInputStream(configurationFile));
126 }
127 } catch (FileNotFoundException e) {
128
129 }
130 }
131
132
133
134
135
136
137
138
139 public void load(InputStream configurationStream) throws ConfigurationException {
140 try {
141 Document configuration = parserPool.parse(configurationStream);
142 load(configuration);
143 } catch (XMLParserException e) {
144 log.error("Invalid configuration file", e);
145 throw new ConfigurationException("Unable to create DocumentBuilder", e);
146 }
147
148 }
149
150
151
152
153
154
155
156 public void load(Document configuration) throws ConfigurationException {
157 log.debug("Loading configuration from XML Document");
158 log.trace("{}", XMLHelper.nodeToString(configuration.getDocumentElement()));
159
160
161 log.debug("Schema validating configuration Document");
162 validateConfiguration(configuration);
163 log.debug("Configuration document validated");
164
165 load(configuration.getDocumentElement());
166 }
167
168
169
170
171
172
173
174
175 protected void load(Element configurationRoot) throws ConfigurationException {
176
177 NodeList objectProviders = configurationRoot.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
178 "ObjectProviders");
179 if (objectProviders.getLength() > 0) {
180 log.info("Preparing to load ObjectProviders");
181 initializeObjectProviders((Element) objectProviders.item(0));
182 log.info("ObjectProviders load complete");
183 }
184
185
186 NodeList validatorSuitesNodes = configurationRoot.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
187 "ValidatorSuites");
188 if (validatorSuitesNodes.getLength() > 0) {
189 log.info("Preparing to load ValidatorSuites");
190 initializeValidatorSuites((Element) validatorSuitesNodes.item(0));
191 log.info("ValidatorSuites load complete");
192 }
193
194
195 NodeList idAttributesNodes = configurationRoot.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
196 "IDAttributes");
197 if (idAttributesNodes.getLength() > 0) {
198 log.info("Preparing to load IDAttributes");
199 initializeIDAttributes((Element) idAttributesNodes.item(0));
200 log.info("IDAttributes load complete");
201 }
202 }
203
204
205
206
207
208
209
210
211 protected void initializeObjectProviders(Element objectProviders) throws ConfigurationException {
212
213 Element objectProvider;
214 Attr qNameAttrib;
215 QName objectProviderName;
216 Element configuration;
217 XMLObjectBuilder builder;
218 Marshaller marshaller;
219 Unmarshaller unmarshaller;
220
221 NodeList providerList = objectProviders.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
222 "ObjectProvider");
223 for (int i = 0; i < providerList.getLength(); i++) {
224 objectProvider = (Element) providerList.item(i);
225
226
227 qNameAttrib = objectProvider.getAttributeNodeNS(null, "qualifiedName");
228 objectProviderName = XMLHelper.getAttributeValueAsQName(qNameAttrib);
229
230 log.debug("Initializing object provider {}", objectProviderName);
231
232 try {
233 configuration = (Element) objectProvider.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
234 "BuilderClass").item(0);
235 builder = (XMLObjectBuilder) createClassInstance(configuration);
236
237 configuration = (Element) objectProvider.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
238 "MarshallingClass").item(0);
239 marshaller = (Marshaller) createClassInstance(configuration);
240
241 configuration = (Element) objectProvider.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
242 "UnmarshallingClass").item(0);
243 unmarshaller = (Unmarshaller) createClassInstance(configuration);
244
245 if(retainXMLConfiguration){
246 Configuration.registerObjectProvider(objectProviderName, builder, marshaller, unmarshaller,
247 objectProvider);
248 }else{
249 Configuration.registerObjectProvider(objectProviderName, builder, marshaller, unmarshaller);
250 }
251
252 log.debug("{} intialized and configuration cached", objectProviderName);
253 } catch (ConfigurationException e) {
254 log.error("Error initializing object provier " + objectProvider, e);
255
256 Configuration.deregisterObjectProvider(objectProviderName);
257 throw e;
258 }
259 }
260 }
261
262
263
264
265
266
267
268
269
270 protected void initializeValidatorSuites(Element validatorSuitesElement) throws ConfigurationException {
271 ValidatorSuite validatorSuite;
272 Validator validator;
273 Element validatorSuiteElement;
274 String validatorSuiteId;
275 Element validatorElement;
276 QName validatorQName;
277
278 NodeList validatorSuiteList = validatorSuitesElement.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
279 "ValidatorSuite");
280 for (int i = 0; i < validatorSuiteList.getLength(); i++) {
281 validatorSuiteElement = (Element) validatorSuiteList.item(i);
282 validatorSuiteId = validatorSuiteElement.getAttributeNS(null, "id");
283 validatorSuite = new ValidatorSuite(validatorSuiteId);
284
285 log.debug("Initializing ValidatorSuite {}", validatorSuiteId);
286 log.trace(XMLHelper.nodeToString(validatorSuiteElement));
287
288 NodeList validatorList = validatorSuiteElement.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
289 "Validator");
290 for (int j = 0; j < validatorList.getLength(); j++) {
291 validatorElement = (Element) validatorList.item(j);
292 validatorQName = XMLHelper.getAttributeValueAsQName(validatorElement.getAttributeNodeNS(null,
293 "qualifiedName"));
294
295 validator = (Validator) createClassInstance(validatorElement);
296 validatorSuite.registerValidator(validatorQName, validator);
297 }
298
299 log.debug("ValidtorSuite {} has been initialized", validatorSuiteId);
300 if(retainXMLConfiguration){
301 Configuration.registerValidatorSuite(validatorSuiteId, validatorSuite, validatorSuiteElement);
302 }else{
303 Configuration.registerValidatorSuite(validatorSuiteId, validatorSuite);
304 }
305 }
306 }
307
308
309
310
311
312
313
314
315 protected void initializeIDAttributes(Element idAttributesElement) throws ConfigurationException {
316 Element idAttributeElement;
317 QName attributeQName;
318
319 NodeList idAttributeList = idAttributesElement.getElementsByTagNameNS(XMLConstants.XMLTOOLING_CONFIG_NS,
320 "IDAttribute");
321
322 for (int i = 0; i < idAttributeList.getLength(); i++) {
323 idAttributeElement = (Element) idAttributeList.item(i);
324 attributeQName = XMLHelper.getElementContentAsQName(idAttributeElement);
325 if (attributeQName == null) {
326 log.info("IDAttribute element was empty, no registration performed");
327 } else {
328 Configuration.registerIDAttribute(attributeQName);
329 log.debug("IDAttribute {} has been registered", attributeQName);
330 }
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343 protected Object createClassInstance(Element configuration) throws ConfigurationException {
344 String className = configuration.getAttributeNS(null, "className");
345 className = DatatypeHelper.safeTrimOrNullString(className);
346
347 if (className == null) {
348 return null;
349 }
350
351 try {
352 log.trace("Creating instance of {}", className);
353 ClassLoader classLoader = this.getClass().getClassLoader();
354 Class clazz = classLoader.loadClass(className);
355 Constructor constructor = clazz.getConstructor();
356 return constructor.newInstance();
357 } catch (Exception e) {
358 log.error("Can not create instance of " + className, e);
359 throw new ConfigurationException("Can not create instance of " + className, e);
360 }
361 }
362
363
364
365
366
367
368
369
370 protected void validateConfiguration(Document configuration) throws ConfigurationException {
371 try {
372 javax.xml.validation.Validator schemaValidator = configurationSchema.newValidator();
373 schemaValidator.validate(new DOMSource(configuration));
374 } catch (IOException e) {
375
376 String errorMsg = "Unable to read configuration file DOM";
377 log.error(errorMsg, e);
378 throw new ConfigurationException(errorMsg, e);
379 } catch (SAXException e) {
380 String errorMsg = "Configuration file does not validate against schema";
381 log.error(errorMsg, e);
382 throw new ConfigurationException(errorMsg, e);
383 }
384 }
385 }