RrdpParser { public void parseDelta(InputStream inputStream, Consumer<DeltaHeader> processDeltaHeader, Consumer<DeltaElement> processDeltaElement) { try { final XMLInputFactory factory = XMLInputFactory.newInstance(); final XMLEventReader eventReader = factory.createXMLEventReader(inputStream); String sessionId = null; BigInteger serial = null; String uri = null; String hash = null; StringBuilder base64 = new StringBuilder(); boolean inPublishElement = false; boolean deltaHeaderProcessed = false; final Base64.Decoder decoder = Base64.getDecoder(); while (eventReader.hasNext()) { final XMLEvent event = eventReader.nextEvent(); switch (event.getEventType()) { case XMLStreamConstants.START_ELEMENT: final StartElement startElement = event.asStartElement(); final String qName = startElement.getName().getLocalPart(); switch (qName) { case "publish": if (!deltaHeaderProcessed) { throw new RrdpException(ErrorCodes.RRDP_PARSE_ERROR, "delta header not present before elements"); } uri = getAttr(startElement, "uri", "Uri is not present in 'publish' element"); hash = getAttr(startElement, "hash"); inPublishElement = true; break; case "withdraw": if (!deltaHeaderProcessed) { throw new RrdpException(ErrorCodes.RRDP_PARSE_ERROR, "delta header not present before elements"); } uri = getAttr(startElement, "uri", "Uri is not present in 'publish' element"); hash = getAttr(startElement, "hash", "Hash is not present in 'withdraw' element"); break; case "delta": serial = new BigInteger(getAttr(startElement, "serial", "Notification serial is not present")); sessionId = getAttr(startElement, "session_id", "Session id is not present"); processDeltaHeader.accept(new DeltaHeader(sessionId, serial)); deltaHeaderProcessed = true; break; } break; case XMLStreamConstants.CHARACTERS: final Characters characters = event.asCharacters(); if (inPublishElement) { final String thisBase64 = characters.getData(); base64.append(thisBase64.replaceAll("\\s", "")); } break; case XMLStreamConstants.END_ELEMENT: final EndElement endElement = event.asEndElement(); final String qqName = endElement.getName().getLocalPart(); switch (qqName) { case "publish": final byte[] decoded = decoder.decode(base64.toString()); base64 = new StringBuilder(); processDeltaElement.accept(new DeltaPublish(decoded, uri, Hex.parse(hash))); break; case "withdraw": processDeltaElement.accept(new DeltaWithdraw(uri, Hex.parse(hash))); break; } break; } } } catch (XMLStreamException e) { throw new RrdpException("Couldn't parse delta: ", e); } }  void parseSnapshot(InputStream inputStream, Consumer<SnapshotHeader> processSnapshotHeader, Consumer<SnapshotObject> processSnapshotObject); void parseDelta(InputStream inputStream, Consumer<DeltaHeader> processDeltaHeader, Consumer<DeltaElement> processDeltaElement); Notification notification(final InputStream inputStream);  }
@Test public void should_parse_delta() throws Exception { Map<String, DeltaElement> delta = new HashMap<>(); new RrdpParser().parseDelta( fileIS("rrdp/delta1.xml"), (deltaHeader) -> { assertEquals("9df4b597-af9e-4dca-bdda-719cce2c4e28", deltaHeader.getSessionId()); assertEquals(BigInteger.valueOf(2), deltaHeader.getSerial()); }, (deltaElement) -> delta.put(deltaElement.getUri(), deltaElement) ); final String uri1 = "rsync: DeltaElement e1 = delta.get(uri1); assertEquals(uri1, ((DeltaPublish)e1).uri); assertEquals("226AB8CD3C887A6EBDDDF317F2FAFC9CF3EFC5D43A86347AC0FEFFE4DC0F607E", Hex.format(((DeltaPublish)e1).getHash().get())); final String uri2 = "rsync: DeltaElement e2 = delta.get(uri2); assertEquals(uri2, ((DeltaPublish)e2).uri); assertEquals("2B551A6C10CCA04C174B0CEB3B64652A5534D1385BEAA40A55A68CB06055E6BB", Hex.format(((DeltaPublish)e2).getHash().get())); final String uri3 = "rsync: DeltaElement e3 = delta.get(uri3); assertEquals(uri3, ((DeltaWithdraw)e3).uri); assertEquals("2B551A6C10CCA04C174B0CEB3B64652A5534D1385BEAA40A55A68CB06055E6BB", Hex.format(((DeltaWithdraw) e3).getHash())); }