package com.tecspy.xmlutil;

import org.apache.log4j.Logger;
import javax.xml.stream.*;

/**
 * A test for the capabilities of multiple Stax implementations.
 * 
 * Inspired by Anghel Leonard on DevX Tip Of The Day
 * http://www.devx.com/tips/Tip/30772
 * 
 * @author Michael Erskine
 * 
 */
public class StaxImplCaps {

	/** Standard Log4J logging */
	static Logger log = Logger.getLogger(StaxImplCaps.class);

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// Woodstox implementation...
		checkInputFactoryCaps("com.ctc.wstx.stax.WstxInputFactory");
		// BEA implementation...
		checkInputFactoryCaps("com.bea.xml.stream.MXParserFactory");
		// Sun implementation...
		checkInputFactoryCaps("com.sun.xml.stream.ZephyrParserFactory");
		// non-existent implementation...
		checkInputFactoryCaps("dunno");

		log.info("finished!");

	}

	/**
	 * the factory finder failure can kill a thread with an uncatchable
	 * throwable and we particularly want to continue so...
	 * 
	 * @param implementation
	 */
	public static void checkInputFactoryCaps(final String implementation) {
		Thread t = new Thread() {
			public void run() {
				checkInputFactoryCaps2(implementation);
			}
		};
		t.start();
		try {
			t.join();
		} catch (InterruptedException e) {
			log.fatal("ugh", e);
		}

	}

	/**
	 * Test the capabilities of an XMLInputFactory implementation and display
	 * the results.
	 * 
	 * @param implementation
	 */
	public static void checkInputFactoryCaps2(String implementation) {
		log.info("testing '" + implementation + "'");
		// system property for XMLInputFactory - save old value to replace it
		// later
		String sysprop = "javax.xml.stream.XMLInputFactory";
		// use summat like this if you need to replace the implementation at
		// runtime
		// String oldimpl = System.getProperty(sysprop);
		System.setProperty(sysprop, implementation);

		// we will be testing these properties
		String[] props = { "javax.xml.stream.isValidating",
				"javax.xml.stream.isNamespaceAware",
				"javax.xml.stream.isCoalescing",
				"javax.xml.stream.isReplacingEntityReferences",
				"javax.xml.stream.isSupportingExternalEntities",
				"javax.xml.stream.supportDTD" };
		XMLInputFactory XMLif = null;

		// get an XMLInputFactory instance

		try {
			XMLif = XMLInputFactory.newInstance();
		} catch (Exception e1) {
			log.fatal("ugh" + e1.getMessage());
		}

		for (int val = 1; val >= 0; val--) {
			Boolean testValue = (val == 1 ? Boolean.TRUE : Boolean.FALSE);
			log.info("Testing value " + testValue);
			for (int i = 0; i < props.length; i++) {
				String msg = "set prop " + props[i] + " " + testValue + " : ";
				try {
					XMLif.setProperty(props[i], testValue);
					log.info(msg + "OK");
				} catch (java.lang.IllegalArgumentException e) {
					log.error(msg + e.getMessage());
				}
			}
		}
	}
}
