package com.formulasearchengine.mathmlquerygenerator;

import com.formulasearchengine.mathmltools.xmlhelper.XMLHelper;
import com.formulasearchengine.mathmltools.xmlhelper.NonWhitespaceNodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.formulasearchengine.mathmltools.xmlhelper.NonWhitespaceNodeList.getFirstChild;

/**
 * Created by Moritz on 08.11.2014.
 * <p/>
 * Reads the topic format specified in
 * http://ntcir-math.nii.ac.jp/wp-content/blogs.dir/13/files/2014/05/NTCIR11-Math-topics.pdf
 */
public class NtcirTopicReader {
    public static final String NS_NII = "http://ntcir-math.nii.ac.jp/";
    private final Document topics;
    private final List<NtcirPattern> patterns = new ArrayList<>();
    private final XQueryGenerator queryGenerator;

    public NtcirTopicReader(Document topics) {
        this.topics = topics;
        queryGenerator = new XQueryGenerator(topics);
    }

    public NtcirTopicReader(File topicFile) throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilder documentBuilder = XMLHelper.getDocumentBuilder(true);
        topics = documentBuilder.parse(topicFile);

        //TODO: Find out how this code duplication can be avoided in Java.
        queryGenerator = new XQueryGenerator(topics);
    }

    public NtcirTopicReader(Document topics, String namespace, String pathToRoot, String returnFormat, boolean restrictLength) {
        queryGenerator = new XQueryGenerator(topics);
        this.topics = topics;
        this.setNamespace(namespace).setReturnFormat(returnFormat).setPathToRoot(pathToRoot).setRestrictLength(restrictLength);
    }

    public final NtcirTopicReader setReturnFormat(String returnFormat) {
        queryGenerator.setReturnFormat(returnFormat);
        return this;
    }

    public final NtcirTopicReader setNamespace(String namespace) {
        queryGenerator.setNamespace(namespace);
        return this;
    }

    public final NtcirTopicReader setPathToRoot(String pathToRoot) {
        queryGenerator.setPathToRoot(pathToRoot);
        return this;
    }

    public final NtcirTopicReader setFindRootApply(boolean findRootApply) {
        queryGenerator.setFindRootApply(findRootApply);
        return this;
    }

    public final NtcirTopicReader setRestrictLength(boolean restrictLength) {
        queryGenerator.setRestrictLength(restrictLength);
        return this;
    }

    public final NtcirTopicReader setAddQvarMap(boolean addQvarMap) {
        queryGenerator.setAddQvarMap(addQvarMap);
        return this;
    }

    /**
     * Splits the given NTCIR query file into individual queries, converts each query into an XQuery using
     * XQueryGenerator, and returns the result as a list of NtcirPatterns for each individual query.
     *
     * @return List of NtcirPatterns for each query
     * @throws XPathExpressionException Thrown if xpaths fail to compile or fail to evaluate
     *                                  +
     */
    public final List<NtcirPattern> extractPatterns() throws XPathExpressionException {
        final XPath xpath = XMLHelper.namespaceAwareXpath("t", NS_NII);
        final XPathExpression xNum = xpath.compile("./t:num");
        final XPathExpression xFormula = xpath.compile("./t:query/t:formula");
        final NonWhitespaceNodeList topicList = new NonWhitespaceNodeList(
                topics.getElementsByTagNameNS(NS_NII, "topic"));
        for (final Node node : topicList) {
            final String num = xNum.evaluate(node);
            final NonWhitespaceNodeList formulae = new NonWhitespaceNodeList((NodeList)
                    xFormula.evaluate(node, XPathConstants.NODESET));
            for (final Node formula : formulae) {
                final String id = formula.getAttributes().getNamedItem("id").getTextContent();
                final Node mathMLNode = getFirstChild(formula);
                queryGenerator.setMainElement(getFirstChild(mathMLNode));
                patterns.add(new NtcirPattern(num, id, queryGenerator.toString(), mathMLNode));
            }
        }
        return patterns;
    }
}

@@ -101,25 +101,37 @@
 lhelper.
-XMLHelper
+NonWhitespaceNodeList
 ;%0Aimport
@@ -177,37 +177,25 @@
 lhelper.
-NonWhitespaceNodeList
+XMLHelper
 ;%0Aimport
@@ -425,17 +425,21 @@
 l.xpath.
-*
+XPath
 ;%0Aimport
@@ -439,24 +439,152 @@
 %0Aimport java
+x.xml.xpath.XPathConstants;%0Aimport javax.xml.xpath.XPathExpression;%0Aimport javax.xml.xpath.XPathExpressionException;%0Aimport java
 .io.File;%0Aim
@@ -611,36 +611,8 @@
 tion
-;%0Aimport java.util.ArrayList
 ;%0Aim
@@ -630,110 +630,40 @@
 til.
+Array
 List;%0A
-%0A
 import 
-static com.formulasearchengine.mathmltools.xmlhelper.NonWhitespaceNodeList.getFirstChild
+java.util.List
 ;%0A%0A/
@@ -4179,16 +4179,38 @@
 LNode = 
+NonWhitespaceNodeList.
 getFirst
@@ -4271,16 +4271,38 @@
 Element(
+NonWhitespaceNodeList.
 getFirst

Improve code style