Skip to content

Commit

Permalink
Issue #10066 - Allow customization of SAXParserFactory and `SAXPars…
Browse files Browse the repository at this point in the history
…er` in `XmlParser` (#10067)

* Allow customization of SAXParserFactory / SAXParser in XmlParser
* Introduce method `.getSAXParser()`
---------

Signed-off-by: Joakim Erdfelt <joakim.erdfelt@gmail.com>
Co-authored-by: Greg Wilkins <gregw@webtide.com>
  • Loading branch information
joakime and gregw committed Aug 11, 2023
1 parent 88d70ca commit 15da450
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 4 deletions.
18 changes: 14 additions & 4 deletions jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public class XmlParser
*/
public XmlParser()
{
SAXParserFactory factory = SAXParserFactory.newInstance();
boolean validatingDft = factory.getClass().toString().startsWith("org.apache.xerces.");
String validatingProp = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validatingDft ? "true" : "false");
SAXParserFactory factory = newSAXParserFactory();
boolean validatingDefault = factory.getClass().toString().contains("org.apache.xerces.");
String validatingProp = System.getProperty("org.eclipse.jetty.xml.XmlParser.Validating", validatingDefault ? "true" : "false");
boolean validating = Boolean.valueOf(validatingProp).booleanValue();
setValidating(validating);
}
Expand All @@ -81,11 +81,16 @@ public XmlParser(boolean validating)
setValidating(validating);
}

protected SAXParserFactory newSAXParserFactory()
{
return SAXParserFactory.newInstance();
}

public void setValidating(boolean validating)
{
try
{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParserFactory factory = newSAXParserFactory();
factory.setValidating(validating);
_parser = factory.newSAXParser();

Expand Down Expand Up @@ -127,6 +132,11 @@ public boolean isValidating()
return _parser.isValidating();
}

public SAXParser getSAXParser()
{
return _parser;
}

public synchronized void redirectEntity(String name, URL entity)
{
if (entity != null)
Expand Down
35 changes: 35 additions & 0 deletions jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@
package org.eclipse.jetty.xml;

import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.junit.jupiter.api.Test;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

public class XmlParserTest
{
Expand All @@ -45,4 +52,32 @@ public void testXmlParser() throws Exception
assertTrue(testDocStr.startsWith("<Configure"));
assertTrue(testDocStr.endsWith("</Configure>"));
}

/**
* Customize SAXParserFactory behavior.
*/
@Test
public void testNewSAXParserFactory() throws SAXException
{
XmlParser xmlParser = new XmlParser()
{
@Override
protected SAXParserFactory newSAXParserFactory()
{
SAXParserFactory saxParserFactory = super.newSAXParserFactory();
// Configure at factory level
saxParserFactory.setXIncludeAware(false);
return saxParserFactory;
}
};

SAXParser saxParser = xmlParser.getSAXParser();
assertNotNull(saxParser);

XMLReader xmlReader = saxParser.getXMLReader();
// Only run testcase if Xerces is being used.
assumeTrue(xmlReader.getClass().getName().contains("org.apache.xerces."));
// look to see it was set at XMLReader level
assertFalse(xmlReader.getFeature("http://apache.org/xml/features/xinclude"));
}
}

0 comments on commit 15da450

Please sign in to comment.