java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java
changeset 34 5af9c7693d70
parent 32 ecc2731a5a46
child 36 ad36a104623f
     1.1 --- a/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java	Sat Jun 07 22:12:11 2014 +0200
     1.2 +++ b/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java	Sat Jun 07 23:17:59 2014 +0200
     1.3 @@ -20,6 +20,7 @@
     1.4  import java.util.Deque;
     1.5  import java.util.LinkedList;
     1.6  import java.util.ServiceLoader;
     1.7 +import javax.xml.parsers.FactoryConfigurationError;
     1.8  import javax.xml.parsers.ParserConfigurationException;
     1.9  import javax.xml.parsers.SAXParser;
    1.10  import javax.xml.parsers.SAXParserFactory;
    1.11 @@ -36,6 +37,16 @@
    1.12  public class ParserFactory extends SAXParserFactory implements ReaderFinder {
    1.13  
    1.14  	private final Deque<Alt2XmlReaderFactory> readerFactories = new LinkedList();
    1.15 +	/**
    1.16 +	 * @see #DEFAULT_FACTORY_PROPERTY
    1.17 +	 */
    1.18 +	private SAXParserFactory fallbackFactory;
    1.19 +
    1.20 +	/**
    1.21 +	 * System property which contains SAXParserFactory class name for XML.
    1.22 +	 * Will be used as fallback if no alternative factory matches systemId to be parsed.
    1.23 +	 */
    1.24 +	public static final String DEFAULT_FACTORY_PROPERTY = "cz.frantovo.alt2xml.fallback.javax.xml.parsers.SAXParserFactory";
    1.25  
    1.26  	public ParserFactory() {
    1.27  		super();
    1.28 @@ -43,6 +54,51 @@
    1.29  			readerFactories.add(f);
    1.30  		}
    1.31  
    1.32 +		readerFactories.add(new FallbackReaderFactory());
    1.33 +	}
    1.34 +
    1.35 +	/**
    1.36 +	 * @return factory to be used for XML documents (default/fallback)
    1.37 +	 * @throws FactoryConfigurationError if fallback factory is the same one as this – avoid
    1.38 +	 * infinite recursion.
    1.39 +	 */
    1.40 +	public SAXParserFactory getFallbackFactory() {
    1.41 +		if (fallbackFactory == null) {
    1.42 +			String className = System.getProperty(DEFAULT_FACTORY_PROPERTY);
    1.43 +			if (className == null) {
    1.44 +				fallbackFactory = SAXParserFactory.newInstance();
    1.45 +			} else {
    1.46 +				fallbackFactory = SAXParserFactory.newInstance(className, null);
    1.47 +			}
    1.48 +		}
    1.49 +
    1.50 +		if (fallbackFactory.getClass().equals(getClass())) {
    1.51 +			throw new FactoryConfigurationError("Fallback factory is the same class as this one – avoid infinite recursion: " + getClass());
    1.52 +		} else {
    1.53 +			return fallbackFactory;
    1.54 +		}
    1.55 +	}
    1.56 +
    1.57 +	public void setFallbackFactory(SAXParserFactory fallbackFactory) {
    1.58 +		this.fallbackFactory = fallbackFactory;
    1.59 +	}
    1.60 +
    1.61 +	private class FallbackReaderFactory implements Alt2XmlReaderFactory {
    1.62 +
    1.63 +		@Override
    1.64 +		public boolean canRead(String systemId) {
    1.65 +			return true;
    1.66 +		}
    1.67 +
    1.68 +		@Override
    1.69 +		public XMLReader getReader() throws SAXException {
    1.70 +
    1.71 +			try {
    1.72 +				return getFallbackFactory().newSAXParser().getXMLReader();
    1.73 +			} catch (ParserConfigurationException e) {
    1.74 +				throw new SAXException("Unable to instantiate the fallback factory.", e);
    1.75 +			}
    1.76 +		}
    1.77  	}
    1.78  
    1.79  	@Override
    1.80 @@ -60,6 +116,9 @@
    1.81  		return new AltSAXParser(new SuperReader(this));
    1.82  	}
    1.83  
    1.84 +	/**
    1.85 +	 * TODO: feature for disabling default SAXParserFactory
    1.86 +	 */
    1.87  	@Override
    1.88  	public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
    1.89  		throw new SAXNotSupportedException("Zatím není podporováno.");