• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmd / pmd / 353

16 Jan 2026 01:01PM UTC coverage: 78.957% (-0.02%) from 78.976%
353

push

github

adangel
[core] Fix #6184: More consistent enum properties (#6233)

18529 of 24342 branches covered (76.12%)

Branch coverage included in aggregate %.

146 of 164 new or added lines in 20 files covered. (89.02%)

6 existing lines in 5 files now uncovered.

40349 of 50228 relevant lines covered (80.33%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.1
/pmd-core/src/main/java/net/sourceforge/pmd/util/internal/xml/XmlUtil.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.util.internal.xml;
6

7
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.ERR__MISSING_REQUIRED_ELEMENT;
8
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__DUPLICATE_CHILD_ELEMENT;
9
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__UNEXPECTED_ELEMENT;
10
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__UNEXPECTED_ELEMENT_IN;
11

12
import java.util.List;
13
import java.util.Objects;
14
import java.util.Set;
15
import java.util.stream.Collectors;
16
import java.util.stream.Stream;
17

18
import org.checkerframework.checker.nullness.qual.Nullable;
19
import org.w3c.dom.Element;
20
import org.w3c.dom.Node;
21

22
import net.sourceforge.pmd.util.CollectionUtil;
23
import net.sourceforge.pmd.util.StringUtil;
24

25
import com.github.oowekyala.ooxml.DomUtils;
26

27
public final class XmlUtil {
28

29
    private XmlUtil() {
30

31
    }
32

33
    public static Stream<Element> getElementChildren(Element parent) {
34
        return DomUtils.asList(parent.getChildNodes()).stream()
1✔
35
                       .filter(it -> it.getNodeType() == Node.ELEMENT_NODE)
1✔
36
                       .map(Element.class::cast);
1✔
37
    }
38

39
    public static List<Element> getElementChildrenList(Element parent) {
40
        return getElementChildren(parent).collect(Collectors.toList());
1✔
41
    }
42

43
    public static Stream<Element> getElementChildrenNamed(Element parent, Set<SchemaConstant> names) {
44
        return getElementChildren(parent).filter(e -> matchesName(e, names));
1✔
45
    }
46

47
    public static Stream<Element> getElementChildrenNamedReportOthers(Element parent, Set<SchemaConstant> names, PmdXmlReporter err) {
48
        return getElementChildren(parent)
1✔
49
            .map(it -> {
1✔
50
                if (matchesName(it, names)) {
1!
51
                    return it;
1✔
52
                } else {
53
                    err.at(it).warn(IGNORED__UNEXPECTED_ELEMENT_IN, it.getTagName(), formatPossibleNames(names));
×
54
                    return null;
×
55
                }
56
            }).filter(Objects::nonNull);
1✔
57
    }
58

59
    public static boolean matchesName(Element elt, Set<SchemaConstant> names) {
60
        return names.stream().anyMatch(it -> it.xmlName().equals(elt.getTagName()));
1✔
61
    }
62

63
    public static void reportIgnoredUnexpectedElt(Element parent,
64
                                                  Element unexpectedChild,
65
                                                  Set<SchemaConstant> names,
66
                                                  PmdXmlReporter err) {
67
        err.at(unexpectedChild).warn(IGNORED__UNEXPECTED_ELEMENT,
×
68
                                     unexpectedChild.getTagName(),
×
69
                                     parent.getTagName(),
×
70
                                     formatPossibleNames(names));
×
71
    }
×
72

73
    public static Stream<Element> getElementChildrenNamed(Element parent, String name) {
74
        return getElementChildren(parent).filter(e -> name.equals(e.getTagName()));
×
75
    }
76

77

78
    public static List<Element> getChildrenExpectSingleName(Element elt, String name, PmdXmlReporter err) {
79
        return XmlUtil.getElementChildren(elt).peek(it -> {
×
80
            if (!it.getTagName().equals(name)) {
×
81
                err.at(it).warn(IGNORED__UNEXPECTED_ELEMENT_IN, it.getTagName(), name);
×
82
            }
83
        }).collect(Collectors.toList());
×
84
    }
85

86
    public static Element getSingleChildIn(Element elt, boolean throwOnMissing, PmdXmlReporter err, Set<SchemaConstant> names) {
87
        List<Element> children = getElementChildrenNamed(elt, names).collect(Collectors.toList());
1✔
88
        if (children.size() == 1) {
1✔
89
            return children.get(0);
1✔
90
        } else if (children.isEmpty()) {
1!
91
            if (throwOnMissing) {
1!
92
                throw err.at(elt).error(ERR__MISSING_REQUIRED_ELEMENT, formatPossibleNames(names));
×
93
            } else {
94
                return null;
1✔
95
            }
96
        } else {
97
            for (int i = 1; i < children.size(); i++) {
×
98
                Element child = children.get(i);
×
99
                err.at(child).warn(IGNORED__DUPLICATE_CHILD_ELEMENT, child.getTagName());
×
100
            }
101
            return children.get(0);
×
102
        }
103
    }
104

105
    public static Set<SchemaConstant> toConstants(Set<String> names) {
106
        return CollectionUtil.map(Collectors.toSet(), names, SchemaConstant::new);
1✔
107
    }
108

109
    public static @Nullable String formatPossibleNames(Set<SchemaConstant> names) {
110
        if (names.isEmpty()) {
1!
111
            return null;
×
112
        } else if (names.size() == 1) {
1!
UNCOV
113
            return StringUtil.inSingleQuotes(names.iterator().next().xmlName());
×
114
        } else {
115
            return "one of " + names.stream()
1✔
116
                                    .map(SchemaConstant::xmlName)
1✔
117
                                    .map(StringUtil::inSingleQuotes)
1✔
118
                                    .collect(Collectors.joining(", "));
1✔
119
        }
120
    }
121

122
    /**
123
     * Parse a String from a textually type node.
124
     *
125
     * @param node The node.
126
     *
127
     * @return The String.
128
     */
129
    public static String parseTextNode(Node node) {
130
        final int nodeCount = node.getChildNodes().getLength();
1✔
131
        if (nodeCount == 0) {
1✔
132
            return "";
1✔
133
        }
134

135
        StringBuilder buffer = new StringBuilder();
1✔
136

137
        for (int i = 0; i < nodeCount; i++) {
1✔
138
            Node childNode = node.getChildNodes().item(i);
1✔
139
            if (childNode.getNodeType() == Node.CDATA_SECTION_NODE || childNode.getNodeType() == Node.TEXT_NODE) {
1✔
140
                buffer.append(childNode.getNodeValue());
1✔
141
            }
142
        }
143
        return buffer.toString();
1✔
144
    }
145

146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc