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
18 package org.apache.commons.text.lookup;
19
20 import java.util.MissingResourceException;
21 import java.util.ResourceBundle;
22
23 /**
24 * Looks up keys from resource bundles.
25 * <p>
26 * Looks up the value for a given key in the format "BundleName:BundleKey".
27 * </p>
28 * <p>
29 * For example: "com.domain.messages:MyKey".
30 * </p>
31 * <p>
32 * Public access is through {@link StringLookupFactory}.
33 * </p>
34 *
35 * @see StringLookupFactory
36 * @see ResourceBundle
37 * @since 1.3
38 */
39 final class ResourceBundleStringLookup extends AbstractStringLookup {
40
41 /**
42 * Defines the singleton for this class.
43 */
44 static final ResourceBundleStringLookup INSTANCE = new ResourceBundleStringLookup();
45
46 /**
47 * The name of the resource bundle from which to look something up.
48 */
49 private final String bundleName;
50
51 /**
52 * Constructs a blank instance.
53 */
54 private ResourceBundleStringLookup() {
55 this(null);
56 }
57
58 /**
59 * Constructs an instance that only works for the given bundle.
60 *
61 * @param bundleName the name of the resource bundle from which we will look keys up.
62 * @since 1.5
63 */
64 ResourceBundleStringLookup(final String bundleName) {
65 this.bundleName = bundleName;
66 }
67
68 ResourceBundle getBundle(final String keyBundleName) {
69 // The ResourceBundle class caches bundles, no need to cache here.
70 return ResourceBundle.getBundle(keyBundleName);
71 }
72
73 String getString(final String keyBundleName, final String bundleKey) {
74 return getBundle(keyBundleName).getString(bundleKey);
75 }
76
77 /**
78 * Looks up the value for the key in the format "BundleName:BundleKey".
79 *
80 * For example: "com.domain.messages:MyKey".
81 *
82 * @param key the key to be looked up, may be null.
83 * @return The value associated with the key.
84 * @see ResourceBundle
85 * @see ResourceBundle#getBundle(String)
86 * @see ResourceBundle#getString(String)
87 */
88 @Override
89 public String lookup(final String key) {
90 if (key == null) {
91 return null;
92 }
93 final String[] keys = key.split(SPLIT_STR);
94 final int keyLen = keys.length;
95 final boolean anyBundle = bundleName == null;
96 if (anyBundle && keyLen != 2) {
97 throw IllegalArgumentExceptions
98 .format("Bad resource bundle key format [%s]; expected format is BundleName:KeyName.", key);
99 }
100 if (bundleName != null && keyLen != 1) {
101 throw IllegalArgumentExceptions.format("Bad resource bundle key format [%s]; expected format is KeyName.",
102 key);
103 }
104 final String keyBundleName = anyBundle ? keys[0] : bundleName;
105 final String bundleKey = anyBundle ? keys[1] : keys[0];
106 try {
107 return getString(keyBundleName, bundleKey);
108 } catch (final MissingResourceException e) {
109 // The key is missing, return null such that an interpolator can supply a default value.
110 return null;
111 } catch (final Exception e) {
112 // Should only be a ClassCastException
113 throw IllegalArgumentExceptions.format(e, "Error looking up resource bundle [%s] and key [%s].",
114 keyBundleName, bundleKey);
115 }
116 }
117
118 @Override
119 public String toString() {
120 return super.toString() + " [bundleName=" + bundleName + "]";
121 }
122
123 }