This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git
The following commit(s) were added to refs/heads/master by this push:
new 052f1294 Set SecureProcessing feature in XmlStringLookup by default.
052f1294 is described below
commit 052f1294daad65da8f0c191e6e2f81fe3897f6b6
Author: Gary Gregory <[email protected]>
AuthorDate: Sat May 6 09:57:28 2023 -0400
Set SecureProcessing feature in XmlStringLookup by default.
Add StringLookupFactory.xmlStringLookup(Pair<String, Boolean>...)
---
pom.xml | 6 ++--
src/changes/changes.xml | 4 ++-
.../commons/text/lookup/StringLookupFactory.java | 39 ++++++++++++++++++++++
.../commons/text/lookup/XmlStringLookup.java | 35 +++++++++++++++----
4 files changed, 74 insertions(+), 10 deletions(-)
diff --git a/pom.xml b/pom.xml
index e39603bb..176f0ca8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
<version>56</version>
</parent>
<artifactId>commons-text</artifactId>
- <version>1.10.1-SNAPSHOT</version>
+ <version>1.11.0-SNAPSHOT</version>
<name>Apache Commons Text</name>
<description>Apache Commons Text is a library focused on algorithms working
on strings.</description>
<url>https://commons.apache.org/proper/commons-text</url>
@@ -38,7 +38,7 @@
<commons.packageId>text</commons.packageId>
<commons.module.name>org.apache.commons.text</commons.module.name>
- <commons.release.version>1.10.0</commons.release.version>
+ <commons.release.version>1.11.0</commons.release.version>
<commons.release.desc>(Java 8+)</commons.release.desc>
<commons.jira.id>TEXT</commons.jira.id>
@@ -64,7 +64,7 @@
<jmh.version>1.36</jmh.version>
<!-- Commons Release Plugin -->
- <commons.bc.version>1.9</commons.bc.version>
+ <commons.bc.version>1.10.0</commons.bc.version>
<commons.rc.version>RC1</commons.rc.version>
<commons.release.isDistModule>true</commons.release.isDistModule>
<commons.distSvnStagingUrl>scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid}</commons.distSvnStagingUrl>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 5a8f57b4..7b25d72d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,7 +46,7 @@ The <action> type attribute can be add,update,fix,remove.
<title>Apache Commons Text Changes</title>
</properties>
<body>
- <release version="1.10.1" date="20YY-MM-DD" description="Release 1.10.1.
Requires Java 8.">
+ <release version="1.11.0" date="20YY-MM-DD" description="Release 1.10.1.
Requires Java 8.">
<!-- FIX -->
<action issue="TEXT-219" type="fix" dev="aherbert" due-to="Jaap
Sperling">Fix StringTokenizer.getTokenList to return an independent modifiable
list</action>
<action type="fix" dev="aherbert" due-to="James Nord">Fix
Javadoc for StringEscapeUtils.escapeHtml4 #382</action>
@@ -58,6 +58,8 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="Gary
Gregory">Add and use a package-private singleton for
JaroWinklerSimilarity.</action>
<action type="fix" dev="ggregory" due-to="Gary
Gregory">Add and use a package-private singleton for JaccardSimilarity.</action>
<!-- ADD -->
+ <action issue="TEXT-224" type="add" dev="ggregory" due-to="PJ Fanning,
Gary Gregory">Set SecureProcessing feature in XmlStringLookup by
default.</action>
+ <action issue="TEXT-224" type="add" dev="ggregory" due-to="Gary
Gregory">Add StringLookupFactory.xmlStringLookup(Pair<String,
Boolean>...).</action>
<!-- UPDATE -->
<action type="update" dev="ggregory"
due-to="Dependabot">Bump actions/cache from 3.0.8 to 3.0.10 #361, #365.</action>
<action type="update" dev="ggregory"
due-to="Dependabot">Bump actions/setup-java from 3 to 3.5.1.</action>
diff --git
a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
index a2a0abd1..8e826e04 100644
--- a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
+++ b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
@@ -27,6 +27,9 @@ import java.util.Properties;
import java.util.function.BiFunction;
import java.util.function.Function;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.text.StringSubstitutor;
/**
@@ -1315,4 +1318,40 @@ public final class StringLookupFactory {
public StringLookup xmlStringLookup() {
return XmlStringLookup.INSTANCE;
}
+
+ /**
+ * Returns the XmlStringLookup singleton instance.
+ * <p>
+ * Looks up the value for the key in the format "DocumentPath:XPath".
+ * </p>
+ * <p>
+ * For example: "com/domain/document.xml:/path/to/node".
+ * </p>
+ * <p>
+ * Using a {@link StringLookup} from the {@link StringLookupFactory}:
+ * </p>
+ *
+ * <pre>
+ *
StringLookupFactory.INSTANCE.xmlStringLookup().lookup("com/domain/document.xml:/path/to/node");
+ * </pre>
+ * <p>
+ * Using a {@link StringSubstitutor}:
+ * </p>
+ *
+ * <pre>
+ * StringSubstitutor.createInterpolator().replace("...
${xml:com/domain/document.xml:/path/to/node} ..."));
+ * </pre>
+ * <p>
+ * The above examples convert {@code
"com/domain/document.xml:/path/to/node"} to the value of the XPath in the XML
+ * document.
+ * </p>
+ *
+ * @param xPathFactoryFeatures XPathFactory features to set.
+ * @return The XmlStringLookup singleton instance.
+ * @see XPathFactory#setFeature(String, boolean)
+ * @since 1.11.0
+ */
+ public StringLookup xmlStringLookup(@SuppressWarnings("unchecked")
Pair<String, Boolean>... xPathFactoryFeatures) {
+ return new XmlStringLookup(xPathFactoryFeatures);
+ }
}
diff --git a/src/main/java/org/apache/commons/text/lookup/XmlStringLookup.java
b/src/main/java/org/apache/commons/text/lookup/XmlStringLookup.java
index 12aa5e56..2c6c73dc 100644
--- a/src/main/java/org/apache/commons/text/lookup/XmlStringLookup.java
+++ b/src/main/java/org/apache/commons/text/lookup/XmlStringLookup.java
@@ -20,10 +20,13 @@ package org.apache.commons.text.lookup;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.Objects;
+import javax.xml.XMLConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.xml.sax.InputSource;
/**
@@ -39,16 +42,32 @@ import org.xml.sax.InputSource;
*/
final class XmlStringLookup extends AbstractStringLookup {
+ /**
+ * Defines default XPath factory features.
+ */
+ @SuppressWarnings("unchecked")
+ private static final Pair<String, Boolean>[] DEFAULT_FEATURES = new Pair[]
{
+ Pair.of(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE) };
+
/**
* Defines the singleton for this class.
*/
- static final XmlStringLookup INSTANCE = new XmlStringLookup();
+ static final XmlStringLookup INSTANCE = new
XmlStringLookup(DEFAULT_FEATURES);
+
+ /**
+ * Defines XPath factory features.
+ */
+ private final Pair<String, Boolean>[] xPathFactoryFeatures;
/**
* No need to build instances for now.
+ *
+ * @param xPathFactoryFeatures XPathFactory features to set.
+ * @see XPathFactory#setFeature(String, boolean)
*/
- private XmlStringLookup() {
- // empty
+ @SafeVarargs
+ XmlStringLookup(final Pair<String, Boolean>... xPathFactoryFeatures) {
+ this.xPathFactoryFeatures =
Objects.requireNonNull(xPathFactoryFeatures, "xPathFfactoryFeatures");
}
/**
@@ -69,15 +88,19 @@ final class XmlStringLookup extends AbstractStringLookup {
final int keyLen = keys.length;
if (keyLen != 2) {
throw IllegalArgumentExceptions.format("Bad XML key format [%s];
expected format is DocumentPath:XPath.",
- key);
+ key);
}
final String documentPath = keys[0];
final String xpath = StringUtils.substringAfter(key, SPLIT_CH);
try (InputStream inputStream =
Files.newInputStream(Paths.get(documentPath))) {
- return XPathFactory.newInstance().newXPath().evaluate(xpath, new
InputSource(inputStream));
+ final XPathFactory factory = XPathFactory.newInstance();
+ for (final Pair<String, Boolean> p : xPathFactoryFeatures) {
+ factory.setFeature(p.getKey(), p.getValue());
+ }
+ return factory.newXPath().evaluate(xpath, new
InputSource(inputStream));
} catch (final Exception e) {
throw IllegalArgumentExceptions.format(e, "Error looking up XML
document [%s] and XPath [%s].",
- documentPath, xpath);
+ documentPath, xpath);
}
}