1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.xmlhammer;
22
23 import java.net.URI;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import javax.xml.parsers.FactoryConfigurationError;
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.parsers.SAXParser;
32 import javax.xml.parsers.SAXParserFactory;
33 import javax.xml.transform.Source;
34 import javax.xml.transform.TransformerConfigurationException;
35 import javax.xml.transform.TransformerException;
36 import javax.xml.transform.TransformerFactory;
37 import javax.xml.transform.TransformerFactoryConfigurationError;
38 import javax.xml.transform.stream.StreamSource;
39 import javax.xml.validation.Schema;
40 import javax.xml.validation.SchemaFactory;
41 import javax.xml.xpath.XPath;
42 import javax.xml.xpath.XPathFactory;
43 import javax.xml.xpath.XPathFactoryConfigurationException;
44
45 import org.apache.log4j.Logger;
46 import org.apache.xml.resolver.tools.CatalogResolver;
47 import org.bounce.util.URIUtils;
48 import org.xml.sax.SAXException;
49 import org.xml.sax.SAXNotRecognizedException;
50 import org.xml.sax.SAXNotSupportedException;
51 import org.xml.sax.SAXParseException;
52 import org.xmlhammer.DefaultErrorHandler.Error;
53 import org.xmlhammer.DefaultErrorHandler.Fatal;
54 import org.xmlhammer.DefaultErrorHandler.Problem;
55 import org.xmlhammer.DefaultErrorHandler.Warning;
56 import org.xmlhammer.gui.status.StatusModel;
57 import org.xmlhammer.gui.util.JAXPSettings;
58 import org.xmlhammer.gui.xpath.NamespaceContextMap;
59 import org.xmlhammer.model.jaxp.Attribute;
60 import org.xmlhammer.model.jaxp.Feature;
61 import org.xmlhammer.model.jaxp.JAXPDocumentBuilderFactory;
62 import org.xmlhammer.model.jaxp.JAXPSAXParserFactory;
63 import org.xmlhammer.model.jaxp.JAXPTransformerFactory;
64 import org.xmlhammer.model.jaxp.JAXPXPathFactory;
65 import org.xmlhammer.model.jaxp.Mapping;
66 import org.xmlhammer.model.jaxp.Property;
67 import org.xmlhammer.model.jaxp.SchemaFactoryProperty;
68 import org.xmlhammer.model.preferences.Preferences;
69 import org.xmlhammer.model.project.Project;
70
71 /***
72 * Put comment...
73 *
74 * @version $Revision: 1.27 $, $Date: 2007/07/04 19:42:48 $
75 * @author Edwin Dankert <edankert@gmail.com>
76 */
77
78 public abstract class Module extends JAXPSettings {
79 private Project project = null;
80 private Preferences preferences = null;
81 private Logger logger = null;
82 private boolean logSettings = true;
83 private boolean fatal = false;
84 private boolean errors = false;
85 private boolean warnings = false;
86
87 public Module(Preferences preferences, Project project, Logger logger, boolean logSettings) {
88 super(preferences.getJAXPSettings(), project.getJAXPSettings());
89
90 this.preferences = preferences;
91 this.project = project;
92 this.logger = logger;
93 this.logSettings = logSettings;
94 }
95
96 /***
97 * Execute the module.
98 *
99 * @param logger the logger.
100 * @param uri the uri.
101 */
102 public void execute(StatusModel status, ResultModel result, URI sourceURI) throws Exception {
103
104 }
105
106 public void execute(StatusModel status, ResultModel result, URI sourceURI, URI resultURI) throws Exception {
107
108 }
109
110 public boolean isResultEnabled() {
111 return false;
112 }
113
114 public boolean isLogSettings() {
115 return logSettings;
116 }
117
118 private synchronized XPathFactory getXPathFactory() {
119 logSettings("info: "+XPathFactory.DEFAULT_PROPERTY_NAME);
120
121 String objectModel = XPathFactory.DEFAULT_OBJECT_MODEL_URI;
122 JAXPXPathFactory.Settings settings = getXPathFactorySettings();
123
124 if ( settings.getObjectModel() != null) {
125 objectModel = settings.getObjectModel();
126 }
127
128 logSettings("\t[object-model] "+objectModel);
129
130 XPathFactory factory = null;
131
132 String previous = System.getProperty(XPathFactory.DEFAULT_PROPERTY_NAME);
133
134
135
136 try {
137 if (settings.getValue() != null) {
138 setProperty(XPathFactory.DEFAULT_PROPERTY_NAME, settings.getValue());
139 }
140
141 factory = XPathFactory.newInstance(objectModel);
142 logSettings("\t[class] "+factory.getClass().getName());
143 } catch (XPathFactoryConfigurationException e) {
144 logFatal(e);
145 fatal = true;
146 } finally {
147 setProperty(XPathFactory.DEFAULT_PROPERTY_NAME, previous);
148 }
149
150 if (factory != null) {
151 for ( Feature feature : getXPathFactoryFeatures()) {
152 try {
153 factory.setFeature( feature.getName(), feature.isEnabled());
154 logSettings( "\t[feature] "+feature.getName()+" = "+feature.isEnabled());
155 } catch (XPathFactoryConfigurationException e) {
156 logError(e);
157 errors = true;
158 }
159 }
160 }
161
162 return factory;
163 }
164
165 public XPath getXPath() {
166 XPathFactory factory = getXPathFactory();
167
168 XPath xpath = factory.newXPath();
169
170 NamespaceContextMap nsMap = new NamespaceContextMap();
171
172 for ( Mapping mapping : getXPathFactoryMappings()) {
173 logSettings("\t[mapping] xmlns:"+mapping.getPrefix()+"=\""+mapping.getUri()+"\"");
174 nsMap.put(mapping.getPrefix(), mapping.getUri());
175 }
176
177 xpath.setNamespaceContext(nsMap);
178
179 return xpath;
180 }
181
182 public synchronized DocumentBuilderFactory getDocumentBuilderFactory() throws SAXException {
183 logSettings("info: javax.xml.parsers.DocumentBuilderFactory");
184
185 JAXPDocumentBuilderFactory.Settings settings = getDocumentBuilderFactorySettings();
186
187 DocumentBuilderFactory factory = null;
188
189 String previous = System.getProperty("javax.xml.parsers.DocumentBuilderFactory");
190
191 try {
192 if ( settings.getValue() != null) {
193 setProperty("javax.xml.parsers.DocumentBuilderFactory", settings.getValue());
194 }
195
196 factory = DocumentBuilderFactory.newInstance();
197 } catch (FactoryConfigurationError e) {
198 logFatal(e);
199 fatal = true;
200 } finally {
201 setProperty("javax.xml.parsers.DocumentBuilderFactory", previous);
202 }
203
204 if (factory != null) {
205 logSettings("\t[class] "+factory.getClass().getName());
206
207 factory.setCoalescing(settings.isCoalescing());
208 logSettings("\t[setting] coalescing = "+settings.isCoalescing());
209 factory.setExpandEntityReferences(settings.isExpandEntityReference());
210 logSettings("\t[setting] expand-entity-reference = "+settings.isExpandEntityReference());
211 factory.setIgnoringComments(settings.isIgnoringComments());
212 logSettings("\t[setting] ignoring-comments = "+settings.isIgnoringComments());
213 factory.setIgnoringElementContentWhitespace(settings.isIgnoringElementContentWhitespace());
214 logSettings("\t[setting] ignoring-element-content-whitespace = "+settings.isIgnoringElementContentWhitespace());
215
216 factory.setValidating(project.getParser().isValidating());
217 logSettings("\t[setting] validating = "+project.getParser().isValidating());
218 factory.setNamespaceAware(project.getParser().isNamespaceAware());
219 logSettings("\t[setting] namespace-aware = "+project.getParser().isNamespaceAware());
220
221 try {
222 factory.setXIncludeAware(project.getParser().isXincludeAware());
223 logSettings("\t[setting] xinclude-aware = "+project.getParser().isXincludeAware());
224 } catch (UnsupportedOperationException e) {
225 logError("xinclude-aware setting not supported");
226 errors = true;
227 }
228
229 for (Feature feature : getDocumentBuilderFactoryFeatures()) {
230 try {
231 factory.setFeature( feature.getName(), feature.isEnabled());
232 logSettings( "\t[feature] "+feature.getName()+" = "+feature.isEnabled());
233 } catch (ParserConfigurationException e) {
234 logError(e);
235 errors = true;
236 }
237 }
238
239 for (Attribute attribute : getDocumentBuilderFactoryAttributes()) {
240 try {
241 factory.setAttribute( attribute.getName(), attribute.getValue());
242 logSettings( "\t[attribute] name = "+attribute.getName());
243 logSettings( "\t[attribute] value = "+attribute.getValue());
244 } catch (IllegalArgumentException e) {
245 logError("Attribute \""+attribute.getName()+"\" not recognized.");
246 errors = true;
247 }
248 }
249
250 if (project.getParser().getLanguage() != null) {
251 Schema schema = getSchema();
252
253 if ( schema != null) {
254 factory.setSchema( schema);
255 } else {
256 logSettings( "\t[attribute] name = http://java.sun.com/xml/jaxp/properties/schemaLanguage");
257 logSettings( "\t[attribute] value = "+project.getParser().getLanguage());
258
259 factory.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", project.getParser().getLanguage());
260 }
261 }
262 }
263
264 return factory;
265 }
266
267 public SAXParser getSAXParser() throws SAXException, ParserConfigurationException {
268 SAXParser parser = null;
269 SAXParserFactory factory = getSAXParserFactory();
270
271 if (factory != null) {
272 parser = factory.newSAXParser();
273
274 List<Property> properties = getSAXParserFactoryProperties();
275 for ( Property property : properties) {
276 try {
277 parser.setProperty( property.getName(), property.getValue());
278 logSettings( "\t[property] name = "+property.getName());
279 logSettings( "\t[property] value = "+property.getValue());
280 } catch (SAXException e) {
281 logError(e);
282 errors = true;
283 }
284 }
285
286 if (project.getParser().getLanguage() != null && factory.getSchema() == null) {
287 logSettings("\t[property] name = http://java.sun.com/xml/jaxp/properties/schemaLanguage");
288 logSettings("\t[property] value = "+project.getParser().getLanguage());
289
290 try {
291 parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", project.getParser().getLanguage());
292 } catch (SAXException e) {
293 logError(e);
294 errors = true;
295 }
296 }
297 }
298
299 return parser;
300 }
301
302 private synchronized SAXParserFactory getSAXParserFactory() throws SAXException {
303 logSettings("info: javax.xml.parsers.SAXParserFactory");
304
305 JAXPSAXParserFactory.Settings settings = getSAXParserSettings();
306
307 SAXParserFactory factory = null;
308
309 String previous = System.getProperty("javax.xml.parsers.SAXParserFactory");
310
311 try {
312 if (settings.getValue() != null) {
313 setProperty("javax.xml.parsers.SAXParserFactory", settings.getValue());
314 }
315
316 factory = SAXParserFactory.newInstance();
317 } catch (FactoryConfigurationError e) {
318 logFatal(e);
319 fatal = true;
320 } finally {
321 setProperty("javax.xml.parsers.SAXParserFactory", previous);
322 }
323
324 if (factory != null) {
325 logSettings("\t[class] "+factory.getClass().getName());
326
327 factory.setValidating( project.getParser().isValidating());
328 logSettings("\t[setting] validating = "+project.getParser().isValidating());
329 factory.setNamespaceAware( project.getParser().isNamespaceAware());
330 logSettings("\t[setting] namespace-aware = "+project.getParser().isNamespaceAware());
331 try {
332 factory.setXIncludeAware(project.getParser().isXincludeAware());
333 logSettings("\t[setting] xinclude-aware = "+project.getParser().isXincludeAware());
334 } catch (UnsupportedOperationException e) {
335 logError("xinclude-aware setting not supported");
336 errors = true;
337 }
338
339 for (Feature feature : getSAXParserFactoryFeatures()) {
340 try {
341 factory.setFeature( feature.getName(), feature.isEnabled());
342 logSettings("\t[feature] "+feature.getName()+" = "+feature.isEnabled());
343 } catch (ParserConfigurationException e) {
344 logError(e);
345 errors = true;
346 } catch (SAXException e) {
347 logError(e);
348 errors = true;
349 }
350 }
351
352 if (project.getParser().getLanguage() != null) {
353 Schema schema = getSchema();
354
355 if ( schema != null) {
356 factory.setSchema( schema);
357 }
358 }
359 }
360
361 return factory;
362 }
363
364 public synchronized SchemaFactory getSchemaFactory(String schemaLanguage) {
365 logSettings("info: javax.xml.validation.SchemaFactory:"+schemaLanguage);
366
367 HashMap<String,String> schemaFactories = new HashMap<String, String>();
368 SchemaFactory factory = null;
369
370 try {
371 for (SchemaFactoryProperty language : getSchemaFactoryLanguageProperties()) {
372 String factoryClass = language.getFactory();
373 String lang = language.getLanguage();
374
375 if (factoryClass != null && lang != null && factoryClass.trim().length() > 0 && lang.length() > 0) {
376 schemaFactories.put(lang, System.getProperty("javax.xml.validation.SchemaFactory:"+lang));
377 System.setProperty("javax.xml.validation.SchemaFactory:"+lang, factoryClass);
378 }
379 }
380
381 factory = SchemaFactory.newInstance(schemaLanguage);
382 } catch (IllegalArgumentException e) {
383 logFatal("Unable to create \""+schemaLanguage+"\" SchemaFactory instance.");
384 fatal = true;
385 } finally {
386 for (String language : schemaFactories.keySet()) {
387 String factoryClass = schemaFactories.get(language);
388
389 if (factory != null && factoryClass != null && factoryClass.trim().length() > 0) {
390 System.setProperty("javax.xml.validation.SchemaFactory:"+language, factoryClass);
391 } else {
392 System.clearProperty("javax.xml.validation.SchemaFactory:"+language);
393 }
394 }
395 }
396
397 if (factory != null) {
398 logSettings("\t[class] "+factory.getClass().getName());
399
400 for (Feature feature : getSchemaFactoryFeatures()) {
401 try {
402 factory.setFeature( feature.getName(), feature.isEnabled());
403 logSettings("\t[feature] "+feature.getName()+" = "+feature.isEnabled());
404 } catch (SAXNotRecognizedException e) {
405 logError(e);
406 errors = true;
407 } catch (SAXNotSupportedException e) {
408 logError(e);
409 errors = true;
410 }
411 }
412
413 for (Property property : getSchemaFactoryProperties()) {
414 try {
415 factory.setProperty( property.getName(), property.getValue());
416 logSettings("\t[property] name = "+property.getName());
417 logSettings("\t[property] value = "+property.getValue());
418 } catch (SAXNotRecognizedException e) {
419 logError(e);
420 errors = true;
421 } catch (SAXNotSupportedException e) {
422 logError(e);
423 errors = true;
424 }
425 }
426 }
427
428 return factory;
429 }
430
431 public Schema getSchema() throws SAXException {
432 Schema result = null;
433 SchemaFactory factory = getSchemaFactory(project.getParser().getLanguage());
434
435 if (factory != null) {
436 DefaultErrorHandler handler = new DefaultErrorHandler(null);
437 factory.setErrorHandler(handler);
438
439 List<org.xmlhammer.model.project.Source> uris = project.getParser().getSource();
440 if ( uris.size() > 0) {
441 Source[] sources = new Source[uris.size()];
442
443 for ( int i = 0; i < uris.size(); i++) {
444 sources[i] = new StreamSource(uris.get(i).getSrc());
445 logSettings("\t[schema] "+uris.get(i).getSrc());
446 }
447
448 try {
449 result = factory.newSchema( sources);
450 } catch (SAXException e) {
451 if (e instanceof SAXParseException) {
452 handler.fatalError((SAXParseException)e);
453 }
454 }
455 }
456
457 logErrors(handler);
458
459 Exception fatal = handler.getFatal();
460 if (fatal != null) {
461 throw (SAXException)fatal;
462 }
463 }
464
465 return result;
466 }
467
468 public TransformerFactory getTransformerFactory() {
469 logSettings("info: javax.xml.transform.TransformerFactory");
470
471 JAXPTransformerFactory.Settings settings = getTransformerFactorySettings();
472
473 TransformerFactory factory = null;
474 String previous = System.getProperty("javax.xml.transform.TransformerFactory");
475
476 try {
477 if (settings.getValue() != null) {
478 setProperty("javax.xml.transform.TransformerFactory", settings.getValue());
479 }
480
481 factory = TransformerFactory.newInstance();
482 } catch (TransformerFactoryConfigurationError e) {
483 logFatal(e);
484 fatal = true;
485 } finally {
486 setProperty("javax.xml.transform.TransformerFactory", previous);
487 }
488
489 if (factory != null) {
490 logSettings( "\t[class] "+factory.getClass().getName());
491
492 for (Feature feature : getTransformerFactoryFeatures()) {
493 try {
494 factory.setFeature(feature.getName(), feature.isEnabled());
495 logSettings("\t[feature] "+feature.getName()+" = "+feature.isEnabled());
496 } catch(TransformerConfigurationException e) {
497 logError(e);
498 errors = true;
499 }
500 }
501
502 for (Attribute attribute : getTransformerFactoryAttributes()) {
503 try {
504 factory.setAttribute(attribute.getName(), attribute.getValue());
505 logSettings("\t[attribute] name = "+attribute.getName());
506 logSettings("\t[attribute] value = "+attribute.getValue());
507 } catch (IllegalArgumentException e) {
508 logError("Attribute \""+attribute.getName()+"\" not recognized.");
509 errors = true;
510 }
511 }
512 }
513
514 return factory;
515 }
516
517 private void logError(String string) {
518 logger.info(formatString("error", string));
519 }
520
521 private void logError(ParserConfigurationException e) {
522 logger.info(formatThrowable("error", e));
523 }
524
525 private void logError(Exception e) {
526 logger.info(formatThrowable("error", e));
527 }
528
529 protected void logError(Throwable t) {
530 logger.info(formatThrowable("error", t));
531 }
532
533 private void logFatal(String string) {
534 logger.info(formatString("fatal", string));
535 }
536
537 private void logFatal(Exception e) {
538 logger.info(formatThrowable("fatal", e));
539 }
540
541 protected void logFatal(Throwable t) {
542 logger.info(formatThrowable("fatal", t));
543 }
544
545 private void logErrors(DefaultErrorHandler handler) {
546 ArrayList<Problem> list = handler.getProblems();
547 if ( list.size() > 0) {
548 for ( Problem problem : list) {
549 if ( problem instanceof Warning) {
550 logger.info(formatThrowable("warn", problem.getException()));
551 warnings = true;
552 } else if ( problem instanceof Error) {
553 logger.info(formatThrowable("error", problem.getException()));
554 errors = true;
555 } else if ( problem instanceof Fatal) {
556 logger.info(formatThrowable("fatal", problem.getException()));
557 }
558 }
559 }
560 }
561
562 private static String formatException(String level, SAXParseException e) {
563 StringBuilder builder = new StringBuilder();
564
565 builder.append("\t[");
566 builder.append(level);
567 builder.append("] ");
568
569 builder.append(format(null, e));
570
571 return builder.toString();
572 }
573
574 private static String formatString(String level, String string) {
575 StringBuilder builder = new StringBuilder();
576
577 builder.append("\t[");
578 builder.append(level);
579 builder.append("] ");
580 builder.append(string);
581
582 return builder.toString();
583 }
584
585 private static String formatThrowable(String level, Throwable e) {
586 if (e instanceof SAXParseException) {
587 return formatException(level, (SAXParseException)e);
588 }
589
590
591
592
593
594
595 StringBuilder builder = new StringBuilder();
596
597 builder.append("\t[");
598 builder.append(level);
599 builder.append("] ");
600 builder.append(e.getLocalizedMessage());
601
602 return builder.toString();
603 }
604
605 public Project getProject() {
606 return project;
607 }
608
609 public Preferences getPreferences() {
610 return preferences;
611 }
612
613 public CatalogResolver getCatalogResolver() {
614 return new CatalogResolver();
615 }
616
617 protected void logError(URI base, SAXParseException exception) {
618 logger.info( "\t[error] "+format(base, exception));
619 }
620
621 protected void logError(URI base, TransformerException exception) {
622 logger.info( "\t[error] "+format(base, exception));
623 }
624
625 protected void logWarning(URI base, SAXParseException exception) {
626 logger.info( "\t[warn] "+format(base, exception));
627 }
628
629 protected void logWarning(URI base, TransformerException exception) {
630 logger.info( "\t[warn] "+format(base, exception));
631 }
632
633 protected void logFatal(URI base, Exception exception) {
634 logger.info( "\t[fatal] "+format(base, exception));
635 }
636
637 private static String format(URI base, Exception exception) {
638 if (exception instanceof SAXParseException) {
639 return format(base, (SAXParseException)exception);
640 }
641
642 return exception.getLocalizedMessage();
643 }
644
645 private static String format(URI base, SAXParseException exception) {
646 StringBuilder builder = new StringBuilder();
647
648 if (exception.getSystemId() != null) {
649 URI systemId = URIUtils.createURI(exception.getSystemId());
650
651 if (base == null || base.compareTo(systemId) != 0) {
652 builder.append(URIUtils.getName(systemId));
653 builder.append(" - ");
654 }
655 }
656
657 if (exception.getLineNumber() != -1) {
658 builder.append("[");
659 builder.append(exception.getLineNumber());
660 builder.append(":");
661 builder.append(exception.getColumnNumber());
662 builder.append("] ");
663 }
664
665 builder.append(exception.getLocalizedMessage());
666
667 return builder.toString();
668 }
669
670 private static String format(URI base, TransformerException exception) {
671 StringBuilder builder = new StringBuilder();
672
673 if (exception.getLocator() != null) {
674 if (exception.getLocator().getSystemId() != null) {
675 URI systemId = URIUtils.createURI(exception.getLocator().getSystemId());
676
677 if (base == null || base.compareTo(systemId) != 0) {
678 builder.append(URIUtils.getName(systemId));
679 builder.append(" - ");
680 }
681 }
682
683 if (exception.getLocator().getLineNumber() != -1) {
684 builder.append("[");
685 builder.append(exception.getLocator().getLineNumber());
686 builder.append(":");
687 builder.append(exception.getLocator().getColumnNumber());
688 builder.append("] ");
689 }
690 }
691
692 builder.append(exception.getLocalizedMessage());
693
694 return builder.toString();
695 }
696
697 protected Logger getLogger() {
698 return logger;
699 }
700
701 protected void logSettings(String info) {
702 if (isLogSettings()) {
703 logger.info(info);
704 }
705 }
706
707 public boolean hasFatal() {
708 return fatal;
709 }
710
711 public boolean hasErrors() {
712 return errors;
713 }
714
715 public boolean hasWarnings() {
716 return warnings;
717 }
718
719 private void setProperty(String property, String value) {
720 if (value != null) {
721 System.setProperty(property, value);
722 } else {
723 System.clearProperty(property);
724 }
725 }
726 }