1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.text.lookup;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNotNull;
21 import static org.junit.jupiter.api.Assertions.assertSame;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.Set;
31
32 import javax.xml.XMLConstants;
33
34 import org.junit.jupiter.api.Test;
35 import org.junitpioneer.jupiter.SetSystemProperty;
36
37
38
39
40 class StringLookupFactoryTest {
41
42 public static void assertDefaultKeys(final Map<String, StringLookup> stringLookupMap) {
43
44 assertMappedLookups(stringLookupMap,
45 "base64",
46 StringLookupFactory.KEY_BASE64_DECODER,
47 StringLookupFactory.KEY_BASE64_ENCODER,
48 StringLookupFactory.KEY_CONST,
49 StringLookupFactory.KEY_DATE,
50 StringLookupFactory.KEY_ENV,
51 StringLookupFactory.KEY_FILE,
52 StringLookupFactory.KEY_JAVA,
53 StringLookupFactory.KEY_LOCALHOST,
54 StringLookupFactory.KEY_LOOPBACK_ADDRESS,
55 StringLookupFactory.KEY_PROPERTIES,
56 StringLookupFactory.KEY_RESOURCE_BUNDLE,
57 StringLookupFactory.KEY_SYS,
58 StringLookupFactory.KEY_URL_DECODER,
59 StringLookupFactory.KEY_URL_ENCODER,
60 StringLookupFactory.KEY_XML,
61 StringLookupFactory.KEY_XML_DECODER,
62 StringLookupFactory.KEY_XML_ENCODER);
63 }
64
65 private static void assertMappedLookups(final Map<String, StringLookup> lookupMap, final String... keys) {
66 final Set<String> remainingKeys = new HashSet<>(lookupMap.keySet());
67 for (final String key : keys) {
68 final String normalizedKey = StringLookupFactory.toKey(key);
69 assertNotNull(normalizedKey, () -> "Expected map to contain string lookup for key " + key);
70 remainingKeys.remove(normalizedKey);
71 }
72 assertTrue(remainingKeys.isEmpty(), () -> "Unexpected keys in lookup map: " + remainingKeys);
73 }
74
75 private static void checkDefaultStringLookupsHolder(final Properties props, final String... keys) {
76 final StringLookupFactory.DefaultStringLookupsHolder holder = new StringLookupFactory.DefaultStringLookupsHolder(props);
77 final Map<String, StringLookup> lookupMap = holder.getDefaultStringLookups();
78 assertMappedLookups(lookupMap, keys);
79 }
80
81
82
83
84
85 public static void main(final String[] args) {
86 final Map<String, StringLookup> lookupMap = new HashMap<>();
87 StringLookupFactory.INSTANCE.addDefaultStringLookups(lookupMap);
88 System.out.println("Default string lookups");
89 for (final String key : lookupMap.keySet()) {
90 System.out.println("- " + key);
91 }
92 }
93
94 @Test
95 void testAddDefaultStringLookupsMap() {
96 final Map<String, StringLookup> stringLookupMap = new HashMap<>();
97 StringLookupFactory.INSTANCE.addDefaultStringLookups(stringLookupMap);
98 assertDefaultKeys(stringLookupMap);
99 }
100
101 @Test
102 void testAddDefaultStringLookupsNull() {
103 StringLookupFactory.INSTANCE.addDefaultStringLookups(null);
104 }
105
106
107
108
109 @Test
110 void testDefault() {
111 final StringLookupFactory stringLookupFactory = StringLookupFactory.INSTANCE;
112 final Map<String, StringLookup> stringLookupMap = new HashMap<>();
113 stringLookupFactory.addDefaultStringLookups(stringLookupMap);
114 assertTrue(stringLookupMap.containsKey("base64"));
115 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_BASE64_ENCODER.toLowerCase(Locale.ROOT)));
116 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_CONST.toLowerCase(Locale.ROOT)));
117 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DATE));
118 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_ENV.toLowerCase(Locale.ROOT)));
119 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_FILE.toLowerCase(Locale.ROOT)));
120 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_JAVA.toLowerCase(Locale.ROOT)));
121 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_LOCALHOST.toLowerCase(Locale.ROOT)));
122 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_LOOPBACK_ADDRESS.toLowerCase(Locale.ROOT)));
123 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_PROPERTIES.toLowerCase(Locale.ROOT)));
124 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_RESOURCE_BUNDLE.toLowerCase(Locale.ROOT)));
125 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_SYS.toLowerCase(Locale.ROOT)));
126 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_URL_DECODER.toLowerCase(Locale.ROOT)));
127 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_URL_ENCODER.toLowerCase(Locale.ROOT)));
128 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_XML.toLowerCase(Locale.ROOT)));
129 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_XML_DECODER.toLowerCase(Locale.ROOT)));
130 assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_XML_ENCODER.toLowerCase(Locale.ROOT)));
131 }
132
133 @Test
134 void testDefaultStringLookupsHolder_allLookups() {
135 final Properties props = new Properties();
136 props.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, "BASE64_DECODER BASE64_ENCODER const, date, dns, environment "
137 + "file ,java, local_host properties, resource_bundle,script,system_properties url url_decoder , url_encoder, xml");
138
139 checkDefaultStringLookupsHolder(props,
140 "base64",
141 StringLookupFactory.KEY_BASE64_DECODER,
142 StringLookupFactory.KEY_BASE64_ENCODER,
143 StringLookupFactory.KEY_CONST,
144 StringLookupFactory.KEY_DATE,
145 StringLookupFactory.KEY_ENV,
146 StringLookupFactory.KEY_FILE,
147 StringLookupFactory.KEY_JAVA,
148 StringLookupFactory.KEY_LOCALHOST,
149 StringLookupFactory.KEY_LOOPBACK_ADDRESS,
150 StringLookupFactory.KEY_PROPERTIES,
151 StringLookupFactory.KEY_RESOURCE_BUNDLE,
152 StringLookupFactory.KEY_SYS,
153 StringLookupFactory.KEY_URL_DECODER,
154 StringLookupFactory.KEY_URL_ENCODER,
155 StringLookupFactory.KEY_XML,
156
157 StringLookupFactory.KEY_DNS,
158 StringLookupFactory.KEY_URL,
159 StringLookupFactory.KEY_SCRIPT);
160
161 }
162
163 @Test
164 void testDefaultStringLookupsHolder_givenSingleLookup() {
165 final Properties props = new Properties();
166 props.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, "base64_encoder");
167 checkDefaultStringLookupsHolder(props, "base64", StringLookupFactory.KEY_BASE64_ENCODER);
168 }
169
170 @Test
171 void testDefaultStringLookupsHolder_givenSingleLookup_weirdString() {
172 final Properties props = new Properties();
173 props.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, " \n \t ,, DnS , , ");
174 checkDefaultStringLookupsHolder(props, StringLookupFactory.KEY_DNS);
175 }
176
177 @Test
178 void testDefaultStringLookupsHolder_invalidLookupsDefinition() {
179 final Properties props = new Properties();
180 props.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, "base64_encoder nope");
181 final Exception exc = assertThrows(IllegalArgumentException.class, () -> new StringLookupFactory.DefaultStringLookupsHolder(props));
182 assertEquals("Invalid default string lookups definition: base64_encoder nope", exc.getMessage());
183 }
184
185 @Test
186 void testDefaultStringLookupsHolder_lookupsPropertyEmptyAndBlank() {
187 final Properties propsWithNull = new Properties();
188 propsWithNull.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, "");
189 checkDefaultStringLookupsHolder(propsWithNull);
190 final Properties propsWithBlank = new Properties();
191 propsWithBlank.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, " ");
192 checkDefaultStringLookupsHolder(propsWithBlank);
193 }
194
195 @Test
196 void testDefaultStringLookupsHolder_lookupsPropertyNotPresent() {
197
198 checkDefaultStringLookupsHolder(new Properties(),
199 "base64",
200 StringLookupFactory.KEY_BASE64_DECODER,
201 StringLookupFactory.KEY_BASE64_ENCODER,
202 StringLookupFactory.KEY_CONST,
203 StringLookupFactory.KEY_DATE,
204 StringLookupFactory.KEY_ENV,
205 StringLookupFactory.KEY_FILE,
206 StringLookupFactory.KEY_JAVA,
207 StringLookupFactory.KEY_LOCALHOST,
208 StringLookupFactory.KEY_LOOPBACK_ADDRESS,
209 StringLookupFactory.KEY_PROPERTIES,
210 StringLookupFactory.KEY_RESOURCE_BUNDLE,
211 StringLookupFactory.KEY_SYS,
212 StringLookupFactory.KEY_URL_DECODER,
213 StringLookupFactory.KEY_URL_ENCODER,
214 StringLookupFactory.KEY_XML,
215 StringLookupFactory.KEY_XML_DECODER,
216 StringLookupFactory.KEY_XML_ENCODER);
217
218 }
219
220 @Test
221 void testDefaultStringLookupsHolder_multipleLookups() {
222 final Properties props = new Properties();
223 props.setProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY, "dns, url script ");
224
225 checkDefaultStringLookupsHolder(props,
226 StringLookupFactory.KEY_DNS,
227 StringLookupFactory.KEY_URL,
228 StringLookupFactory.KEY_SCRIPT);
229
230 }
231
232
233
234
235 @Test
236 void testSingletons() {
237 final StringLookupFactory stringLookupFactory = StringLookupFactory.INSTANCE;
238 assertSame(StringLookupFactory.INSTANCE_BASE64_DECODER, stringLookupFactory.base64DecoderStringLookup());
239 assertSame(StringLookupFactory.INSTANCE_BASE64_ENCODER, stringLookupFactory.base64EncoderStringLookup());
240 assertSame(ConstantStringLookup.INSTANCE, stringLookupFactory.constantStringLookup());
241 assertSame(DateStringLookup.INSTANCE, stringLookupFactory.dateStringLookup());
242 assertSame(DnsStringLookup.INSTANCE, stringLookupFactory.dnsStringLookup());
243 assertSame(StringLookupFactory.INSTANCE_ENVIRONMENT_VARIABLES, stringLookupFactory.environmentVariableStringLookup());
244 assertSame(InterpolatorStringLookup.INSTANCE, stringLookupFactory.interpolatorStringLookup());
245 assertSame(JavaPlatformStringLookup.INSTANCE, stringLookupFactory.javaPlatformStringLookup());
246 assertSame(InetAddressStringLookup.LOCAL_HOST, stringLookupFactory.localHostStringLookup());
247 assertSame(InetAddressStringLookup.LOOPACK_ADDRESS, stringLookupFactory.loopbackAddressStringLookup());
248 assertSame(StringLookupFactory.INSTANCE_NULL, stringLookupFactory.nullStringLookup());
249 assertSame(ResourceBundleStringLookup.INSTANCE, stringLookupFactory.resourceBundleStringLookup());
250 assertSame(ScriptStringLookup.INSTANCE, stringLookupFactory.scriptStringLookup());
251 assertSame(StringLookupFactory.INSTANCE_SYSTEM_PROPERTIES, stringLookupFactory.systemPropertyStringLookup());
252 assertSame(UrlDecoderStringLookup.INSTANCE, stringLookupFactory.urlDecoderStringLookup());
253 assertSame(UrlEncoderStringLookup.INSTANCE, stringLookupFactory.urlEncoderStringLookup());
254 assertSame(UrlStringLookup.INSTANCE, stringLookupFactory.urlStringLookup());
255 assertSame(XmlStringLookup.INSTANCE, stringLookupFactory.xmlStringLookup());
256 assertSame(XmlDecoderStringLookup.INSTANCE, stringLookupFactory.xmlDecoderStringLookup());
257 assertSame(XmlEncoderStringLookup.INSTANCE, stringLookupFactory.xmlEncoderStringLookup());
258 }
259
260 @Test
261 void testXmlStringLookup() {
262 final StringLookupFactory stringLookupFactory = StringLookupFactory.INSTANCE;
263 final HashMap<String, Boolean> features = new HashMap<>(1);
264 features.put(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
265 XmlStringLookupTest.assertLookup(stringLookupFactory.xmlStringLookup(features));
266 XmlStringLookupTest.assertLookup(stringLookupFactory.xmlStringLookup(new HashMap<>()));
267 }
268
269 @Test
270 void testXmlStringLookupExternalEntityOff() {
271 assertThrows(IllegalArgumentException.class,
272 () -> StringLookupFactory.INSTANCE.xmlStringLookup().apply(XmlStringLookupTest.DOC_DIR + "document-entity-ref.xml:/document/content"));
273 }
274
275 @Test
276 @SetSystemProperty(key = "XmlStringLookup.secure", value = "false")
277 void testXmlStringLookupExternalEntityOn() {
278 final String key = XmlStringLookupTest.DOC_DIR + "document-entity-ref.xml:/document/content";
279 assertEquals(XmlStringLookupTest.DATA, StringLookupFactory.INSTANCE.xmlStringLookup(XmlStringLookupTest.EMPTY_MAP).apply(key).trim());
280 }
281
282 }