nl.dedicon.pipeline.braille.step.NotesMover Maven / Gradle / Ivy
package nl.dedicon.pipeline.braille.step;
import java.util.HashMap;
import java.util.Map;
import java.util.function.UnaryOperator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Move notes right after the parent node of their corresponding noteref
*
* @author Paul Rambags
*/
public class NotesMover {
private static final String NOTE = "note";
private static final String NOTEREF = "noteref";
private static final String ID = "id";
private static final String IDREF = "idref";
private final Map notes = new HashMap<>(); // id -> Element(note)
private final Map noterefs = new HashMap<>(); // idref -> Element(noteref)
public void collectNotesAndNoterefs(Document document) {
collect(document, notes, NOTE, ID, s -> s);
collect(document, noterefs, NOTEREF, IDREF, s -> s.replaceFirst("^#", ""));
}
private static void collect(Document document, Map map, String nodeName, String attributeName, UnaryOperator attributeFormatter) {
String namespace = document.getDocumentElement().getNamespaceURI();
NodeList nodeList = document.getElementsByTagNameNS(namespace, nodeName);
for (int i = 0; i < nodeList.getLength(); ++i) {
Element element = (Element)nodeList.item(i);
String attributeValue = element.getAttribute(attributeName);
if (attributeValue != null && attributeValue.length() > 0) {
map.put(attributeFormatter.apply(attributeValue), element);
}
}
}
public void moveNotes() {
notes.entrySet().stream().forEach(e -> {
String id = e.getKey();
Element note = e.getValue();
Element noteref = noterefs.get(id);
if (noteref == null) {
// note without noteref
return;
}
Node parent = noteref.getParentNode();
if (parent == null) {
return;
}
Node grandParent = parent.getParentNode();
if (grandParent == null) {
return;
}
grandParent.insertBefore(note, parent.getNextSibling());
});
}
}