View Javadoc
1   /*
2    * Copyright (C) 2017 B3Partners B.V.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU Affero General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU Affero General Public License for more details.
13   *
14   * You should have received a copy of the GNU Affero General Public License
15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16   */
17  package nl.b3p.brmo.loader.xml;
18  
19  import java.io.InputStream;
20  import java.io.StringWriter;
21  import java.util.Date;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Map.Entry;
25  import javax.xml.parsers.DocumentBuilder;
26  import javax.xml.parsers.DocumentBuilderFactory;
27  import javax.xml.parsers.ParserConfigurationException;
28  import javax.xml.transform.OutputKeys;
29  import javax.xml.transform.Source;
30  import javax.xml.transform.Templates;
31  import javax.xml.transform.Transformer;
32  import javax.xml.transform.TransformerFactory;
33  import javax.xml.transform.dom.DOMSource;
34  import javax.xml.transform.stream.StreamResult;
35  import javax.xml.transform.stream.StreamSource;
36  import javax.xml.xpath.XPath;
37  import javax.xml.xpath.XPathConstants;
38  import javax.xml.xpath.XPathExpression;
39  import javax.xml.xpath.XPathExpressionException;
40  import javax.xml.xpath.XPathFactory;
41  import nl.b3p.brmo.loader.BrmoFramework;
42  import nl.b3p.brmo.loader.StagingProxy;
43  import nl.b3p.brmo.loader.entity.Bericht;
44  import nl.b3p.brmo.loader.util.RsgbTransformer;
45  import org.w3c.dom.Document;
46  import org.w3c.dom.Node;
47  import org.w3c.dom.NodeList;
48  
49  /**
50   * @author Meine Toonen
51   */
52  public class BRPXMLReader extends BrmoXMLReader {
53  
54    private InputStream in;
55    private NodeList nodes = null;
56    private int index;
57  
58    private Templates template;
59    private final String pathToXsl = "/xsl/brp-brxml-preprocessor.xsl";
60  
61    public static final String PREFIX = "NL.BRP.Persoon.";
62    private StagingProxy staging;
63  
64    public BRPXMLReader(InputStream in, Date d, StagingProxy staging) throws Exception {
65      this.in = in;
66      this.staging = staging;
67      setBestandsDatum(d);
68      init();
69    }
70  
71    @Override
72    public void init() throws Exception {
73      soort = BrmoFramework.BR_BRP;
74      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
75      factory.setNamespaceAware(true);
76      DocumentBuilder builder = factory.newDocumentBuilder();
77      Document doc = builder.parse(in);
78  
79      TransformerFactory tf = TransformerFactory.newInstance();
80      tf.setURIResolver(
81          (href, base) ->
82              new StreamSource(RsgbTransformer.class.getResourceAsStream("/xsl/" + href)));
83  
84      Source xsl = new StreamSource(BRPXMLReader.class.getResourceAsStream(pathToXsl));
85      this.template = tf.newTemplates(xsl);
86  
87      nodes = doc.getDocumentElement().getChildNodes();
88      index = 0;
89    }
90  
91    @Override
92    public boolean hasNext() throws Exception {
93      return index < nodes.getLength();
94    }
95  
96    @Override
97    public Bericht next() throws Exception {
98      Node n = nodes.item(index);
99      index++;
100     String object_ref = getObjectRef(n);
101     StringWriter sw = new StringWriter();
102     Bericht old =
103         staging.getPreviousBericht(object_ref, getBestandsDatum(), -1L, new StringBuilder());
104 
105     // kijk hier of dit bericht een voorganger heeft: zo niet, dan moet niet de preprocessor
106     // template gebruikt worden, maar de gewone.
107 
108     Transformer t;
109 
110     if (old != null) {
111       t = this.template.newTransformer();
112     } else {
113       t = TransformerFactory.newInstance().newTransformer();
114     }
115 
116     t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
117     t.transform(new DOMSource(n), new StreamResult(sw)); // new StreamResult(outputStream));
118 
119     Map<String, String> bsns = extractBSN(n);
120 
121     String el = getXML(bsns);
122     String origXML = sw.toString();
123     String brXML = "<root>" + origXML;
124     brXML += el + "</root>";
125     Bericht b = new Bericht(brXML);
126     b.setBrOrgineelXml(origXML);
127     b.setVolgordeNummer(index);
128     b.setObjectRef(object_ref);
129     b.setSoort(BrmoFramework.BR_BRP);
130     b.setDatum(getBestandsDatum());
131     return b;
132   }
133 
134   private String getObjectRef(Node n) {
135     NodeList childs = n.getChildNodes();
136     String hash = null;
137     for (int i = 0; i < childs.getLength(); i++) {
138       Node child = childs.item(i);
139       String name = child.getNodeName();
140       if (name.contains("bsn-nummer")) {
141         hash = child.getTextContent();
142         hash = getHash(hash);
143         break;
144       }
145     }
146     return PREFIX + hash;
147   }
148 
149   /**
150    * maakt een map met bsn,bsnhash.
151    *
152    * @param n document node met bsn-nummer
153    * @return hashmap met bsn,bsnhash
154    * @throws XPathExpressionException if any
155    */
156   public Map<String, String> extractBSN(Node n) throws XPathExpressionException {
157     Map<String, String> hashes = new HashMap<>();
158 
159     XPathFactory xPathfactory = XPathFactory.newInstance();
160     XPath xpath = xPathfactory.newXPath();
161     XPathExpression expr = xpath.compile("//*[local-name() = 'bsn-nummer']");
162     NodeList nodelist = (NodeList) expr.evaluate(n, XPathConstants.NODESET);
163     for (int i = 0; i < nodelist.getLength(); i++) {
164       Node bsn = nodelist.item(i);
165       String bsnString = bsn.getTextContent();
166       String hash = getHash(bsnString);
167       hashes.put(bsnString, hash);
168     }
169     return hashes;
170   }
171 
172   public String getXML(Map<String, String> map) throws ParserConfigurationException {
173     String root = "<bsnhashes>";
174     for (Entry<String, String> entry : map.entrySet()) {
175       if (!entry.getKey().isEmpty() && !entry.getValue().isEmpty()) {
176         String hash = entry.getValue();
177 
178         String el =
179             "<" + PREFIX + entry.getKey() + ">" + hash + "</" + PREFIX + entry.getKey() + ">";
180         root += el;
181       }
182     }
183     root += "</bsnhashes>";
184     return root;
185   }
186 }