001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017
018package org.apache.commons.text.lookup;
019
020import java.util.Map;
021
022/**
023 * Provides access to lookups defined in this package.
024 * <p>
025 * The default lookups are:
026 * </p>
027 * <table>
028 * <caption>Default String Lookups</caption>
029 * <tr>
030 * <th>Key</th>
031 * <th>Implementation</th>
032 * <th>Factory Method</th>
033 * <th>Since</th>
034 * </tr>
035 * <tr>
036 * <td>{@value #KEY_BASE64_DECODER}</td>
037 * <td>{@link Base64DecoderStringLookup}</td>
038 * <td>{@link #base64DecoderStringLookup()}</td>
039 * <td>1.6</td>
040 * </tr>
041 * <tr>
042 * <td>{@value #KEY_BASE64_ENCODER}</td>
043 * <td>{@link Base64EncoderStringLookup}</td>
044 * <td>{@link #base64EncoderStringLookup()}</td>
045 * <td>1.6</td>
046 * </tr>
047 * <tr>
048 * <td>{@value #KEY_CONST}</td>
049 * <td>{@link ConstantStringLookup}</td>
050 * <td>{@link #constantStringLookup()}</td>
051 * <td>1.5</td>
052 * </tr>
053 * <tr>
054 * <td>{@value #KEY_DATE}</td>
055 * <td>{@link DateStringLookup}</td>
056 * <td>{@link #dateStringLookup()}</td>
057 * <td>1.5</td>
058 * </tr>
059 * <tr>
060 * <td>{@value #KEY_ENV}</td>
061 * <td>{@link EnvironmentVariableStringLookup}</td>
062 * <td>{@link #environmentVariableStringLookup()}</td>
063 * <td>1.3</td>
064 * </tr>
065 * <tr>
066 * <td>{@value #KEY_FILE}</td>
067 * <td>{@link FileStringLookup}</td>
068 * <td>{@link #fileStringLookup()}</td>
069 * <td>1.5</td>
070 * </tr>
071 * <tr>
072 * <td>{@value #KEY_JAVA}</td>
073 * <td>{@link JavaPlatformStringLookup}</td>
074 * <td>{@link #javaPlatformStringLookup()}</td>
075 * <td>1.5</td>
076 * </tr>
077 * <tr>
078 * <td>{@value #KEY_LOCALHOST}</td>
079 * <td>{@link LocalHostStringLookup}</td>
080 * <td>{@link #localHostStringLookup()}</td>
081 * <td>1.3</td>
082 * </tr>
083 * <tr>
084 * <td>{@value #KEY_PROPERTIES}</td>
085 * <td>{@link PropertiesStringLookup}</td>
086 * <td>{@link #propertiesStringLookup()}</td>
087 * <td>1.5</td>
088 * </tr>
089 * <tr>
090 * <td>{@value #KEY_RESOURCE_BUNDLE}</td>
091 * <td>{@link ResourceBundleStringLookup}</td>
092 * <td>{@link #resourceBundleStringLookup()}</td>
093 * <td>1.6</td>
094 * </tr>
095 * <tr>
096 * <td>{@value #KEY_SCRIPT}</td>
097 * <td>{@link ScriptStringLookup}</td>
098 * <td>{@link #scriptStringLookup()}</td>
099 * <td>1.5</td>
100 * </tr>
101 * <tr>
102 * <td>{@value #KEY_SYS}</td>
103 * <td>{@link SystemPropertyStringLookup}</td>
104 * <td>{@link #systemPropertyStringLookup()}</td>
105 * <td>1.3</td>
106 * </tr>
107 * <tr>
108 * <td>{@value #KEY_URL}</td>
109 * <td>{@link UrlStringLookup}</td>
110 * <td>{@link #urlStringLookup()}</td>
111 * <td>1.5</td>
112 * </tr>
113 * <tr>
114 * <td>{@value #KEY_URL_DECODER}</td>
115 * <td>{@link UrlDecoderStringLookup}</td>
116 * <td>{@link #urlDecoderStringLookup()}</td>
117 * <td>1.5</td>
118 * </tr>
119 * <tr>
120 * <td>{@value #KEY_URL_ENCODER}</td>
121 * <td>{@link UrlEncoderStringLookup}</td>
122 * <td>{@link #urlEncoderStringLookup()}</td>
123 * <td>1.5</td>
124 * </tr>
125 * <tr>
126 * <td>{@value #KEY_XML}</td>
127 * <td>{@link XmlStringLookup}</td>
128 * <td>{@link #xmlStringLookup()}</td>
129 * <td>1.5</td>
130 * </tr>
131 * </table>
132 *
133 * @since 1.3
134 */
135public final class StringLookupFactory {
136
137    /**
138     * Defines the singleton for this class.
139     */
140    public static final StringLookupFactory INSTANCE = new StringLookupFactory();
141
142    /**
143     * Default lookup key for interpolation.
144     *
145     * @since 1.6
146     */
147    public static final String KEY_BASE64_DECODER = "base64Decoder";
148
149    /**
150     * Default lookup key for interpolation.
151     *
152     * @since 1.6
153     */
154    public static final String KEY_BASE64_ENCODER = "base64Encoder";
155
156    /**
157     * Default lookup key for interpolation.
158     *
159     * @since 1.6
160     */
161    public static final String KEY_CONST = "const";
162
163    /**
164     * Default lookup key for interpolation.
165     *
166     * @since 1.6
167     */
168    public static final String KEY_DATE = "date";
169
170    /**
171     * Default lookup key for interpolation.
172     *
173     * @since 1.6
174     */
175    public static final String KEY_ENV = "env";
176
177    /**
178     * Default lookup key for interpolation.
179     *
180     * @since 1.6
181     */
182    public static final String KEY_FILE = "file";
183
184    /**
185     * Default lookup key for interpolation.
186     *
187     * @since 1.6
188     */
189    public static final String KEY_JAVA = "java";
190
191    /**
192     * Default lookup key for interpolation.
193     *
194     * @since 1.6
195     */
196    public static final String KEY_LOCALHOST = "localhost";
197
198    /**
199     * Default lookup key for interpolation.
200     *
201     * @since 1.6
202     */
203    public static final String KEY_PROPERTIES = "properties";
204
205    /**
206     * Default lookup key for interpolation.
207     *
208     * @since 1.6
209     */
210    public static final String KEY_RESOURCE_BUNDLE = "resourceBundle";
211
212    /**
213     * Default lookup key for interpolation.
214     *
215     * @since 1.6
216     */
217    public static final String KEY_SCRIPT = "script";
218
219    /**
220     * Default lookup key for interpolation.
221     *
222     * @since 1.6
223     */
224    public static final String KEY_SYS = "sys";
225
226    /**
227     * Default lookup key for interpolation.
228     *
229     * @since 1.6
230     */
231    public static final String KEY_URL = "url";
232
233    /**
234     * Default lookup key for interpolation.
235     *
236     * @since 1.6
237     */
238    public static final String KEY_URL_DECODER = "urlDecoder";
239
240    /**
241     * Default lookup key for interpolation.
242     *
243     * @since 1.6
244     */
245    public static final String KEY_URL_ENCODER = "urlEncoder";
246
247    /**
248     * Default lookup key for interpolation.
249     *
250     * @since 1.6
251     */
252    public static final String KEY_XML = "xml";
253
254    /**
255     * Clears any static resources.
256     *
257     * @since 1.5
258     */
259    public static void clear() {
260        ConstantStringLookup.clear();
261    }
262
263    /**
264     * No need to build instances for now.
265     */
266    private StringLookupFactory() {
267        // empty
268    }
269
270    /**
271     * Adds the {@link StringLookupFactory default lookups}.
272     *
273     * @param stringLookupMap
274     *            the map of string lookups.
275     * @since 1.5
276     */
277    public void addDefaultStringLookups(final Map<String, StringLookup> stringLookupMap) {
278        if (stringLookupMap != null) {
279            // "base64" is deprecated in favor of KEY_BASE64_DECODER.
280            stringLookupMap.put("base64", Base64DecoderStringLookup.INSTANCE);
281            stringLookupMap.put(KEY_BASE64_DECODER, Base64DecoderStringLookup.INSTANCE);
282            stringLookupMap.put(KEY_BASE64_ENCODER, Base64EncoderStringLookup.INSTANCE);
283            stringLookupMap.put(KEY_CONST, ConstantStringLookup.INSTANCE);
284            stringLookupMap.put(KEY_DATE, DateStringLookup.INSTANCE);
285            stringLookupMap.put(KEY_ENV, EnvironmentVariableStringLookup.INSTANCE);
286            stringLookupMap.put(KEY_FILE, FileStringLookup.INSTANCE);
287            stringLookupMap.put(KEY_JAVA, JavaPlatformStringLookup.INSTANCE);
288            stringLookupMap.put(KEY_LOCALHOST, LocalHostStringLookup.INSTANCE);
289            stringLookupMap.put(KEY_PROPERTIES, PropertiesStringLookup.INSTANCE);
290            stringLookupMap.put(KEY_RESOURCE_BUNDLE, ResourceBundleStringLookup.INSTANCE);
291            stringLookupMap.put(KEY_SCRIPT, ScriptStringLookup.INSTANCE);
292            stringLookupMap.put(KEY_SYS, SystemPropertyStringLookup.INSTANCE);
293            stringLookupMap.put(KEY_URL, UrlStringLookup.INSTANCE);
294            stringLookupMap.put(KEY_URL_DECODER, UrlDecoderStringLookup.INSTANCE);
295            stringLookupMap.put(KEY_URL_ENCODER, UrlEncoderStringLookup.INSTANCE);
296            stringLookupMap.put(KEY_XML, XmlStringLookup.INSTANCE);
297        }
298    }
299
300    /**
301     * Returns the Base64StringLookup singleton instance to format the current date with the format given in the key in
302     * a format compatible with {@link java.text.SimpleDateFormat}.
303     *
304     * @return the DateStringLookup singleton instance.
305     * @since 1.5
306     */
307    public StringLookup base64DecoderStringLookup() {
308        return Base64DecoderStringLookup.INSTANCE;
309    }
310
311    /**
312     * Returns the Base64StringLookup singleton instance to format the current date with the format given in the key in
313     * a format compatible with {@link java.text.SimpleDateFormat}.
314     *
315     * @return the DateStringLookup singleton instance.
316     * @since 1.6
317     */
318    public StringLookup base64EncoderStringLookup() {
319        return Base64EncoderStringLookup.INSTANCE;
320    }
321
322    /**
323     * Returns the Base64StringLookup singleton instance to format the current date with the format given in the key in
324     * a format compatible with {@link java.text.SimpleDateFormat}.
325     *
326     * @return the DateStringLookup singleton instance.
327     * @since 1.5
328     * @deprecated Use {@link #base64DecoderStringLookup()}.
329     */
330    @Deprecated
331    public StringLookup base64StringLookup() {
332        return Base64DecoderStringLookup.INSTANCE;
333    }
334
335    /**
336     * Returns the ConstantStringLookup singleton instance to get the value of a fully-qualified static final value.
337     *
338     * @return the DateStringLookup singleton instance.
339     * @since 1.5
340     */
341    public StringLookup constantStringLookup() {
342        return ConstantStringLookup.INSTANCE;
343    }
344
345    /**
346     * Returns the DateStringLookup singleton instance to format the current date with the format given in the key in a
347     * format compatible with {@link java.text.SimpleDateFormat}.
348     *
349     * @return the DateStringLookup singleton instance.
350     */
351    public StringLookup dateStringLookup() {
352        return DateStringLookup.INSTANCE;
353    }
354
355    /**
356     * Returns the EnvironmentVariableStringLookup singleton instance where the lookup key is an environment variable
357     * name.
358     *
359     * @return the EnvironmentVariableStringLookup singleton instance.
360     */
361    public StringLookup environmentVariableStringLookup() {
362        return EnvironmentVariableStringLookup.INSTANCE;
363    }
364
365    /**
366     * Returns the FileStringLookup singleton instance.
367     * <p>
368     * Looks up the value for the key in the format "CharsetName:Path".
369     * </p>
370     * <p>
371     * For example: "UTF-8:com/domain/document.properties".
372     * </p>
373     *
374     * @return the FileStringLookup singleton instance.
375     * @since 1.5
376     */
377    public StringLookup fileStringLookup() {
378        return FileStringLookup.INSTANCE;
379    }
380
381    /**
382     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
383     *
384     * @return a new InterpolatorStringLookup.
385     */
386    public StringLookup interpolatorStringLookup() {
387        return InterpolatorStringLookup.INSTANCE;
388    }
389
390    /**
391     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
392     * <p>
393     * If {@code addDefaultLookups} is true, the following lookups are used in addition to the ones provided in
394     * {@code stringLookupMap}:
395     * </p>
396     *
397     * @param stringLookupMap
398     *            the map of string lookups.
399     * @param defaultStringLookup
400     *            the default string lookup.
401     * @param addDefaultLookups
402     *            whether to use lookups as described above.
403     * @return a new InterpolatorStringLookup.
404     * @since 1.4
405     */
406    public StringLookup interpolatorStringLookup(final Map<String, StringLookup> stringLookupMap,
407            final StringLookup defaultStringLookup, final boolean addDefaultLookups) {
408        return new InterpolatorStringLookup(stringLookupMap, defaultStringLookup, addDefaultLookups);
409    }
410
411    /**
412     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
413     *
414     * @param <V>
415     *            the value type the default string lookup's map.
416     * @param map
417     *            the default map for string lookups.
418     * @return a new InterpolatorStringLookup.
419     */
420    public <V> StringLookup interpolatorStringLookup(final Map<String, V> map) {
421        return new InterpolatorStringLookup(map);
422    }
423
424    /**
425     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
426     *
427     * @param defaultStringLookup
428     *            the default string lookup.
429     * @return a new InterpolatorStringLookup.
430     */
431    public StringLookup interpolatorStringLookup(final StringLookup defaultStringLookup) {
432        return new InterpolatorStringLookup(defaultStringLookup);
433    }
434
435    /**
436     * Returns the JavaPlatformStringLookup singleton instance. Looks up keys related to Java: Java version, JRE
437     * version, VM version, and so on.
438     * <p>
439     * The lookup keys with examples are:
440     * </p>
441     * <ul>
442     * <li><b>version</b>: "Java version 1.8.0_181"</li>
443     * <li><b>runtime</b>: "Java(TM) SE Runtime Environment (build 1.8.0_181-b13) from Oracle Corporation"</li>
444     * <li><b>vm</b>: "Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)"</li>
445     * <li><b>os</b>: "Windows 10 10.0, architecture: amd64-64"</li>
446     * <li><b>hardware</b>: "processors: 4, architecture: amd64-64, instruction sets: amd64"</li>
447     * <li><b>locale</b>: "default locale: en_US, platform encoding: iso-8859-1"</li>
448     * </ul>
449     *
450     * @return the JavaPlatformStringLookup singleton instance.
451     */
452    public StringLookup javaPlatformStringLookup() {
453        return JavaPlatformStringLookup.INSTANCE;
454    }
455
456    /**
457     * Returns the LocalHostStringLookup singleton instance where the lookup key is one of:
458     * <ul>
459     * <li><b>name</b>: for the local host name, for example {@code EXAMPLE}.</li>
460     * <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li>
461     * <li><b>address</b>: for the local host address, for example {@code 192.168.56.1}.</li>
462     * </ul>
463     *
464     * @return the DateStringLookup singleton instance.
465     */
466    public StringLookup localHostStringLookup() {
467        return LocalHostStringLookup.INSTANCE;
468    }
469
470    /**
471     * Returns a new map-based lookup where the request for a lookup is answered with the value for that key.
472     *
473     * @param <V>
474     *            the map value type.
475     * @param map
476     *            the map.
477     * @return a new MapStringLookup.
478     */
479    public <V> StringLookup mapStringLookup(final Map<String, V> map) {
480        return MapStringLookup.on(map);
481    }
482
483    /**
484     * Returns the NullStringLookup singleton instance which always returns null.
485     *
486     * @return the NullStringLookup singleton instance.
487     */
488    public StringLookup nullStringLookup() {
489        return NullStringLookup.INSTANCE;
490    }
491
492    /**
493     * Returns the PropertiesStringLookup singleton instance.
494     * <p>
495     * Looks up the value for the key in the format "DocumentPath:Key".
496     * </p>
497     * <p>
498     * For example: "com/domain/document.properties:Key".
499     * </p>
500     *
501     * @return the PropertiesStringLookup singleton instance.
502     * @since 1.5
503     */
504    public StringLookup propertiesStringLookup() {
505        return PropertiesStringLookup.INSTANCE;
506    }
507
508    /**
509     * Returns the ResourceBundleStringLookup singleton instance.
510     * <p>
511     * Looks up the value for a given key in the format "BundleName:BundleKey".
512     * </p>
513     * <p>
514     * For example: "com.domain.messages:MyKey".
515     * </p>
516     *
517     * @return the ResourceBundleStringLookup singleton instance.
518     */
519    public StringLookup resourceBundleStringLookup() {
520        return ResourceBundleStringLookup.INSTANCE;
521    }
522
523    /**
524     * Returns a ResourceBundleStringLookup instance for the given bundle name.
525     * <p>
526     * Looks up the value for a given key in the format "BundleKey".
527     * </p>
528     * <p>
529     * For example: "MyKey".
530     * </p>
531     *
532     * @param bundleName
533     *            Only lookup in this bundle.
534     * @return a ResourceBundleStringLookup instance for the given bundle name.
535     * @since 1.5
536     */
537    public StringLookup resourceBundleStringLookup(final String bundleName) {
538        return new ResourceBundleStringLookup(bundleName);
539    }
540
541    /**
542     * Returns the ScriptStringLookup singleton instance.
543     * <p>
544     * Looks up the value for the key in the format "ScriptEngineName:Script".
545     * </p>
546     * <p>
547     * For example: "javascript:\"HelloWorld\"".
548     * </p>
549     *
550     * @return the ScriptStringLookup singleton instance.
551     * @since 1.5
552     */
553    public StringLookup scriptStringLookup() {
554        return ScriptStringLookup.INSTANCE;
555    }
556
557    /**
558     * Returns the SystemPropertyStringLookup singleton instance where the lookup key is a system property name.
559     *
560     * @return the SystemPropertyStringLookup singleton instance.
561     */
562    public StringLookup systemPropertyStringLookup() {
563        return SystemPropertyStringLookup.INSTANCE;
564    }
565
566    /**
567     * Returns the UrlDecoderStringLookup singleton instance.
568     * <p>
569     * Decodes URL Strings using the UTF-8 encoding.
570     * </p>
571     * <p>
572     * For example: "Hello%20World%21" becomes "Hello World!".
573     * </p>
574     *
575     * @return the UrlStringLookup singleton instance.
576     * @since 1.6
577     */
578    public StringLookup urlDecoderStringLookup() {
579        return UrlDecoderStringLookup.INSTANCE;
580    }
581
582    /**
583     * Returns the UrlDecoderStringLookup singleton instance.
584     * <p>
585     * Decodes URL Strings using the UTF-8 encoding.
586     * </p>
587     * <p>
588     * For example: "Hello World!" becomes "Hello+World%21".
589     * </p>
590     *
591     * @return the UrlStringLookup singleton instance.
592     * @since 1.6
593     */
594    public StringLookup urlEncoderStringLookup() {
595        return UrlEncoderStringLookup.INSTANCE;
596    }
597
598    /**
599     * Returns the UrlStringLookup singleton instance.
600     * <p>
601     * Looks up the value for the key in the format "CharsetName:URL".
602     * </p>
603     * <p>
604     * For example, using the HTTP scheme: "UTF-8:http://www.google.com"
605     * </p>
606     * <p>
607     * For example, using the file scheme:
608     * "UTF-8:file:///C:/somehome/commons/commons-text/src/test/resources/document.properties"
609     * </p>
610     *
611     * @return the UrlStringLookup singleton instance.
612     * @since 1.5
613     */
614    public StringLookup urlStringLookup() {
615        return UrlStringLookup.INSTANCE;
616    }
617
618    /**
619     * Returns the XmlStringLookup singleton instance.
620     * <p>
621     * Looks up the value for the key in the format "DocumentPath:XPath".
622     * </p>
623     * <p>
624     * For example: "com/domain/document.xml:/path/to/node".
625     * </p>
626     *
627     * @return the XmlStringLookup singleton instance.
628     * @since 1.5
629     */
630    public StringLookup xmlStringLookup() {
631        return XmlStringLookup.INSTANCE;
632    }
633
634}