1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.rat.testhelpers;
20
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.io.PrintStream;
29 import java.io.StringReader;
30 import java.lang.reflect.UndeclaredThrowableException;
31 import java.nio.charset.StandardCharsets;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35
36 import java.util.Map;
37 import javax.xml.parsers.DocumentBuilder;
38 import javax.xml.parsers.DocumentBuilderFactory;
39 import javax.xml.parsers.FactoryConfigurationError;
40 import javax.xml.parsers.ParserConfigurationException;
41 import javax.xml.parsers.SAXParserFactory;
42 import javax.xml.transform.OutputKeys;
43 import javax.xml.transform.Transformer;
44 import javax.xml.transform.TransformerException;
45 import javax.xml.transform.TransformerFactory;
46 import javax.xml.transform.dom.DOMSource;
47 import javax.xml.transform.stream.StreamResult;
48 import javax.xml.xpath.XPath;
49 import javax.xml.xpath.XPathConstants;
50 import javax.xml.xpath.XPathExpressionException;
51
52 import org.apache.rat.report.xml.writer.IXmlWriter;
53 import org.apache.rat.utils.DefaultLog;
54 import org.w3c.dom.Document;
55 import org.w3c.dom.NamedNodeMap;
56 import org.w3c.dom.Node;
57 import org.w3c.dom.NodeList;
58 import org.xml.sax.InputSource;
59 import org.xml.sax.SAXException;
60 import org.xml.sax.XMLReader;
61
62 public final class XmlUtils {
63
64
65
66 private XmlUtils() {
67
68 }
69
70 public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
71 final SAXParserFactory spf = SAXParserFactory.newInstance();
72 spf.setValidating(false);
73 spf.setNamespaceAware(true);
74 return spf.newSAXParser().getXMLReader();
75 }
76
77 public static boolean isWellFormedXml(final String string) {
78 return isWellFormedXml(new InputSource(new StringReader(string)));
79 }
80
81 public static boolean isWellFormedXml(final InputStream in) {
82 return isWellFormedXml(new InputSource(in));
83 }
84
85 public static boolean isWellFormedXml(final InputSource isource) {
86 try {
87 newXMLReader().parse(isource);
88 return true;
89 } catch (SAXException e) {
90 DefaultLog.getInstance().error(e.getMessage(), e);
91 return false;
92 } catch (IOException | ParserConfigurationException e) {
93 throw new UndeclaredThrowableException(e);
94 }
95 }
96
97 public static NodeList getNodeList(Object source, XPath xPath, String xpath) throws XPathExpressionException {
98 return (NodeList) xPath.compile(xpath).evaluate(source, XPathConstants.NODESET);
99 }
100
101 public static boolean isPresent(Object source, XPath xPath, String xpath) throws XPathExpressionException {
102 Object node = xPath.compile(xpath).evaluate(source, XPathConstants.NODE);
103 return node != null;
104 }
105
106 public static List<Node> getNodes(Object source, XPath xPath, String xpath) throws XPathExpressionException {
107 NodeList nodeList = (NodeList) xPath.compile(xpath).evaluate(source, XPathConstants.NODESET);
108 List<Node> result = new ArrayList<>();
109 for (int i = 0; i < nodeList.getLength(); i++) {
110 result.add(nodeList.item(i));
111 }
112 return result;
113 }
114
115 public static Node getNode(Object source, XPath xPath, String xpath) throws XPathExpressionException {
116 NodeList nodeList = getNodeList(source, xPath, xpath);
117 assertEquals(1, nodeList.getLength(), "Could not find exactly one" + xpath);
118 return nodeList.item(0);
119 }
120
121 public static String printNodeList(NodeList nodeList) {
122 StringBuilder sb = new StringBuilder();
123 for (int i = 0; i < nodeList.getLength(); i++) {
124 Node n = nodeList.item(0);
125 sb.append(n.getNodeName()).append(" ");
126 NamedNodeMap nnm = n.getAttributes();
127 for (int j = 0; j < nnm.getLength(); j++) {
128 Node a = nnm.item(j);
129 sb.append(a.getNodeName()).append("=").append(a.getNodeValue()).append(" ");
130 }
131 sb.append("\n");
132 }
133 return sb.toString();
134 }
135
136 public static Document toDom(final InputStream in)
137 throws SAXException, IOException, ParserConfigurationException, FactoryConfigurationError {
138 final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
139 Document result;
140 result = builder.parse(in);
141 return result;
142 }
143
144 public static void writeAttribute(final IXmlWriter writer, final String name, final boolean booleanValue)
145 throws IOException {
146 final String value = Boolean.toString(booleanValue);
147 writer.attribute(name, value);
148 }
149
150
151
152
153
154
155
156 public static void printDocument(OutputStream out, Document document) {
157 TransformerFactory tf = TransformerFactory.newInstance();
158 Transformer transformer;
159 try {
160 transformer = tf.newTransformer();
161
162 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
163 transformer.setOutputProperty(OutputKeys.METHOD, "xml");
164 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
165 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
166 transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
167
168 transformer.transform(new DOMSource(document), new StreamResult(new OutputStreamWriter(out, StandardCharsets.UTF_8)));
169 } catch (TransformerException e) {
170 e.printStackTrace(new PrintStream(out));
171 }
172 }
173
174 public static String getAttribute(Object source, XPath xPath, String xpath, String attribute) throws XPathExpressionException {
175 Node node = XmlUtils.getNode(source, xPath, xpath);
176 NamedNodeMap attr = node.getAttributes();
177 node = attr.getNamedItem(attribute);
178 assertThat(node).as(attribute + " was not found").isNotNull();
179 return node.getNodeValue();
180 }
181
182 public static Map<String, String> mapOf(String... parts) {
183 Map<String, String> map = new HashMap<>();
184 for (int i = 0; i < parts.length; i += 2) {
185 map.put(parts[i], parts[i+1]);
186 }
187 return map;
188 }
189
190 public static void assertAttributes(Object source, XPath xPath, String xpath, String... mapValues) throws XPathExpressionException {
191 assertAttributes(source, xPath, xpath, mapOf(mapValues));
192 }
193
194 public static void assertAttributes(Object source, XPath xPath, String xpath, Map<String, String> attributes) throws XPathExpressionException {
195 Node node = XmlUtils.getNode(source, xPath, xpath);
196 NamedNodeMap attr = node.getAttributes();
197 for (Map.Entry<String, String> entry : attributes.entrySet()) {
198 node = attr.getNamedItem(entry.getKey());
199 assertThat(node).as(() -> entry.getKey() + " was not found on " + xpath).isNotNull();
200 assertThat(node.getNodeValue()).as(() -> entry.getKey() + " on " + xpath).isEqualTo(entry.getValue());
201 }
202 }
203
204 public static void assertIsPresent(Object source, XPath xPath, String xpath) throws XPathExpressionException {
205 assertThat(isPresent(source, xPath, xpath)).as("Presence of " + xpath).isTrue();
206 }
207
208 public static void assertIsNotPresent(Object source, XPath xPath, String xpath) throws XPathExpressionException {
209 assertThat(isPresent(source, xPath, xpath)).as("Non-presence of " + xpath).isFalse();
210 }
211
212 public static void assertIsPresent(String identifier, Object source, XPath xPath, String xpath) throws XPathExpressionException {
213 assertThat(isPresent(source, xPath, xpath)).as(identifier + ": Presence of " + xpath).isTrue();
214 }
215
216 public static void assertIsNotPresent(String identifier, Object source, XPath xPath, String xpath) throws XPathExpressionException {
217 assertThat(isPresent(source, xPath, xpath)).as(identifier + ": Non-presence of " + xpath).isFalse();
218 }
219 }