class TraxUtils {

	public static void doWithSource(Source source, SourceCallback callback) throws Exception {
		if (source instanceof DOMSource) {
			callback.domSource(((DOMSource) source).getNode());
			return;
		} else if (StaxUtils.isStaxSource(source)) {
			XMLStreamReader streamReader = StaxUtils.getXMLStreamReader(source);
			if (streamReader != null) {
				callback.staxSource(streamReader);
				return;
			} else {
				XMLEventReader eventReader = StaxUtils.getXMLEventReader(source);
				if (eventReader != null) {
					callback.staxSource(eventReader);
					return;
				}
			}
		} else if (source instanceof SAXSource) {
			SAXSource saxSource = (SAXSource) source;
			callback.saxSource(saxSource.getXMLReader(), saxSource.getInputSource());
			return;
		} else if (source instanceof StreamSource) {
			StreamSource streamSource = (StreamSource) source;
			if (streamSource.getInputStream() != null) {
				callback.streamSource(streamSource.getInputStream());
				return;
			} else if (streamSource.getReader() != null) {
				callback.streamSource(streamSource.getReader());
				return;
			}
		}
		if (StringUtils.hasLength(source.getSystemId())) {
			String systemId = source.getSystemId();
			callback.source(systemId);
		} else {
			throw new IllegalArgumentException("Unknown Source type: " + source.getClass());
		}
	}

}

class TraxUtilsTest {

	@Test
	public void testDoWithStaxSourceEventReader() throws Exception {

		XMLInputFactory inputFactory = XMLInputFactoryUtils.newInstance();
		XMLEventReader eventReader = inputFactory.createXMLEventReader(new StringReader("<element/>"));

		TraxUtils.SourceCallback mock = createMock(TraxUtils.SourceCallback.class);
		mock.staxSource(eventReader);

		replay(mock);

		TraxUtils.doWithSource(StaxUtils.createStaxSource(eventReader), mock);

		verify(mock);
	}

}