Skip to content

Commit ba9a994

Browse files
The XML catalog unit test that verifies if the local XSD files matches the content of the XML catalog is ready.
Signed-off-by: Nicolas-Peiffer <[email protected]>
1 parent 4631813 commit ba9a994

File tree

2 files changed

+68
-32
lines changed

2 files changed

+68
-32
lines changed

tools/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,10 @@
145145
<version>3.2.5</version>
146146
</plugin>
147147
</plugins>
148+
<testResources>
149+
<testResource>
150+
<directory>${basedir}/../schema</directory>
151+
</testResource>
152+
</testResources>
148153
</build>
149154
</project>

tools/src/test/java/org/cyclonedx/schema/XmlCatalogVerificationTest.java

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,50 @@
1010
import org.xml.sax.InputSource;
1111
import org.xml.sax.SAXException;
1212

13+
import javax.xml.namespace.NamespaceContext;
1314
import javax.xml.parsers.DocumentBuilder;
1415
import javax.xml.parsers.DocumentBuilderFactory;
1516
import javax.xml.parsers.ParserConfigurationException;
17+
import javax.xml.xpath.XPath;
18+
import javax.xml.xpath.XPathConstants;
19+
import javax.xml.xpath.XPathExpressionException;
20+
import javax.xml.xpath.XPathFactory;
1621

17-
import java.io.InputStream;
1822
import java.io.IOException;
19-
import java.io.StringReader;
20-
import java.nio.charset.StandardCharsets;
23+
import java.io.InputStream;
2124
import java.util.ArrayList;
25+
import java.util.Iterator;
2226
import java.util.List;
2327

24-
import static org.junit.jupiter.api.Assertions.assertTrue;
2528
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
2629

