DivisionXMLParser.java

package com.tradecloud.domain.helper;

import com.tradecloud.domain.common.Percentage;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.rate.RateSourceType;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class DivisionXMLParser extends DefaultHandler {

    List<OrganisationalUnit> divisions = new ArrayList<OrganisationalUnit>();

    public List<OrganisationalUnit> parse(InputStream in) throws XPathExpressionException, ParserConfigurationException, IOException, SAXException {

        Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(in));

        NodeList organisationalUnitCodes = xPathMultiNode("//OrganisationalUnit/code/text()", document);

        for (int i = 0; i < organisationalUnitCodes.getLength(); i++) {

            String organisationalUnitCode = organisationalUnitCodes.item(i).getNodeValue();
            String organisationalUnitName = xPathValue("//OrganisationalUnit[code=" + organisationalUnitCode + "]/name", document);
            String spotRateMarginValue =
                    xPathValue("//OrganisationalUnit[code=" + organisationalUnitCode
                            + "]/rules/rule/attribute[name='spot_rate_margin']/value/text()", document);
            String forwardRateMarginValue =
                    xPathValue("//OrganisationalUnit[code=" + organisationalUnitCode
                            + "]/rules/rule/attribute[name='forward_rate_margin']/value/text()", document);
            String rateSource =
                    xPathValue("//OrganisationalUnit[code=" + organisationalUnitCode + "]/rules/rule/attribute[name='rate_source']/value/text()",
                            document);

            Percentage spotRateMargin =
                    (spotRateMarginValue != null && !spotRateMarginValue.isEmpty()) ? new Percentage(new BigDecimal(spotRateMarginValue)) : null;
            Percentage forwardRateMargin =
                    (forwardRateMarginValue != null && !forwardRateMarginValue.isEmpty()) ? new Percentage(new BigDecimal(forwardRateMarginValue))
                            : null;

            OrganisationalUnit organisationalUnit =
                    OrganisationalUnit.valueOf(organisationalUnitCode, organisationalUnitName, 0, RateSourceType.valueOf(rateSource),
                            spotRateMargin, forwardRateMargin);
            divisions.add(organisationalUnit);
        }

        return divisions;
    }

    private String xPathValue(String expression, Document document) throws XPathExpressionException {
        String result = null;
        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression initialIdValue = xPath.compile(expression);

        result = initialIdValue.evaluate(document);
        return result;
    }

    public NodeList xPathMultiNode(String expression, Document document) throws XPathExpressionException {
        XPath xPath = XPathFactory.newInstance().newXPath();
        XPathExpression initialIdValue = xPath.compile(expression);

        NodeList nodes = (NodeList) initialIdValue.evaluate(document, XPathConstants.NODESET);
        return nodes;
    }

    public List<OrganisationalUnit> getOrganisationalUnits() {
        return divisions;
    }
}