StrLookup.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.text;

  18. import java.util.Collections;
  19. import java.util.Map;
  20. import java.util.Objects;
  21. import java.util.ResourceBundle;

  22. import org.apache.commons.text.lookup.StringLookup;
  23. import org.apache.commons.text.lookup.StringLookupFactory;

  24. /**
  25.  * Lookup a String key to a String value.
  26.  * <p>
  27.  * This class represents the simplest form of a string to string map. It has a benefit over a map in that it can create
  28.  * the result on demand based on the key.
  29.  * </p>
  30.  * <p>
  31.  * This class comes complete with various factory methods. If these do not suffice, you can subclass and implement your
  32.  * own matcher.
  33.  * </p>
  34.  * <p>
  35.  * For example, it would be possible to implement a lookup that used the key as a primary key, and looked up the value
  36.  * on demand from the database
  37.  * </p>
  38.  *
  39.  * @param <V> the type of the values supported by the lookup
  40.  * @since 1.0
  41.  * @deprecated Deprecated as of 1.3, use {@link StringLookupFactory} instead. This class will be removed in 2.0.
  42.  */
  43. @Deprecated
  44. public abstract class StrLookup<V> implements StringLookup {

  45.     /**
  46.      * Lookup implementation that uses a Map.
  47.      *
  48.      * @param <V> the type of the values supported by the lookup
  49.      */
  50.     private static final class MapStrLookup<V> extends StrLookup<V> {

  51.         /** Map keys are variable names and value. */
  52.         private final Map<String, V> map;

  53.         /**
  54.          * Creates a new instance backed by a Map.
  55.          *
  56.          * @param map the map of keys to values, may be null
  57.          */
  58.         private MapStrLookup(final Map<String, V> map) {
  59.             this.map = map != null ? map : Collections.emptyMap();
  60.         }

  61.         /**
  62.          * Looks up a String key to a String value using the map.
  63.          * <p>
  64.          * If the map is null, then null is returned. The map result object is converted to a string using toString().
  65.          * </p>
  66.          *
  67.          * @param key the key to be looked up, may be null
  68.          * @return The matching value, null if no match
  69.          */
  70.         @Override
  71.         public String lookup(final String key) {
  72.             return Objects.toString(map.get(key), null);
  73.         }

  74.         @Override
  75.         public String toString() {
  76.             return super.toString() + " [map=" + map + "]";
  77.         }
  78.     }

  79.     /**
  80.      * Lookup implementation based on a ResourceBundle.
  81.      */
  82.     private static final class ResourceBundleLookup extends StrLookup<String> {

  83.         /** ResourceBundle keys are variable names and value. */
  84.         private final ResourceBundle resourceBundle;

  85.         /**
  86.          * Creates a new instance backed by a ResourceBundle.
  87.          *
  88.          * @param resourceBundle the ResourceBundle of keys to values, may be null
  89.          */
  90.         private ResourceBundleLookup(final ResourceBundle resourceBundle) {
  91.             this.resourceBundle = resourceBundle;
  92.         }

  93.         @Override
  94.         public String lookup(final String key) {
  95.             if (resourceBundle == null || key == null || !resourceBundle.containsKey(key)) {
  96.                 return null;
  97.             }
  98.             return resourceBundle.getString(key);
  99.         }

  100.         @Override
  101.         public String toString() {
  102.             return super.toString() + " [resourceBundle=" + resourceBundle + "]";
  103.         }

  104.     }

  105.     /**
  106.      * Lookup implementation based on system properties.
  107.      */
  108.     private static final class SystemPropertiesStrLookup extends StrLookup<String> {

  109.         /**
  110.          * Private for Spotbugs SING_SINGLETON_GETTER_NOT_SYNCHRONIZED.
  111.          */
  112.         private SystemPropertiesStrLookup() {
  113.             // default
  114.         }

  115.         /**
  116.          * {@inheritDoc} This implementation directly accesses system properties.
  117.          */
  118.         @Override
  119.         public String lookup(final String key) {
  120.             if (!key.isEmpty()) {
  121.                 try {
  122.                     return System.getProperty(key);
  123.                 } catch (final SecurityException ignored) {
  124.                     // Noop: All lookup(String) will return null.
  125.                 }
  126.             }
  127.             return null;
  128.         }
  129.     }

  130.     /**
  131.      * Lookup that always returns null.
  132.      */
  133.     private static final StrLookup<String> NONE_LOOKUP = new MapStrLookup<>(null);

  134.     /**
  135.      * Lookup based on system properties.
  136.      */
  137.     private static final StrLookup<String> SYSTEM_PROPERTIES_LOOKUP = new SystemPropertiesStrLookup();

  138.     /**
  139.      * Returns a lookup which looks up values using a map.
  140.      * <p>
  141.      * If the map is null, then null will be returned from every lookup. The map result object is converted to a string
  142.      * using toString().
  143.      * </p>
  144.      *
  145.      * @param <V> the type of the values supported by the lookup
  146.      * @param map the map of keys to values, may be null
  147.      * @return a lookup using the map, not null
  148.      */
  149.     public static <V> StrLookup<V> mapLookup(final Map<String, V> map) {
  150.         return new MapStrLookup<>(map);
  151.     }

  152.     /**
  153.      * Returns a lookup which always returns null.
  154.      *
  155.      * @return a lookup that always returns null, not null
  156.      */
  157.     public static StrLookup<?> noneLookup() {
  158.         return NONE_LOOKUP;
  159.     }

  160.     /**
  161.      * Returns a lookup which looks up values using a ResourceBundle.
  162.      * <p>
  163.      * If the ResourceBundle is null, then null will be returned from every lookup. The map result object is converted
  164.      * to a string using toString().
  165.      * </p>
  166.      *
  167.      * @param resourceBundle the map of keys to values, may be null
  168.      * @return a lookup using the map, not null
  169.      * @see StringLookupFactory#resourceBundleStringLookup(String)
  170.      */
  171.     public static StrLookup<String> resourceBundleLookup(final ResourceBundle resourceBundle) {
  172.         return new ResourceBundleLookup(resourceBundle);
  173.     }

  174.     /**
  175.      * Returns a new lookup which uses a copy of the current {@link System#getProperties() System properties}.
  176.      * <p>
  177.      * If a security manager blocked access to system properties, then null will be returned from every lookup.
  178.      * </p>
  179.      * <p>
  180.      * If a null key is used, this lookup will throw a NullPointerException.
  181.      * </p>
  182.      *
  183.      * @return a lookup using system properties, not null
  184.      */
  185.     public static StrLookup<String> systemPropertiesLookup() {
  186.         return SYSTEM_PROPERTIES_LOOKUP;
  187.     }

  188.     /**
  189.      * Constructs a new instance for subclasses.
  190.      */
  191.     protected StrLookup() {
  192.     }
  193. }