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

pkiraly / metadata-qa-api / #717

28 Aug 2025 09:15AM UTC coverage: 86.426% (-0.1%) from 86.526%
#717

push

pkiraly
Add priorityOnFail

12 of 23 new or added lines in 4 files covered. (52.17%)

3 existing lines in 2 files now uncovered.

5654 of 6542 relevant lines covered (86.43%)

0.86 hits per line

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

73.5
/src/main/java/de/gwdg/metadataqa/api/xml/XPathWrapper.java
1
package de.gwdg.metadataqa.api.xml;
2

3
import de.gwdg.metadataqa.api.model.EdmFieldInstance;
4
import org.w3c.dom.Document;
5
import org.w3c.dom.NamedNodeMap;
6
import org.w3c.dom.Node;
7
import org.w3c.dom.NodeList;
8
import org.xml.sax.SAXException;
9

10
import javax.xml.parsers.DocumentBuilder;
11
import javax.xml.parsers.DocumentBuilderFactory;
12
import javax.xml.parsers.ParserConfigurationException;
13
import javax.xml.xpath.XPath;
14
import javax.xml.xpath.XPathConstants;
15
import javax.xml.xpath.XPathExpression;
16
import javax.xml.xpath.XPathExpressionException;
17

18
import java.io.ByteArrayInputStream;
19
import java.io.File;
20
import java.io.IOException;
21
import java.io.InputStream;
22
import java.io.Serializable;
23
import java.nio.charset.StandardCharsets;
24
import java.util.ArrayList;
25
import java.util.HashMap;
26
import java.util.List;
27
import java.util.Map;
28
import java.util.logging.Level;
29
import java.util.logging.Logger;
30

