RrdpParser { public void parseSnapshot(InputStream inputStream, Consumer<SnapshotHeader> processSnapshotHeader, Consumer<SnapshotObject> processSnapshotObject) { try { final XMLInputFactory factory = XMLInputFactory.newInstance(); final XMLEventReader eventReader = factory.createXMLEventReader(inputStream); String sessionId = null; BigInteger serial = null; String uri = null; StringBuilder base64 = new StringBuilder(); boolean inPublishElement = false; boolean snapshotHeaderProcessed = 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().toLowerCase(Locale.ROOT); switch (qName) { case "publish": if (!snapshotHeaderProcessed) { throw new RrdpException(ErrorCodes.RRDP_PARSE_ERROR, "snapshot header not present before published objects"); } uri = getAttr(startElement, "uri", "Uri is not present in 'publish' element"); inPublishElement = true; break; case "snapshot": serial = new BigInteger(getAttr(startElement, "serial", "Notification serial is not present")); sessionId = getAttr(startElement, "session_id", "Session id is not present"); processSnapshotHeader.accept(new SnapshotHeader(sessionId, serial)); snapshotHeaderProcessed = 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().toLowerCase(Locale.ROOT); if ("publish".equals(qqName)) { final byte[] decoded = decoder.decode(base64.toString()); processSnapshotObject.accept(new SnapshotObject(decoded, uri)); inPublishElement = false; base64 = new StringBuilder(); } break; } } } catch (XMLStreamException e) { throw new RrdpException("Couldn't parse snapshot: ", 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_snapshot() throws Exception { new RrdpParser().parseSnapshot( fileIS("rrdp/snapshot1.xml"), (snapshotInfo) -> { assertEquals("9df4b597-af9e-4dca-bdda-719cce2c4e28", snapshotInfo.getSessionId()); assertEquals(BigInteger.ONE, snapshotInfo.getSerial()); }, (snapshotObject) -> { assertEquals("rsync: } ); }