Fallback SAXParserFactory
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 07 Jun 2014 23:17:59 +0200
changeset 345af9c7693d70
parent 33 e853e5b5bfdf
child 35 106c5d280835
Fallback SAXParserFactory
→ we can parse also pure/standard XML files
→ seamless integration of multiple formats
java/alt2xml-cli/nbproject/project.properties
java/alt2xml-lib-input/dist/alt2xml-lib-input.jar
java/alt2xml-lib-input/src/cz/frantovo/alt2xml/Alt2XmlReaderFactory.java
java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java
scripts/alt2xml.sh
     1.1 --- a/java/alt2xml-cli/nbproject/project.properties	Sat Jun 07 22:12:11 2014 +0200
     1.2 +++ b/java/alt2xml-cli/nbproject/project.properties	Sat Jun 07 23:17:59 2014 +0200
     1.3 @@ -64,10 +64,6 @@
     1.4  run.classpath=\
     1.5      ${javac.classpath}:\
     1.6      ${build.classes.dir}
     1.7 -# Space-separated list of JVM arguments used when running the project
     1.8 -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
     1.9 -# or test-sys-prop.name=value to set system properties for unit tests):
    1.10 -run.jvmargs=
    1.11  run.test.classpath=\
    1.12      ${javac.test.classpath}:\
    1.13      ${build.test.classes.dir}
     2.1 Binary file java/alt2xml-lib-input/dist/alt2xml-lib-input.jar has changed
     3.1 --- a/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/Alt2XmlReaderFactory.java	Sat Jun 07 22:12:11 2014 +0200
     3.2 +++ b/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/Alt2XmlReaderFactory.java	Sat Jun 07 23:17:59 2014 +0200
     3.3 @@ -17,6 +17,7 @@
     3.4   */
     3.5  package cz.frantovo.alt2xml;
     3.6  
     3.7 +import org.xml.sax.SAXException;
     3.8  import org.xml.sax.XMLReader;
     3.9  
    3.10  /**
    3.11 @@ -31,5 +32,5 @@
    3.12  	 */
    3.13  	public boolean canRead(String systemId);
    3.14  
    3.15 -	public XMLReader getReader();
    3.16 +	public XMLReader getReader() throws SAXException;
    3.17  }
     4.1 --- a/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java	Sat Jun 07 22:12:11 2014 +0200
     4.2 +++ b/java/alt2xml-lib-input/src/cz/frantovo/alt2xml/ParserFactory.java	Sat Jun 07 23:17:59 2014 +0200
     4.3 @@ -20,6 +20,7 @@
     4.4  import java.util.Deque;
     4.5  import java.util.LinkedList;
     4.6  import java.util.ServiceLoader;
     4.7 +import javax.xml.parsers.FactoryConfigurationError;
     4.8  import javax.xml.parsers.ParserConfigurationException;
     4.9  import javax.xml.parsers.SAXParser;
    4.10  import javax.xml.parsers.SAXParserFactory;
    4.11 @@ -36,6 +37,16 @@
    4.12  public class ParserFactory extends SAXParserFactory implements ReaderFinder {
    4.13  
    4.14  	private final Deque<Alt2XmlReaderFactory> readerFactories = new LinkedList();
    4.15 +	/**
    4.16 +	 * @see #DEFAULT_FACTORY_PROPERTY
    4.17 +	 */
    4.18 +	private SAXParserFactory fallbackFactory;
    4.19 +
    4.20 +	/**
    4.21 +	 * System property which contains SAXParserFactory class name for XML.
    4.22 +	 * Will be used as fallback if no alternative factory matches systemId to be parsed.
    4.23 +	 */
    4.24 +	public static final String DEFAULT_FACTORY_PROPERTY = "cz.frantovo.alt2xml.fallback.javax.xml.parsers.SAXParserFactory";
    4.25  
    4.26  	public ParserFactory() {
    4.27  		super();
    4.28 @@ -43,6 +54,51 @@
    4.29  			readerFactories.add(f);
    4.30  		}
    4.31  
    4.32 +		readerFactories.add(new FallbackReaderFactory());
    4.33 +	}
    4.34 +
    4.35 +	/**
    4.36 +	 * @return factory to be used for XML documents (default/fallback)
    4.37 +	 * @throws FactoryConfigurationError if fallback factory is the same one as this – avoid
    4.38 +	 * infinite recursion.
    4.39 +	 */
    4.40 +	public SAXParserFactory getFallbackFactory() {
    4.41 +		if (fallbackFactory == null) {
    4.42 +			String className = System.getProperty(DEFAULT_FACTORY_PROPERTY);
    4.43 +			if (className == null) {
    4.44 +				fallbackFactory = SAXParserFactory.newInstance();
    4.45 +			} else {
    4.46 +				fallbackFactory = SAXParserFactory.newInstance(className, null);
    4.47 +			}
    4.48 +		}
    4.49 +
    4.50 +		if (fallbackFactory.getClass().equals(getClass())) {
    4.51 +			throw new FactoryConfigurationError("Fallback factory is the same class as this one – avoid infinite recursion: " + getClass());
    4.52 +		} else {
    4.53 +			return fallbackFactory;
    4.54 +		}
    4.55 +	}
    4.56 +
    4.57 +	public void setFallbackFactory(SAXParserFactory fallbackFactory) {
    4.58 +		this.fallbackFactory = fallbackFactory;
    4.59 +	}
    4.60 +
    4.61 +	private class FallbackReaderFactory implements Alt2XmlReaderFactory {
    4.62 +
    4.63 +		@Override
    4.64 +		public boolean canRead(String systemId) {
    4.65 +			return true;
    4.66 +		}
    4.67 +
    4.68 +		@Override
    4.69 +		public XMLReader getReader() throws SAXException {
    4.70 +
    4.71 +			try {
    4.72 +				return getFallbackFactory().newSAXParser().getXMLReader();
    4.73 +			} catch (ParserConfigurationException e) {
    4.74 +				throw new SAXException("Unable to instantiate the fallback factory.", e);
    4.75 +			}
    4.76 +		}
    4.77  	}
    4.78  
    4.79  	@Override
    4.80 @@ -60,6 +116,9 @@
    4.81  		return new AltSAXParser(new SuperReader(this));
    4.82  	}
    4.83  
    4.84 +	/**
    4.85 +	 * TODO: feature for disabling default SAXParserFactory
    4.86 +	 */
    4.87  	@Override
    4.88  	public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException {
    4.89  		throw new SAXNotSupportedException("Zatím není podporováno.");
     5.1 --- a/scripts/alt2xml.sh	Sat Jun 07 22:12:11 2014 +0200
     5.2 +++ b/scripts/alt2xml.sh	Sat Jun 07 23:17:59 2014 +0200
     5.3 @@ -19,7 +19,14 @@
     5.4  done
     5.5  
     5.6  MAIN_CLASS="cz.frantovo.alt2xml.cli.CLI";
     5.7 -SAX_PARSER_FACTORY="cz.frantovo.alt2xml.ParserFactory";
     5.8  
     5.9 -java -cp "$CLASS_PATH" -D"javax.xml.parsers.SAXParserFactory=$SAX_PARSER_FACTORY" $MAIN_CLASS "$@"
    5.10 +SAX_PARSER_FACTORY_ALT="cz.frantovo.alt2xml.ParserFactory";                             # our alternative ParserFactory as default
    5.11 +SAX_PARSER_FACTORY_XML="com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";  # former default factory as fallback 
    5.12  
    5.13 +java \
    5.14 +	-cp "$CLASS_PATH" \
    5.15 +	-D"javax.xml.parsers.SAXParserFactory=$SAX_PARSER_FACTORY_ALT" \
    5.16 +	-D"cz.frantovo.alt2xml.fallback.javax.xml.parsers.SAXParserFactory=$SAX_PARSER_FACTORY_XML" \
    5.17 +	$MAIN_CLASS \
    5.18 +	"$@"
    5.19 +