garydgregory commented on code in PR #341:
URL: https://github.com/apache/commons-text/pull/341#discussion_r930993240


##########
src/changes/changes.xml:
##########
@@ -78,6 +78,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action issue="TEXT-185" type="add" dev="ggregory" due-to="Larry West, 
Gary Gregory">Release Notes page hasn't been updated for 1.9 release 
yet.</action>
     <action                  type="add" dev="ggregory" due-to="Gary 
Gregory">Add StrBuilder.isNotEmpty().</action>
     <!-- UPDATE -->
+    <action                  type="update" dev="mattjuntunen">Make default 
string lookups configurable via system property. Remove dns, url, and script 
lookups from defaults. If these lookups are required for use in 
StringSubstitutor.createInterpolator(), they must be enabled via system 
property. See StringLookupFactory for details.</action>

Review Comment:
   Move this to the FIX section IMO



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -471,7 +483,7 @@ public void addDefaultStringLookups(final Map<String, 
StringLookup> stringLookup
      * The above examples convert {@code "SGVsbG9Xb3JsZCE="} to {@code 
"HelloWorld!"}.
      * </p>
      *
-     * @return The DateStringLookup singleton instance.
+     * @return The Base64DecoderStringLookup singleton instance.

Review Comment:
   The name "Base64DecoderStringLookup" does not exist as a class or type, what 
is it supposed to refer to? It's confusing to me because I expect such a name 
to be a class.



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -579,7 +591,7 @@ public <R, U> BiStringLookup<U> 
biFunctionStringLookup(final BiFunction<String,
      * The above examples convert {@code java.awt.event.KeyEvent.VK_ESCAPE} to 
{@code "27"}.
      * </p>
      *
-     * @return The DateStringLookup singleton instance.
+     * @return The ConstantStringLookup singleton instance.

Review Comment:
   I do not think we should use "ConstantStringLookup" because it is a 
package-private class by design and it does not help users to know the private 
name, so "foo StringLookup" would be better for all of these unless the name is 
public or protected.



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -629,17 +641,24 @@ public StringLookup dateStringLookup() {
      * 
StringLookupFactory.INSTANCE.dnsStringLookup().lookup("address|apache.org");
      * </pre>
      * <p>
-     * Using a {@link StringSubstitutor}:
+     * When used through a {@link StringSubstitutor}, this lookup must either 
be added programmatically
+     * (as below) or enabled as a default lookup using the {@value 
#DEFAULT_STRING_LOOKUPS_PROPERTY} system property
+     * (see class documentation).
      * </p>
      *
      * <pre>
-     * StringSubstitutor.createInterpolator().replace("... 
${dns:address|apache.org} ..."));
+     * Map&lt;String, StringLookup&gt; lookupMap = new HashMap&lt;&gt;();
+     * lookupMap.put("dns", StringLookupFactory.INSTANCE.dnsStringLookup());
+     *
+     * StringLookup variableResolver = 
StringLookupFactory.INSTANCE.interpolatorStringLookup(lookupMap, null, false);
+     *
+     * new StringSubstitutor(variableResolver).replace("... 
${dns:address|apache.org} ...");
      * </pre>
      * <p>
-     * The above examples convert {@code "address|apache.org"} to {@code 
"95.216.24.32} (or {@code "40.79.78.1"}).
+     * The above examples convert {@code "address|apache.org"} to the IP 
address of {@code apache.org}.
      * </p>
      *
-     * @return the DateStringLookup singleton instance.
+     * @return the DnsStringLookup singleton instance.

Review Comment:
   See above, private class.



##########
src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java:
##########
@@ -31,100 +34,125 @@
 public enum DefaultStringLookup {
 
     /**
-     * The lookup for Base64 decoding using the key {@value 
StringLookupFactory#KEY_BASE64_DECODER}.
+     * The lookup for Base64 decoding using the key {@code "base64Decoder"}.

Review Comment:
   Wrong fix here and in subsequent comments, instead, use the FQCN, for 
example, replace:
   ```
   {@value StringLookupFactory#KEY_BASE64_DECODER}
   ```
   with
   ```
   {@value 
org.apache.commons.text.lookup.StringLookupFactory#KEY_BASE64_DECODER}
   ```



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.

Review Comment:
   This is not a "getter", so the Javadoc should not be a "Gets..." comment, 
instead "to" methods convert things, so I would use "Converts..."



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -525,7 +537,7 @@ public StringLookup base64EncoderStringLookup() {
      * The above examples convert {@code "SGVsbG9Xb3JsZCE="} to {@code 
"HelloWorld!"}.
      * </p>
      *
-     * @return The DateStringLookup singleton instance.
+     * @return The Base64DecoderStringLookup singleton instance.

Review Comment:
   See above.



##########
src/main/java/org/apache/commons/text/StringSubstitutor.java:
##########
@@ -141,26 +141,28 @@
  *
  * <pre>
  * final StringSubstitutor interpolator = 
StringSubstitutor.createInterpolator();
- * interpolator.setEnableSubstitutionInVariables(true); // Allows for nested 
$'s.
- * final String text = interpolator.replace("Base64 Decoder:        
${base64Decoder:SGVsbG9Xb3JsZCE=}\n"

Review Comment:
   See my other comment below for this type of comment.



##########
src/site/xdoc/userguide.xml:
##########
@@ -181,36 +181,39 @@ limitations under the License.
     <section name="text.lookup">
       <p>Provides algorithms for looking up strings used by a 
         <a 
href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/StringSubstitutor.html";>StringSubstitutor</a>.
-        where you can select which lookup are used from 
-        <a 
href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html";>StringLookupFactory</a>.</p>
+        Standard lookups are defined in
+        <a 
href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html";>StringLookupFactory</a>
+        and the associated
+        <a 
href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/DefaultStringLookup.html";>DefaultStringLookup</a>
+        enum.
+        </p>
       <p>
-        The SS lets you build complex strings:
+        The example below demonstrates use of the default lookups for 
<code>StringSubstitutor</code> in order to
+        construct a complex string.
+      </p>
+      <p><strong>NOTE:</strong> The list of lookups available by default 
changed in version 1.10.0. See the documentation for
+        <a 
href="http://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html";>StringLookupFactory</a>
+        for details and instructions on how to reproduce the previous behavior.
       </p>
-      <code>
+      <source>
 final StringSubstitutor interpolator = StringSubstitutor.createInterpolator();
-interpolator.setEnableSubstitutionInVariables(true); // Allows for nested $'s.

Review Comment:
   The docs are worse IMO, not just here. We want more documentation now that 
we've made the behavior more complicated, not less.
   IMO the PR should do one of:
   - Add inline comment at the lines showing which examples are `// not enabled 
by default`
   - Have 2 sections, one for the "Default Configuration", the second for the 
"Full Configuration"



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -498,7 +510,7 @@ public StringLookup base64DecoderStringLookup() {
      * The above examples convert {@code } to {@code "SGVsbG9Xb3JsZCE="}.
      * </p>
      *
-     * @return The DateStringLookup singleton instance.
+     * @return The Base64EncoderStringLookup singleton instance.

Review Comment:
   See above.



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.
+     * @param key string to convert to a string lookup map key
+     * @return string lookup map key
+     */
+    static String toKey(final String key) {
+        return key.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Internal class used to construct the default {@link StringLookup} map 
used by
+     * {@link StringLookupFactory#addDefaultStringLookups(Map)}.
+     */
+    static final class DefaultStringLookupsHolder {
+
+        /** Singleton instance, initialized with the system properties. */
+        static final DefaultStringLookupsHolder INSTANCE = new 
DefaultStringLookupsHolder(System.getProperties());
+
+        /** Default string lookup map. */
+        private final Map<String, StringLookup> defaultStringLookups;
+
+        /**
+         * Construct a new instance initialized with the given properties.

Review Comment:
   Construct -> Constructs



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.
+     * @param key string to convert to a string lookup map key
+     * @return string lookup map key
+     */
+    static String toKey(final String key) {
+        return key.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Internal class used to construct the default {@link StringLookup} map 
used by
+     * {@link StringLookupFactory#addDefaultStringLookups(Map)}.
+     */
+    static final class DefaultStringLookupsHolder {
+
+        /** Singleton instance, initialized with the system properties. */
+        static final DefaultStringLookupsHolder INSTANCE = new 
DefaultStringLookupsHolder(System.getProperties());
+
+        /** Default string lookup map. */
+        private final Map<String, StringLookup> defaultStringLookups;
+
+        /**
+         * Construct a new instance initialized with the given properties.
+         * @param props initialization properties
+         */
+        DefaultStringLookupsHolder(final Properties props) {
+            final Map<String, StringLookup> lookups =
+                    
props.containsKey(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY)
+                        ? 
parseStringLookups(props.getProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY))
+                        : createDefaultStringLookups();
+
+            defaultStringLookups = Collections.unmodifiableMap(lookups);
+        }
+
+        /**
+         * Get the default string lookups map.
+         * @return default string lookups map
+         */
+        Map<String, StringLookup> getDefaultStringLookups() {
+            return defaultStringLookups;
+        }
+
+        /**
+         * Create the lookup map used when the user has requested no 
customization.
+         * @return default lookup map
+         */
+        private static Map<String, StringLookup> createDefaultStringLookups() {
+            final Map<String, StringLookup> lookupMap = new HashMap<>();
+
+            addLookup(DefaultStringLookup.BASE64_DECODER, lookupMap);
+            addLookup(DefaultStringLookup.BASE64_ENCODER, lookupMap);
+            addLookup(DefaultStringLookup.CONST, lookupMap);
+            addLookup(DefaultStringLookup.DATE, lookupMap);
+            addLookup(DefaultStringLookup.ENVIRONMENT, lookupMap);
+            addLookup(DefaultStringLookup.FILE, lookupMap);
+            addLookup(DefaultStringLookup.JAVA, lookupMap);
+            addLookup(DefaultStringLookup.LOCAL_HOST, lookupMap);
+            addLookup(DefaultStringLookup.PROPERTIES, lookupMap);
+            addLookup(DefaultStringLookup.RESOURCE_BUNDLE, lookupMap);
+            addLookup(DefaultStringLookup.SYSTEM_PROPERTIES, lookupMap);
+            addLookup(DefaultStringLookup.URL_DECODER, lookupMap);
+            addLookup(DefaultStringLookup.URL_ENCODER, lookupMap);
+            addLookup(DefaultStringLookup.XML, lookupMap);
+
+            return lookupMap;
+        }
+
+        /**
+         * Construct a lookup map by parsing the given string. The string is 
expected to contain
+         * comma or space-separated names of values from the {@link 
DefaultStringLookup} enum. If
+         * the given string is null or empty, an empty map is returned.
+         * @param str string to parse; may be null or empty
+         * @return lookup map parsed from the given string
+         */
+        private static Map<String, StringLookup> parseStringLookups(final 
String str) {
+            final Map<String, StringLookup> lookupMap = new HashMap<>();
+
+            try {
+                for (final String lookupName : str.split("[\\s,]+")) {
+                    if (!lookupName.isEmpty()) {
+                        
addLookup(DefaultStringLookup.valueOf(lookupName.toUpperCase()), lookupMap);
+                    }
+                }
+            } catch (IllegalArgumentException exc) {
+                throw new IllegalArgumentException("Invalid default string 
lookups definition: " + str, exc);
+            }
+
+            return lookupMap;
+        }
+
+        /**
+         * Add the key and string lookup from {@code lookup} to {@code map}, 
also adding any additional

Review Comment:
   Add -> Adds



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.
+     * @param key string to convert to a string lookup map key
+     * @return string lookup map key
+     */
+    static String toKey(final String key) {
+        return key.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Internal class used to construct the default {@link StringLookup} map 
used by
+     * {@link StringLookupFactory#addDefaultStringLookups(Map)}.
+     */
+    static final class DefaultStringLookupsHolder {
+
+        /** Singleton instance, initialized with the system properties. */
+        static final DefaultStringLookupsHolder INSTANCE = new 
DefaultStringLookupsHolder(System.getProperties());
+
+        /** Default string lookup map. */
+        private final Map<String, StringLookup> defaultStringLookups;
+
+        /**
+         * Construct a new instance initialized with the given properties.
+         * @param props initialization properties
+         */
+        DefaultStringLookupsHolder(final Properties props) {
+            final Map<String, StringLookup> lookups =
+                    
props.containsKey(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY)
+                        ? 
parseStringLookups(props.getProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY))
+                        : createDefaultStringLookups();
+
+            defaultStringLookups = Collections.unmodifiableMap(lookups);
+        }
+
+        /**
+         * Get the default string lookups map.

Review Comment:
   Get -> Gets



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.
+     * @param key string to convert to a string lookup map key
+     * @return string lookup map key
+     */
+    static String toKey(final String key) {
+        return key.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Internal class used to construct the default {@link StringLookup} map 
used by
+     * {@link StringLookupFactory#addDefaultStringLookups(Map)}.
+     */
+    static final class DefaultStringLookupsHolder {
+
+        /** Singleton instance, initialized with the system properties. */
+        static final DefaultStringLookupsHolder INSTANCE = new 
DefaultStringLookupsHolder(System.getProperties());
+
+        /** Default string lookup map. */
+        private final Map<String, StringLookup> defaultStringLookups;
+
+        /**
+         * Construct a new instance initialized with the given properties.
+         * @param props initialization properties
+         */
+        DefaultStringLookupsHolder(final Properties props) {
+            final Map<String, StringLookup> lookups =
+                    
props.containsKey(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY)
+                        ? 
parseStringLookups(props.getProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY))
+                        : createDefaultStringLookups();
+
+            defaultStringLookups = Collections.unmodifiableMap(lookups);
+        }
+
+        /**
+         * Get the default string lookups map.
+         * @return default string lookups map
+         */
+        Map<String, StringLookup> getDefaultStringLookups() {
+            return defaultStringLookups;
+        }
+
+        /**
+         * Create the lookup map used when the user has requested no 
customization.

Review Comment:
   Create -> Creates



##########
src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java:
##########
@@ -1171,4 +1211,109 @@ public StringLookup xmlStringLookup() {
         return XmlStringLookup.INSTANCE;
     }
 
+    /**
+     * Get a string suitable for use as a key in the string lookup map.
+     * @param key string to convert to a string lookup map key
+     * @return string lookup map key
+     */
+    static String toKey(final String key) {
+        return key.toLowerCase(Locale.ROOT);
+    }
+
+    /**
+     * Internal class used to construct the default {@link StringLookup} map 
used by
+     * {@link StringLookupFactory#addDefaultStringLookups(Map)}.
+     */
+    static final class DefaultStringLookupsHolder {
+
+        /** Singleton instance, initialized with the system properties. */
+        static final DefaultStringLookupsHolder INSTANCE = new 
DefaultStringLookupsHolder(System.getProperties());
+
+        /** Default string lookup map. */
+        private final Map<String, StringLookup> defaultStringLookups;
+
+        /**
+         * Construct a new instance initialized with the given properties.
+         * @param props initialization properties
+         */
+        DefaultStringLookupsHolder(final Properties props) {
+            final Map<String, StringLookup> lookups =
+                    
props.containsKey(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY)
+                        ? 
parseStringLookups(props.getProperty(StringLookupFactory.DEFAULT_STRING_LOOKUPS_PROPERTY))
+                        : createDefaultStringLookups();
+
+            defaultStringLookups = Collections.unmodifiableMap(lookups);
+        }
+
+        /**
+         * Get the default string lookups map.
+         * @return default string lookups map
+         */
+        Map<String, StringLookup> getDefaultStringLookups() {
+            return defaultStringLookups;
+        }
+
+        /**
+         * Create the lookup map used when the user has requested no 
customization.
+         * @return default lookup map
+         */
+        private static Map<String, StringLookup> createDefaultStringLookups() {
+            final Map<String, StringLookup> lookupMap = new HashMap<>();
+
+            addLookup(DefaultStringLookup.BASE64_DECODER, lookupMap);
+            addLookup(DefaultStringLookup.BASE64_ENCODER, lookupMap);
+            addLookup(DefaultStringLookup.CONST, lookupMap);
+            addLookup(DefaultStringLookup.DATE, lookupMap);
+            addLookup(DefaultStringLookup.ENVIRONMENT, lookupMap);
+            addLookup(DefaultStringLookup.FILE, lookupMap);
+            addLookup(DefaultStringLookup.JAVA, lookupMap);
+            addLookup(DefaultStringLookup.LOCAL_HOST, lookupMap);
+            addLookup(DefaultStringLookup.PROPERTIES, lookupMap);
+            addLookup(DefaultStringLookup.RESOURCE_BUNDLE, lookupMap);
+            addLookup(DefaultStringLookup.SYSTEM_PROPERTIES, lookupMap);
+            addLookup(DefaultStringLookup.URL_DECODER, lookupMap);
+            addLookup(DefaultStringLookup.URL_ENCODER, lookupMap);
+            addLookup(DefaultStringLookup.XML, lookupMap);
+
+            return lookupMap;
+        }
+
+        /**
+         * Construct a lookup map by parsing the given string. The string is 
expected to contain

Review Comment:
   I usually like to reserve the use of "Constructs" comments to constructors, 
this method looks like it "Parses.... and returns a Map".



##########
src/main/java/org/apache/commons/text/StringSubstitutor.java:
##########
@@ -292,9 +294,81 @@ public String toString() {
      *
      * <pre>
      * StringSubstitutor.createInterpolator().replace(
-     *   "OS name: ${sys:os.name}, " + "3 + 4 = ${script:javascript:3 + 4}");
+     *   "OS name: ${sys:os.name}, user: ${env:USER}");
      * </pre>
      *
+     * <p>The table below lists the lookups available by default in the 
returned instance. These
+     * may be modified through the use of the {@value 
StringLookupFactory#DEFAULT_STRING_LOOKUPS_PROPERTY}
+     * system property, as described in the {@link StringLookupFactory} 
documentation.</p>
+     *
+     * <p><strong>NOTE:</strong> The list of lookups available by default 
changed in version {@code 1.10.0}.
+     * Configuration via system property (as mentioned above) may be necessary 
to reproduce previous functionality.

Review Comment:
   "may be"? You MUST do something if you want the previous behavior. I would 
be more explicit and list the lookups removed from the default here (DNS, ...)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to