From 09eed2f0fce49775611b2405f7779dd43f8834c0 Mon Sep 17 00:00:00 2001 From: Pablo Herrera Date: Fri, 13 Oct 2023 20:22:29 +0200 Subject: [PATCH] Add support for deleting nodes with constants Signed-off-by: Pablo Herrera --- .../tc/oc/pgm/map/MapFilePreprocessor.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/tc/oc/pgm/map/MapFilePreprocessor.java b/core/src/main/java/tc/oc/pgm/map/MapFilePreprocessor.java index ec3ad9b474..f7f4a04ff2 100644 --- a/core/src/main/java/tc/oc/pgm/map/MapFilePreprocessor.java +++ b/core/src/main/java/tc/oc/pgm/map/MapFilePreprocessor.java @@ -21,6 +21,7 @@ import org.jdom2.JDOMException; import org.jdom2.Text; import org.jdom2.input.SAXBuilder; +import org.jetbrains.annotations.Nullable; import tc.oc.pgm.api.map.MapSource; import tc.oc.pgm.api.map.exception.MapMissingException; import tc.oc.pgm.api.map.includes.MapInclude; @@ -92,7 +93,12 @@ public Document getDocument() for (Element constant : XMLUtils.flattenElements(document.getRootElement(), "constants", "constant", 0)) { - constants.put(XMLUtils.parseRequiredId(constant), constant.getText()); + boolean isDelete = XMLUtils.parseBoolean(constant.getAttribute("delete"), false); + String text = constant.getText(); + if ((text == null || text.isEmpty()) != isDelete) + throw new InvalidXMLException( + "Delete attribute cannot be combined with having an inner text", constant); + constants.put(XMLUtils.parseRequiredId(constant), isDelete ? null : constant.getText()); } // If no constants are set, assume we can skip the step @@ -158,7 +164,9 @@ private List processConditional(Element el, boolean shouldContain) private void postprocessChildren(Element parent) throws InvalidXMLException { for (Attribute attribute : parent.getAttributes()) { - attribute.setValue(postprocessString(parent, attribute.getValue())); + String result = postprocessString(parent, attribute.getValue()); + if (result == null) parent.removeAttribute(attribute); + else attribute.setValue(result); } for (int i = 0; i < parent.getContentSize(); i++) { @@ -167,22 +175,29 @@ private void postprocessChildren(Element parent) throws InvalidXMLException { postprocessChildren((Element) content); } else if (content instanceof Text) { Text text = (Text) content; - text.setText(postprocessString(parent, text.getText())); + + String result = postprocessString(parent, text.getText()); + if (result == null) parent.removeContent(text); + else text.setText(result); } } } - private String postprocessString(Element el, String text) throws InvalidXMLException { + private @Nullable String postprocessString(Element el, String text) throws InvalidXMLException { Matcher matcher = CONSTANT_PATTERN.matcher(text); StringBuffer result = new StringBuffer(); while (matcher.find()) { String constant = matcher.group(1); - String replacement = constants.get(matcher.group(1)); - if (replacement == null) - throw new InvalidXMLException( - "No constant '" + constant + "' is used but has not been defined", el); - + String replacement = constants.get(constant); + if (replacement == null) { + if (!constants.containsKey(constant)) { + throw new InvalidXMLException( + "Constant '" + constant + "' is used but has not been defined", el); + } else { + return null; + } + } matcher.appendReplacement(result, replacement); } matcher.appendTail(result);