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 * https://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
19 import java.util.Collections;
20 import java.util.Map;
21 import java.util.Objects;
22 import java.util.ResourceBundle;
23
24 import org.apache.commons.text.lookup.StringLookup;
25 import org.apache.commons.text.lookup.StringLookupFactory;
26
27 /**
28 * Lookup a String key to a String value.
29 * <p>
30 * This class represents the simplest form of a string to string map. It has a benefit over a map in that it can create
31 * the result on demand based on the key.
32 * </p>
33 * <p>
34 * This class comes complete with various factory methods. If these do not suffice, you can subclass and implement your
35 * own matcher.
36 * </p>
37 * <p>
38 * For example, it would be possible to implement a lookup that used the key as a primary key, and looked up the value
39 * on demand from the database
40 * </p>
41 *
42 * @param <V> the type of the values supported by the lookup
43 * @since 1.0
44 * @deprecated Deprecated as of 1.3, use {@link StringLookupFactory} instead. This class will be removed in 2.0.
45 */
46 @Deprecated
47 public abstract class StrLookup<V> implements StringLookup {
48
49 /**
50 * Lookup implementation that uses a Map.
51 *
52 * @param <V> the type of the values supported by the lookup
53 */
54 private static final class MapStrLookup<V> extends StrLookup<V> {
55
56 /** Map keys are variable names and value. */
57 private final Map<String, V> map;
58
59 /**
60 * Creates a new instance backed by a Map.
61 *
62 * @param map the map of keys to values, may be null
63 */
64 private MapStrLookup(final Map<String, V> map) {
65 this.map = map != null ? map : Collections.emptyMap();
66 }
67
68 /**
69 * Looks up a String key to a String value using the map.
70 * <p>
71 * If the map is null, then null is returned. The map result object is converted to a string using toString().
72 * </p>
73 *
74 * @param key the key to be looked up, may be null
75 * @return The matching value, null if no match
76 */
77 @Override
78 public String lookup(final String key) {
79 return Objects.toString(map.get(key), null);
80 }
81
82 @Override
83 public String toString() {
84 return super.toString() + " [map=" + map + "]";
85 }
86 }
87
88 /**
89 * Lookup implementation based on a ResourceBundle.
90 */
91 private static final class ResourceBundleLookup extends StrLookup<String> {
92
93 /** ResourceBundle keys are variable names and value. */
94 private final ResourceBundle resourceBundle;
95
96 /**
97 * Creates a new instance backed by a ResourceBundle.
98 *
99 * @param resourceBundle the ResourceBundle of keys to values, may be null.
100 */
101 private ResourceBundleLookup(final ResourceBundle resourceBundle) {
102 this.resourceBundle = resourceBundle;
103 }
104
105 @Override
106 public String lookup(final String key) {
107 if (resourceBundle == null || key == null || !resourceBundle.containsKey(key)) {
108 return null;
109 }
110 return resourceBundle.getString(key);
111 }
112
113 @Override
114 public String toString() {
115 return super.toString() + " [resourceBundle=" + resourceBundle + "]";
116 }
117
118 }
119
120 /**
121 * Lookup implementation based on system properties.
122 */
123 private static final class SystemPropertiesStrLookup extends StrLookup<String> {
124
125 /**
126 * Private for Spotbugs SING_SINGLETON_GETTER_NOT_SYNCHRONIZED.
127 */
128 private SystemPropertiesStrLookup() {
129 // default
130 }
131
132 /**
133 * {@inheritDoc} This implementation directly accesses system properties.
134 */
135 @Override
136 public String lookup(final String key) {
137 if (!key.isEmpty()) {
138 try {
139 return System.getProperty(key);
140 } catch (final SecurityException ignored) {
141 // Noop: All lookup(String) will return null.
142 }
143 }
144 return null;
145 }
146 }
147
148 /**
149 * Lookup that always returns null.
150 */
151 private static final StrLookup<String> NONE_LOOKUP = new MapStrLookup<>(null);
152
153 /**
154 * Lookup based on system properties.
155 */
156 private static final StrLookup<String> SYSTEM_PROPERTIES_LOOKUP = new SystemPropertiesStrLookup();
157
158 /**
159 * Returns a lookup which looks up values using a map.
160 * <p>
161 * If the map is null, then null will be returned from every lookup. The map result object is converted to a string
162 * using toString().
163 * </p>
164 *
165 * @param <V> the type of the values supported by the lookup.
166 * @param map the map of keys to values, may be null.
167 * @return a lookup using the map, not null.
168 */
169 public static <V> StrLookup<V> mapLookup(final Map<String, V> map) {
170 return new MapStrLookup<>(map);
171 }
172
173 /**
174 * Returns a lookup which always returns null.
175 *
176 * @return a lookup that always returns null, not null.
177 */
178 public static StrLookup<?> noneLookup() {
179 return NONE_LOOKUP;
180 }
181
182 /**
183 * Returns a lookup which looks up values using a ResourceBundle.
184 * <p>
185 * If the ResourceBundle is null, then null will be returned from every lookup. The map result object is converted
186 * to a string using toString().
187 * </p>
188 *
189 * @param resourceBundle the map of keys to values, may be null.
190 * @return a lookup using the map, not null.
191 * @see StringLookupFactory#resourceBundleStringLookup(String)
192 */
193 public static StrLookup<String> resourceBundleLookup(final ResourceBundle resourceBundle) {
194 return new ResourceBundleLookup(resourceBundle);
195 }
196
197 /**
198 * Returns a new lookup which uses a copy of the current {@link System#getProperties() System properties}.
199 * <p>
200 * If a security manager blocked access to system properties, then null will be returned from every lookup.
201 * </p>
202 * <p>
203 * If a null key is used, this lookup will throw a NullPointerException.
204 * </p>
205 *
206 * @return a lookup using system properties, not null.
207 */
208 public static StrLookup<String> systemPropertiesLookup() {
209 return SYSTEM_PROPERTIES_LOOKUP;
210 }
211
212 /**
213 * Constructs a new instance for subclasses.
214 */
215 protected StrLookup() {
216 }
217 }