diff -r e853e5b5bfdf -r 5af9c7693d70 java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java --- a/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java Sat Jun 07 22:12:11 2014 +0200 +++ b/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java Sat Jun 07 23:17:59 2014 +0200 @@ -20,6 +20,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.ServiceLoader; +import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; @@ -36,6 +37,16 @@ public class ParserFactory extends SAXParserFactory implements ReaderFinder { private final Deque readerFactories = new LinkedList(); + /** + * @see #DEFAULT_FACTORY_PROPERTY + */ + private SAXParserFactory fallbackFactory; + + /** + * System property which contains SAXParserFactory class name for XML. + * Will be used as fallback if no alternative factory matches systemId to be parsed. + */ + public static final String DEFAULT_FACTORY_PROPERTY = "cz.frantovo.alt2xml.fallback.javax.xml.parsers.SAXParserFactory"; public ParserFactory() { super(); @@ -43,6 +54,51 @@ readerFactories.add(f); } + readerFactories.add(new FallbackReaderFactory()); + } + + /** + * @return factory to be used for XML documents (default/fallback) + * @throws FactoryConfigurationError if fallback factory is the same one as this – avoid + * infinite recursion. + */ + public SAXParserFactory getFallbackFactory() { + if (fallbackFactory == null) { + String className = System.getProperty(DEFAULT_FACTORY_PROPERTY); + if (className == null) { + fallbackFactory = SAXParserFactory.newInstance(); + } else { + fallbackFactory = SAXParserFactory.newInstance(className, null); + } + } + + if (fallbackFactory.getClass().equals(getClass())) { + throw new FactoryConfigurationError("Fallback factory is the same class as this one – avoid infinite recursion: " + getClass()); + } else { + return fallbackFactory; + } + } + + public void setFallbackFactory(SAXParserFactory fallbackFactory) { + this.fallbackFactory = fallbackFactory; + } + + private class FallbackReaderFactory implements Alt2XmlReaderFactory { + + @Override + public boolean canRead(String systemId) { + return true; + } + + @Override + public XMLReader getReader() throws SAXException { + + try { + return getFallbackFactory().newSAXParser().getXMLReader(); + } catch (ParserConfigurationException e) { + throw new SAXException("Unable to instantiate the fallback factory.", e); + } + } } @Override @@ -60,6 +116,9 @@ return new AltSAXParser(new SuperReader(this)); } + /** + * TODO: feature for disabling default SAXParserFactory + */ @Override public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { throw new SAXNotSupportedException("Zatím není podporováno.");