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            for (final DefaultStringLookup stringLookup : DefaultStringLookup.values()) {
282                stringLookupMap.put(stringLookup.getKey(), stringLookup.getStringLookup());
283            }
284        }
285    }
286
287    /**
288     * Returns the Base64DecoderStringLookup singleton instance to format the current date with the format given in the
289     * key in a format compatible with {@link java.text.SimpleDateFormat}.
290     *
291     * @return the DateStringLookup singleton instance.
292     * @since 1.5
293     */
294    public StringLookup base64DecoderStringLookup() {
295        return Base64DecoderStringLookup.INSTANCE;
296    }
297
298    /**
299     * Returns the Base64EncoderStringLookup singleton instance to format the current date with the format given in the
300     * key in a format compatible with {@link java.text.SimpleDateFormat}.
301     *
302     * @return the DateStringLookup singleton instance.
303     * @since 1.6
304     */
305    public StringLookup base64EncoderStringLookup() {
306        return Base64EncoderStringLookup.INSTANCE;
307    }
308
309    /**
310     * Returns the Base64DecoderStringLookup singleton instance to format the current date with the format given in the
311     * key in a format compatible with {@link java.text.SimpleDateFormat}.
312     *
313     * @return the DateStringLookup singleton instance.
314     * @since 1.5
315     * @deprecated Use {@link #base64DecoderStringLookup()}.
316     */
317    @Deprecated
318    public StringLookup base64StringLookup() {
319        return Base64DecoderStringLookup.INSTANCE;
320    }
321
322    /**
323     * Returns the ConstantStringLookup singleton instance to get the value of a fully-qualified static final value.
324     *
325     * @return the DateStringLookup singleton instance.
326     * @since 1.5
327     */
328    public StringLookup constantStringLookup() {
329        return ConstantStringLookup.INSTANCE;
330    }
331
332    /**
333     * Returns the DateStringLookup singleton instance to format the current date with the format given in the key in a
334     * format compatible with {@link java.text.SimpleDateFormat}.
335     *
336     * @return the DateStringLookup singleton instance.
337     */
338    public StringLookup dateStringLookup() {
339        return DateStringLookup.INSTANCE;
340    }
341
342    /**
343     * Returns the EnvironmentVariableStringLookup singleton instance where the lookup key is an environment variable
344     * name.
345     *
346     * @return the EnvironmentVariableStringLookup singleton instance.
347     */
348    public StringLookup environmentVariableStringLookup() {
349        return EnvironmentVariableStringLookup.INSTANCE;
350    }
351
352    /**
353     * Returns the FileStringLookup singleton instance.
354     * <p>
355     * Looks up the value for the key in the format "CharsetName:Path".
356     * </p>
357     * <p>
358     * For example: "UTF-8:com/domain/document.properties".
359     * </p>
360     *
361     * @return the FileStringLookup singleton instance.
362     * @since 1.5
363     */
364    public StringLookup fileStringLookup() {
365        return FileStringLookup.INSTANCE;
366    }
367
368    /**
369     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
370     *
371     * @return a new InterpolatorStringLookup.
372     */
373    public StringLookup interpolatorStringLookup() {
374        return InterpolatorStringLookup.INSTANCE;
375    }
376
377    /**
378     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
379     * <p>
380     * If {@code addDefaultLookups} is true, the following lookups are used in addition to the ones provided in
381     * {@code stringLookupMap}:
382     * </p>
383     *
384     * @param stringLookupMap
385     *            the map of string lookups.
386     * @param defaultStringLookup
387     *            the default string lookup.
388     * @param addDefaultLookups
389     *            whether to use lookups as described above.
390     * @return a new InterpolatorStringLookup.
391     * @since 1.4
392     */
393    public StringLookup interpolatorStringLookup(final Map<String, StringLookup> stringLookupMap,
394            final StringLookup defaultStringLookup, final boolean addDefaultLookups) {
395        return new InterpolatorStringLookup(stringLookupMap, defaultStringLookup, addDefaultLookups);
396    }
397
398    /**
399     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
400     *
401     * @param <V>
402     *            the value type the default string lookup's map.
403     * @param map
404     *            the default map for string lookups.
405     * @return a new InterpolatorStringLookup.
406     */
407    public <V> StringLookup interpolatorStringLookup(final Map<String, V> map) {
408        return new InterpolatorStringLookup(map);
409    }
410
411    /**
412     * Returns a new InterpolatorStringLookup using the {@link StringLookupFactory default lookups}.
413     *
414     * @param defaultStringLookup
415     *            the default string lookup.
416     * @return a new InterpolatorStringLookup.
417     */
418    public StringLookup interpolatorStringLookup(final StringLookup defaultStringLookup) {
419        return new InterpolatorStringLookup(defaultStringLookup);
420    }
421
422    /**
423     * Returns the JavaPlatformStringLookup singleton instance. Looks up keys related to Java: Java version, JRE
424     * version, VM version, and so on.
425     * <p>
426     * The lookup keys with examples are:
427     * </p>
428     * <ul>
429     * <li><b>version</b>: "Java version 1.8.0_181"</li>
430     * <li><b>runtime</b>: "Java(TM) SE Runtime Environment (build 1.8.0_181-b13) from Oracle Corporation"</li>
431     * <li><b>vm</b>: "Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)"</li>
432     * <li><b>os</b>: "Windows 10 10.0, architecture: amd64-64"</li>
433     * <li><b>hardware</b>: "processors: 4, architecture: amd64-64, instruction sets: amd64"</li>
434     * <li><b>locale</b>: "default locale: en_US, platform encoding: iso-8859-1"</li>
435     * </ul>
436     *
437     * @return the JavaPlatformStringLookup singleton instance.
438     */
439    public StringLookup javaPlatformStringLookup() {
440        return JavaPlatformStringLookup.INSTANCE;
441    }
442
443    /**
444     * Returns the LocalHostStringLookup singleton instance where the lookup key is one of:
445     * <ul>
446     * <li><b>name</b>: for the local host name, for example {@code EXAMPLE}.</li>
447     * <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li>
448     * <li><b>address</b>: for the local host address, for example {@code 192.168.56.1}.</li>
449     * </ul>
450     *
451     * @return the DateStringLookup singleton instance.
452     */
453    public StringLookup localHostStringLookup() {
454        return LocalHostStringLookup.INSTANCE;
455    }
456
457    /**
458     * Returns a new map-based lookup where the request for a lookup is answered with the value for that key.
459     *
460     * @param <V>
461     *            the map value type.
462     * @param map
463     *            the map.
464     * @return a new MapStringLookup.
465     */
466    public <V> StringLookup mapStringLookup(final Map<String, V> map) {
467        return MapStringLookup.on(map);
468    }
469
470    /**
471     * Returns the NullStringLookup singleton instance which always returns null.
472     *
473     * @return the NullStringLookup singleton instance.
474     */
475    public StringLookup nullStringLookup() {
476        return NullStringLookup.INSTANCE;
477    }
478
479    /**
480     * Returns the PropertiesStringLookup singleton instance.
481     * <p>
482     * Looks up the value for the key in the format "DocumentPath:Key".
483     * </p>
484     * <p>
485     * For example: "com/domain/document.properties:Key".
486     * </p>
487     *
488     * @return the PropertiesStringLookup singleton instance.
489     * @since 1.5
490     */
491    public StringLookup propertiesStringLookup() {
492        return PropertiesStringLookup.INSTANCE;
493    }
494
495    /**
496     * Returns the ResourceBundleStringLookup singleton instance.
497     * <p>
498     * Looks up the value for a given key in the format "BundleName:BundleKey".
499     * </p>
500     * <p>
501     * For example: "com.domain.messages:MyKey".
502     * </p>
503     *
504     * @return the ResourceBundleStringLookup singleton instance.
505     */
506    public StringLookup resourceBundleStringLookup() {
507        return ResourceBundleStringLookup.INSTANCE;
508    }
509
510    /**
511     * Returns a ResourceBundleStringLookup instance for the given bundle name.
512     * <p>
513     * Looks up the value for a given key in the format "BundleKey".
514     * </p>
515     * <p>
516     * For example: "MyKey".
517     * </p>
518     *
519     * @param bundleName
520     *            Only lookup in this bundle.
521     * @return a ResourceBundleStringLookup instance for the given bundle name.
522     * @since 1.5
523     */
524    public StringLookup resourceBundleStringLookup(final String bundleName) {
525        return new ResourceBundleStringLookup(bundleName);
526    }
527
528    /**
529     * Returns the ScriptStringLookup singleton instance.
530     * <p>
531     * Looks up the value for the key in the format "ScriptEngineName:Script".
532     * </p>
533     * <p>
534     * For example: "javascript:\"HelloWorld\"".
535     * </p>
536     *
537     * @return the ScriptStringLookup singleton instance.
538     * @since 1.5
539     */
540    public StringLookup scriptStringLookup() {
541        return ScriptStringLookup.INSTANCE;
542    }
543
544    /**
545     * Returns the SystemPropertyStringLookup singleton instance where the lookup key is a system property name.
546     *
547     * @return the SystemPropertyStringLookup singleton instance.
548     */
549    public StringLookup systemPropertyStringLookup() {
550        return SystemPropertyStringLookup.INSTANCE;
551    }
552
553    /**
554     * Returns the UrlDecoderStringLookup singleton instance.
555     * <p>
556     * Decodes URL Strings using the UTF-8 encoding.
557     * </p>
558     * <p>
559     * For example: "Hello%20World%21" becomes "Hello World!".
560     * </p>
561     *
562     * @return the UrlStringLookup singleton instance.
563     * @since 1.6
564     */
565    public StringLookup urlDecoderStringLookup() {
566        return UrlDecoderStringLookup.INSTANCE;
567    }
568
569    /**
570     * Returns the UrlDecoderStringLookup singleton instance.
571     * <p>
572     * Decodes URL Strings using the UTF-8 encoding.
573     * </p>
574     * <p>
575     * For example: "Hello World!" becomes "Hello+World%21".
576     * </p>
577     *
578     * @return the UrlStringLookup singleton instance.
579     * @since 1.6
580     */
581    public StringLookup urlEncoderStringLookup() {
582        return UrlEncoderStringLookup.INSTANCE;
583    }
584
585    /**
586     * Returns the UrlStringLookup singleton instance.
587     * <p>
588     * Looks up the value for the key in the format "CharsetName:URL".
589     * </p>
590     * <p>
591     * For example, using the HTTP scheme: "UTF-8:http://www.google.com"
592     * </p>
593     * <p>
594     * For example, using the file scheme:
595     * "UTF-8:file:///C:/somehome/commons/commons-text/src/test/resources/document.properties"
596     * </p>
597     *
598     * @return the UrlStringLookup singleton instance.
599     * @since 1.5
600     */
601    public StringLookup urlStringLookup() {
602        return UrlStringLookup.INSTANCE;
603    }
604
605    /**
606     * Returns the XmlStringLookup singleton instance.
607     * <p>
608     * Looks up the value for the key in the format "DocumentPath:XPath".
609     * </p>
610     * <p>
611     * For example: "com/domain/document.xml:/path/to/node".
612     * </p>
613     *
614     * @return the XmlStringLookup singleton instance.
615     * @since 1.5
616     */
617    public StringLookup xmlStringLookup() {
618        return XmlStringLookup.INSTANCE;
619    }
620
621}