31
public class XPathWrapper implements Serializable {
32
  private static final long serialVersionUID = 3040547541095974755L;
33

34
  private static final Logger LOGGER = Logger.getLogger(XPathWrapper.class.getCanonicalName());
1✔
35

36
  private static transient XPath xpathEngine;
37
  private static final DocumentBuilder builder = initializeDocumentBuilder();
1✔
38
  private static transient Map<String, String> namespaces;
39
  private boolean namespaceChanged = false;
1✔
40
  private static Map<String, XPathExpression> xpathCache = new HashMap<>();
1✔
41

42
  private static DocumentBuilder initializeDocumentBuilder() {
43
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1✔
44
    factory.setNamespaceAware(true);
1✔
45
    DocumentBuilder builder = null;
1✔
46
    try {
47
      builder = factory.newDocumentBuilder();
1✔
48
    } catch (ParserConfigurationException e) {
×
49
      e.printStackTrace();
×
50
    }
1✔
51
    return builder;
1✔
52
  }
53

54
  Document document;
55

56
  public XPathWrapper(String input) {
1✔
57
    parseContent(input);
1✔
58
  }
1✔
59

60
  public XPathWrapper(String input, Map<String, String> customNamespaces) {
1✔
61
    if (customNamespaces != null && this.namespaces != customNamespaces) {
1✔
62
      namespaceChanged = true;
1✔
63
      this.namespaces = customNamespaces;
1✔
64
    }
65
    parseContent(input);
1✔
66
  }
1✔
67

68
  public XPathWrapper(File input) {
1✔
69
    parseFile(input.getPath());
1✔
70
  }
1✔
71

72
  public XPathWrapper(File input, Map<String, String> customNamespaces) {
×
73
    if (this.namespaces != customNamespaces) {
×
74
      namespaceChanged = true;
×
75
      this.namespaces = customNamespaces;
×
76
    }
77
    parseFile(input.getPath());
×
78
  }
×
79

80
  private void initialize() {
81
    if (xpathEngine == null || namespaceChanged) {
1✔
82
      LOGGER.info("initialize xpathEngine");
1✔
83
      if (namespaces == null) {
1✔
UNCOV
84
        LOGGER.info("initialize without namespaces");
×
UNCOV
85
        xpathEngine = XpathEngineFactory.initializeEngine();
×
86
      } else {
87
        xpathEngine = XpathEngineFactory.initializeEngine(namespaces);
1✔
88
      }
89
    }
90
  }
1✔
91

92
  public XPathWrapper(String input, boolean fromString) {
×
93
    if (fromString) {
×
94
      parseContent(input);
×
95
    } else {
96
      parseFile(input);
×
97
    }
98
  }
×
99

100
  private void parseFile(String path) {
101
    initialize();
1✔
102
    try {
103
      document = builder.parse(path);
1✔
104
    } catch (SAXException e) {
×
105
      e.printStackTrace();
×
106
    } catch (IOException e) {
×
107
      LOGGER.log(Level.WARNING, "buildUrl", e);
×
108
    }
1✔
109
  }
1✔
110

111
  public void parseContent(String content) {
112
    initialize();
1✔
113
    parseContent(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
1✔
114
  }
1✔
115

116
  private void parseContent(InputStream content) {
117
    try {
118
      document = builder.parse(content);
1✔
119
    } catch (SAXException e) {
×
120
      e.printStackTrace();
×
121
    } catch (IOException e) {
×
122
      LOGGER.log(Level.WARNING, "parseContent", e);
×
123
    }
1✔
124
  }
1✔
125

126
  public List<EdmFieldInstance> extractFieldInstanceList(String xpath) {
127
    return extractFieldInstanceList(document, xpath);
1✔
128
  }
129

130
  public List<EdmFieldInstance> extractFieldInstanceList(Object context, String xpath) {
131
    List<EdmFieldInstance> list = new ArrayList<>();
1✔
132
    try {
133
      if (!xpathCache.containsKey(xpath))
1✔
134
        xpathCache.put(xpath, xpathEngine.compile(xpath));
1✔
135
      XPathExpression expr = xpathCache.get(xpath);
1✔
136
      if (xpath.endsWith(")")) {
1✔
137
        String value = String.valueOf(expr.evaluate(context, XPathConstants.STRING));
×
138
        list.add(new EdmFieldInstance(value, null, null));
×
139
      } else {
×
140
        NodeList nodes = (NodeList) expr.evaluate(context, XPathConstants.NODESET);
1✔
141
        for (var i = 0; i < nodes.getLength(); i++) {
1✔
142
          Node node = nodes.item(i);
1✔
143
          if (node.getNodeType() == Node.ELEMENT_NODE) {
1✔
144
            String value = node.getTextContent().trim();
1✔
145
            if (value.contains("\n"))
1✔
146
              value = value.replaceAll("(\\r|\\n)", " ").replaceAll("\\s+", " ");
1✔
147
            String lang = null;
1✔
148
            String resource = null;
1✔
149
            if (node.hasAttributes()) {
1✔
150
              NamedNodeMap attributes = node.getAttributes();
1✔
151
              lang = getAttribute(attributes, "xml", "lang");
1✔
152
              resource = getAttribute(attributes, "rdf", "resource");
1✔
153
            }
154
            list.add(new EdmFieldInstance(value, lang, resource));
1✔
155
          } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
1✔
156
            String value = node.getNodeValue();
1✔
157
            list.add(new EdmFieldInstance(value, null, null));
1✔
158
          }
159
        }
160
      }
161
    } catch (XPathExpressionException e) {
×
162
      LOGGER.log(Level.WARNING, "error in extractFieldInstanceList() with xpath: '" + xpath + "' " + e.getMessage());
×
163
    }
1✔
164
    return list;
1✔
165
  }
166

167
  public List<Node> extractNodes(String xpath) {
168
    return extractNodes(document, xpath);
1✔
169
  }
170

171
  public List<Node> extractNodes(Object context, String xpath) {
172
    List<Node> list = new ArrayList<>();
1✔
173
    try {
174
      XPathExpression expr = xpathEngine.compile(xpath);
1✔
175
      NodeList nodes = (NodeList) expr.evaluate(context, XPathConstants.NODESET);
1✔
176
      for (var i = 0; i < nodes.getLength(); i++) {
1✔
177
        Node node = nodes.item(i);
1✔
178
        if (node.getNodeType() == Node.ELEMENT_NODE) {
1✔
179
          list.add(node);
1✔
180
        } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
1✔
181
          list.add(node);
1✔
182
        }
183
      }
184
    } catch (XPathExpressionException e) {
×
185
      LOGGER.log(Level.WARNING, "extractNodes", e);
×
186
    }
1✔
187
    return list;
1✔
188
  }
189

190
  public String getAttribute(NamedNodeMap attributes, String prefix, String name) {
191
    Node attribute = attributes.getNamedItemNS(xpathEngine.getNamespaceContext().getNamespaceURI(prefix), name);
1✔
192
    String value = null;
1✔
193
    if (attribute != null) {
1✔
194
      value = attribute.getNodeValue();
1✔
195
      if (value != null)
1✔
196
        value = value.trim();
1✔
197
    }
198
    return value;
1✔
199
  }
200

201
  public XPath getXpathEngine() {
202
    return xpathEngine;
1✔
203
  }
204

205
  public Document getDocument() {
206
    return document;
×
207
  }
208

209
  public static void setXpathEngine(XPath xpathEngine) {
210
    XPathWrapper.xpathEngine = xpathEngine;
1✔
211
  }
1✔
212

213
  public static void setXpathEngine(Map<String, String> namespaces) {
214
    xpathEngine = XpathEngineFactory.initializeEngine(namespaces);
1✔
215
  }
1✔
216
}
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