package beaform.importer;

import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public final class Importer {

	private static final File SCHEMA = new File("xml-schemas/input.xsd");

	private Importer() {
		// A utility class doesn't need a public constructor.
	}

	public static boolean importFromFile(final File input) throws ImporterException {

		validateXmlFile(input);

		final SAXParserFactory factory = SAXParserFactory.newInstance();
		final SAXParser parser;
		try {
			parser = factory.newSAXParser();
		}
		catch (ParserConfigurationException | SAXException e) {
			throw new ImporterException("There was a problem setting up the parser", e);
		}

		final ImporterHandler handler = new ImporterHandler();
		try {
			parser.parse(input, handler);
		}
		catch (SAXException | IOException e) {
			throw new ImporterException("There was a problem parsing the input file", e);
		}

		// The map should be empty now.
		final boolean noPendingIngredients = handler.getPendingIngredients() == 0;
		assert noPendingIngredients;
		return noPendingIngredients;
	}

	private static void validateXmlFile(final File input) throws ImporterException {
		SchemaFactory schemaFactory = SchemaFactory
						.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		try {
			Schema schema = schemaFactory.newSchema(SCHEMA);
			SAXParserFactory saxFactory = SAXParserFactory.newInstance();
			saxFactory.setSchema(schema);
			SAXParser parser = saxFactory.newSAXParser();
			parser.parse(input, new DefaultHandler() {
				@Override
				public void error(SAXParseException e) throws SAXException {
					throw e;
				}
			});
		}
		catch (SAXException | IOException | ParserConfigurationException e) {
			throw new ImporterException("Unable to validate the XML", e);
		}
	}

}

@@ -39,40 +39,136 @@
 .io.
-File;%0Aimport java.io.IOException
+BufferedInputStream;%0Aimport java.io.File;%0Aimport java.io.FileInputStream;%0Aimport java.io.IOException;%0Aimport java.io.InputStream
 ;%0A%0Ai
@@ -411,16 +411,48 @@
 ctory;%0A%0A
+import org.xml.sax.InputSource;%0A
 import o
@@ -506,32 +506,62 @@
 ParseException;%0A
+import org.xml.sax.XMLReader;%0A
 import org.xml.s
@@ -586,16 +586,61 @@
 Handler;
+%0Aimport org.xml.sax.helpers.XMLReaderFactory;
 %0A%0Apublic
@@ -941,89 +941,22 @@
 nal 
-SAXParserFactory factory = SAXParserFactory.newInstance();%0A%09%09final SAXParser pars
+XMLReader read
 er;%0A
@@ -970,85 +970,66 @@
 %0A%09%09%09
-pars
+read
 er = 
-factory.newSAXParser();%0A%09%09%7D%0A%09%09catch (ParserConfigurationException %7C 
+XMLReaderFactory.createXMLReader();%0A%09%09%7D%0A%09%09catch (
 SAXE
@@ -1194,43 +1194,176 @@
 try 
-%7B%0A%09%09%09parser.parse(input, handler
+(InputStream inputStream = new BufferedInputStream(new FileInputStream(input))) %7B%0A%09%09%09reader.setContentHandler(handler);%0A%09%09%09reader.parse(new InputSource(inputStream)
 );%0A
+%0A
 %09%09%7D%0A

Use the XMLReader interface for reading XML data