2730
public class XmlCatalogVerificationTest {
2831

2932
/**
30-
* Tests the XML catalog by parsing the xmlcatalog.xml file and checking if the namespaces
31-
* in the XSD schema files match the namespaces defined in the xmlcatalog.xml file.
33+
* Tests the XML catalog by parsing the xmlcatalog.xml file and verifying if the XML namespaces
34+
* in the referenced XSD schema files match the XML namespaces defined in the xmlcatalog.xml file.
3235
*
3336
* @return a list of dynamic tests for each URI in the xmlcatalog.xml file
3437
* @throws IOException if an I/O error occurs while reading the XML catalog file
3538
* @throws ParserConfigurationException if a parser configuration error occurs
3639
* @throws SAXException if a SAX error occurs while parsing the XML catalog file
40+
* @throws XPathExpressionException if an XPath expression error occurs
3741
*/
3842
@TestFactory
39-
public List<DynamicTest> testXmlCatalog() throws IOException, ParserConfigurationException, SAXException {
40-
// Define the path to the XML catalog file
43+
public List<DynamicTest> testXmlCatalog() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException {
44+
// Define the path to the XML catalog file. This is relative to "${basedir}/../schema" in the pom.xml.
4145
String xmlCatalogFilename = "xmlcatalog.xml";
4246

4347
// Load the XML catalog file from the classpath
4448
ClassLoader classLoader = getClass().getClassLoader();
4549
InputStream xmlCatalogStream = classLoader.getResourceAsStream(xmlCatalogFilename);
4650

51+
// Ensure the XML catalog file is found
4752
Assertions.assertNotNull(xmlCatalogStream, "XML catalog file not found");
4853

4954
// Parse the xmlcatalog.xml file
5055
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
56+
factory.setNamespaceAware(true); // Make the factory namespace-aware
5157
DocumentBuilder builder = factory.newDocumentBuilder();
5258
Document xmlCatalogDocument = builder.parse(new InputSource(xmlCatalogStream));
5359

@@ -60,39 +66,64 @@ public List<DynamicTest> testXmlCatalog() throws IOException, ParserConfiguratio
6066
// Iterate through the XML catalog elements
6167
for (int i = 0; i < xmlCatalogElements.getLength(); i++) {
6268
Node xmlCatalogElement = xmlCatalogElements.item(i);
69+
70+
// Check if the element is a <uri> element
6371
if (xmlCatalogElement.getNodeName().equals("uri")) {
64-
String uriName = xmlCatalogElement.getAttributes().getNamedItem("name").getTextContent();
72+
// Get the URI name and the local filename of the XSD schema
73+
String uriNameXmlCtlg = xmlCatalogElement.getAttributes().getNamedItem("name").getTextContent();
6574
String xsdLocalFilename = xmlCatalogElement.getAttributes().getNamedItem("uri").getTextContent();
6675

67-
// Create a dynamic test for each URI
68-
dynamicTests.add(dynamicTest("Testing URI: " + uriName, () -> {
69-
// Load the XSD schema file from the classpath
70-
InputStream xsdSchemaFileStream = classLoader.getResourceAsStream(xsdLocalFilename);
71-
Assertions.assertNotNull(xsdSchemaFileStream, "The following file is missing: " + xsdLocalFilename);
72-
73-
// Read the XSD local file content
74-
String xsdContent = new String(xsdSchemaFileStream.readAllBytes(), StandardCharsets.UTF_8);
75-
76-
// Parse the XSD file content to a Document object
77-
Document xsdDocument = builder.parse(new InputSource(new StringReader(xsdContent)));
78-
79-
// Check if the XSD document contains the expected namespace
80-
NodeList schemaNodes = xsdDocument.getElementsByTagNameNS("*", "schema");
81-
boolean namespaceFound = false;
82-
for (int j = 0; j < schemaNodes.getLength(); j++) {
83-
Node schemaNode = schemaNodes.item(j);
84-
String targetNamespace = schemaNode.getAttributes().getNamedItem("targetNamespace").getTextContent();
85-
System.out.println("uriName.equals(targetNamespace)" + uriName.equals(targetNamespace));
86-
if (uriName.equals(targetNamespace)) {
87-
namespaceFound = true;
88-
break;
76+
// Load the XSD schema local file from the classpath
77+
InputStream xsdSchemaFileStream = classLoader.getResourceAsStream(xsdLocalFilename);
78+
Assertions.assertNotNull(xsdSchemaFileStream, "The following file is missing: " + xsdLocalFilename);
79+
80+
// Parse the XSD schema local file
81+
DocumentBuilderFactory factoryXsd = DocumentBuilderFactory.newInstance();
82+
factoryXsd.setNamespaceAware(true); // Make the factory namespace-aware
83+
DocumentBuilder builderXsd = factoryXsd.newDocumentBuilder();
84+
Document xsdDocument = builderXsd.parse(new InputSource(xsdSchemaFileStream));
85+
86+
// Create an XPath instance to evaluate the targetNamespace field found in the XSD schema
87+
XPath xPath = XPathFactory.newInstance().newXPath();
88+
xPath.setNamespaceContext(new NamespaceContext() {
89+
@Override
90+
public String getNamespaceURI(String prefix) {
91+
// Define the namespace URI for the xs prefix
92+
if ("xs".equals(prefix)) {
93+
return "http://www.w3.org/2001/XMLSchema";
94+
}
95+
return null;
96+
}
97+
98+
@Override
99+
public String getPrefix(String namespaceURI) {
100+
// Define the prefix for the namespace URI
101+
if ("http://www.w3.org/2001/XMLSchema".equals(namespaceURI)) {
102+
return "xs";
89103
}
104+
return null;
90105
}
91-
assertTrue(namespaceFound, "The namespace " + uriName + " is not present in file " + xsdLocalFilename);
106+
107+
@Override
108+
public Iterator<String> getPrefixes(String namespaceURI) {
109+
return null;
110+
}
111+
});
112+
113+
// Evaluate the targetNamespace attribute from the XSD document
114+
String targetNamespace = (String) xPath.evaluate("/xs:schema/@targetNamespace", xsdDocument, XPathConstants.STRING);
115+
116+
// Assert if the targetNamespace from the XSD file matches the uriNameXmlCtlg from the XML catalog
117+
Assertions.assertEquals(uriNameXmlCtlg, targetNamespace, "The namespace " + uriNameXmlCtlg + " does not match the targetNamespace in file " + xsdLocalFilename);
118+
119+
// Create a dynamic test for each URI
120+
dynamicTests.add(dynamicTest("Testing if URI namespace from the XML catalog: " + uriNameXmlCtlg + " matches the URI namespace from the local XSD file: " + targetNamespace, () -> {
121+
// Dummy test, the namespace check is done before
92122
}));
93123
}
94124
}
95125

126+
// Return the list of dynamic tests
96127
return dynamicTests;
97128
}
98129
}

0 commit comments

Comments
 (0)