BRPXMLReader.java
/*
* Copyright (C) 2017 B3Partners B.V.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package nl.b3p.brmo.loader.xml;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import nl.b3p.brmo.loader.BrmoFramework;
import nl.b3p.brmo.loader.StagingProxy;
import nl.b3p.brmo.loader.entity.Bericht;
import nl.b3p.brmo.loader.util.RsgbTransformer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author Meine Toonen
*/
public class BRPXMLReader extends BrmoXMLReader {
private InputStream in;
private NodeList nodes = null;
private int index;
private Templates template;
private final String pathToXsl = "/xsl/brp-brxml-preprocessor.xsl";
public static final String PREFIX = "NL.BRP.Persoon.";
private StagingProxy staging;
public BRPXMLReader(InputStream in, Date d, StagingProxy staging) throws Exception {
this.in = in;
this.staging = staging;
setBestandsDatum(d);
init();
}
@Override
public void init() throws Exception {
soort = BrmoFramework.BR_BRP;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(in);
TransformerFactory tf = TransformerFactory.newInstance();
tf.setURIResolver(
(href, base) ->
new StreamSource(RsgbTransformer.class.getResourceAsStream("/xsl/" + href)));
Source xsl = new StreamSource(BRPXMLReader.class.getResourceAsStream(pathToXsl));
this.template = tf.newTemplates(xsl);
nodes = doc.getDocumentElement().getChildNodes();
index = 0;
}
@Override
public boolean hasNext() throws Exception {
return index < nodes.getLength();
}
@Override
public Bericht next() throws Exception {
Node n = nodes.item(index);
index++;
String object_ref = getObjectRef(n);
StringWriter sw = new StringWriter();
Bericht old =
staging.getPreviousBericht(object_ref, getBestandsDatum(), -1L, new StringBuilder());
// kijk hier of dit bericht een voorganger heeft: zo niet, dan moet niet de preprocessor
// template gebruikt worden, maar de gewone.
Transformer t;
if (old != null) {
t = this.template.newTransformer();
} else {
t = TransformerFactory.newInstance().newTransformer();
}
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(n), new StreamResult(sw)); // new StreamResult(outputStream));
Map<String, String> bsns = extractBSN(n);
String el = getXML(bsns);
String origXML = sw.toString();
String brXML = "<root>" + origXML;
brXML += el + "</root>";
Bericht b = new Bericht(brXML);
b.setBrOrgineelXml(origXML);
b.setVolgordeNummer(index);
b.setObjectRef(object_ref);
b.setSoort(BrmoFramework.BR_BRP);
b.setDatum(getBestandsDatum());
return b;
}
private String getObjectRef(Node n) {
NodeList childs = n.getChildNodes();
String hash = null;
for (int i = 0; i < childs.getLength(); i++) {
Node child = childs.item(i);
String name = child.getNodeName();
if (name.contains("bsn-nummer")) {
hash = child.getTextContent();
hash = getHash(hash);
break;
}
}
return PREFIX + hash;
}
/**
* maakt een map met bsn,bsnhash.
*
* @param n document node met bsn-nummer
* @return hashmap met bsn,bsnhash
* @throws XPathExpressionException if any
*/
public Map<String, String> extractBSN(Node n) throws XPathExpressionException {
Map<String, String> hashes = new HashMap<>();
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//*[local-name() = 'bsn-nummer']");
NodeList nodelist = (NodeList) expr.evaluate(n, XPathConstants.NODESET);
for (int i = 0; i < nodelist.getLength(); i++) {
Node bsn = nodelist.item(i);
String bsnString = bsn.getTextContent();
String hash = getHash(bsnString);
hashes.put(bsnString, hash);
}
return hashes;
}
public String getXML(Map<String, String> map) throws ParserConfigurationException {
String root = "<bsnhashes>";
for (Entry<String, String> entry : map.entrySet()) {
if (!entry.getKey().isEmpty() && !entry.getValue().isEmpty()) {
String hash = entry.getValue();
String el =
"<" + PREFIX + entry.getKey() + ">" + hash + "</" + PREFIX + entry.getKey() + ">";
root += el;
}
}
root += "</bsnhashes>";
return root;
}
}