1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.text.lookup;
19
20 import java.io.InputStream;
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Objects;
27
28 import javax.xml.XMLConstants;
29 import javax.xml.xpath.XPathFactory;
30
31 import org.apache.commons.lang3.StringUtils;
32 import org.xml.sax.InputSource;
33
34
35
36
37
38
39
40
41
42
43
44
45 final class XmlStringLookup extends AbstractPathFencedLookup {
46
47
48
49
50 static final Map<String, Boolean> DEFAULT_FEATURES;
51
52 static {
53 DEFAULT_FEATURES = new HashMap<>(1);
54 DEFAULT_FEATURES.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
55 }
56
57
58
59
60 static final XmlStringLookup INSTANCE = new XmlStringLookup(DEFAULT_FEATURES, (Path[]) null);
61
62
63
64
65 private final Map<String, Boolean> xPathFactoryFeatures;
66
67
68
69
70
71
72
73 XmlStringLookup(final Map<String, Boolean> xPathFactoryFeatures, final Path... fences) {
74 super(fences);
75 this.xPathFactoryFeatures = Objects.requireNonNull(xPathFactoryFeatures, "xPathFfactoryFeatures");
76 }
77
78
79
80
81
82
83
84
85
86
87 @Override
88 public String lookup(final String key) {
89 if (key == null) {
90 return null;
91 }
92 final String[] keys = key.split(SPLIT_STR);
93 final int keyLen = keys.length;
94 if (keyLen != 2) {
95 throw IllegalArgumentExceptions.format("Bad XML key format [%s]; expected format is DocumentPath:XPath.",
96 key);
97 }
98 final String documentPath = keys[0];
99 final String xpath = StringUtils.substringAfter(key, SPLIT_CH);
100 try (InputStream inputStream = Files.newInputStream(getPath(documentPath))) {
101 final XPathFactory factory = XPathFactory.newInstance();
102 for (final Entry<String, Boolean> p : xPathFactoryFeatures.entrySet()) {
103 factory.setFeature(p.getKey(), p.getValue());
104 }
105 return factory.newXPath().evaluate(xpath, new InputSource(inputStream));
106 } catch (final Exception e) {
107 throw IllegalArgumentExceptions.format(e, "Error looking up XML document [%s] and XPath [%s].",
108 documentPath, xpath);
109 }
110 }
111
112 }