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