You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/08/04 15:26:57 UTC

[commons-text] branch master updated: [TEXT-170] Add String lookup for host names and IP addresses (#118)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-text.git


The following commit(s) were added to refs/heads/master by this push:
     new d81879e  [TEXT-170] Add String lookup for host names and IP addresses (#118)
d81879e is described below

commit d81879e0e705a6df5a9cd45563ce9a59804e5580
Author: Gary Gregory <ga...@users.noreply.github.com>
AuthorDate: Sun Aug 4 11:26:52 2019 -0400

    [TEXT-170] Add String lookup for host names and IP addresses (#118)
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    Do not use hardcoded IP addresses.
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    Do not use hardcoded IP addresses.
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    Fix Checkstyle issues.
    
    * Fix version number in Javadoc.
    
    * Update Javadoc per PR review.
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    Update test per PR review.
    
    * [TEXT-170] Add String lookup for host names and IP addresses
    (DnsStringLookup).
    
    Update test per PR review.
---
 src/changes/changes.xml                            |  1 +
 .../commons/text/lookup/DefaultStringLookup.java   |  7 ++
 .../commons/text/lookup/DnsStringLookup.java       | 85 ++++++++++++++++++++++
 .../commons/text/lookup/InetAddressKeys.java       | 44 +++++++++++
 .../commons/text/lookup/LocalHostStringLookup.java |  6 +-
 .../commons/text/lookup/StringLookupFactory.java   | 28 +++++++
 ...ubstitutorWithInterpolatorStringLookupTest.java | 53 +++++++++++++-
 .../text/lookup/DefaultStringLookupTest.java       |  1 +
 .../commons/text/lookup/DnsStringLookupTest.java   | 71 ++++++++++++++++++
 .../text/lookup/StringLookupFactoryTest.java       |  2 +
 10 files changed, 292 insertions(+), 6 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index b66bb0a..b0b2a60 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -49,6 +49,7 @@ The <action> type attribute can be add,update,fix,remove.
     <action issue="TEXT-167" type="fix" dev="ggregory" due-to="Larry West">commons-text web page missing "RELEASE-NOTES-1.7.txt"</action>
     <action issue="TEXT-168" type="fix" dev="ggregory" due-to="luksan47">(doc) Fixed wrong value for Jaro-Winkler example #117</action>
     <action issue="TEXT-169" type="add" dev="ggregory" due-to="Gary Gregory">Add helper factory method org.apache.commons.text.StringSubstitutor.createInterpolator().</action>
+    <action issue="TEXT-170" type="add" dev="ggregory" due-to="Gary Gregory">Add String lookup for host names and IP addresses (DnsStringLookup).</action>
   </release>
   
   <release version="1.7" date="2019-06-30" description="Release 1.7">
diff --git a/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java b/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java
index ba57578..c9632fa 100644
--- a/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java
+++ b/src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java
@@ -49,6 +49,13 @@ public enum DefaultStringLookup {
     DATE(StringLookupFactory.KEY_DATE, StringLookupFactory.INSTANCE.dateStringLookup()),
 
     /**
+     * The lookup for DNS.
+     *
+     * @since 1.8
+     */
+    DNS(StringLookupFactory.KEY_DNS, StringLookupFactory.INSTANCE.dnsStringLookup()),
+
+    /**
      * The lookup for environment properties.
      */
     ENVIRONMENT(StringLookupFactory.KEY_ENV, StringLookupFactory.INSTANCE.environmentVariableStringLookup()),
diff --git a/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java b/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java
new file mode 100644
index 0000000..ba89418
--- /dev/null
+++ b/src/main/java/org/apache/commons/text/lookup/DnsStringLookup.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.commons.text.lookup;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Looks up keys related to DNS entries like host name, canonical host name, host address.
+ * <p>
+ * The lookup keys are:
+ * </p>
+ * <ul>
+ * <li><b>name|<em>address</em></b>: for the host name, for example {@code "name|93.184.216.34"} ->
+ * {@code "example.com"}.</li>
+ * <li><b>canonical-name|<em>address</em></b>: for the canonical host name, for example {@code "name|93.184.216.34"} ->
+ * {@code "example.com"}.</li>
+ * <li><b>address|<em>hostname</em></b>: for the host address, for example {@code "address|example.com"} ->
+ * {@code "93.184.216.34"}.</li>
+ * <li><b><em>address</em></b>: same as {@code address|hostname}.</li>
+ * </ul>
+ *
+ * @since 1.8
+ */
+final class DnsStringLookup extends AbstractStringLookup {
+
+    /**
+     * Defines the singleton for this class.
+     */
+    static final DnsStringLookup INSTANCE = new DnsStringLookup();
+
+    /**
+     * No need to build instances for now.
+     */
+    private DnsStringLookup() {
+        // empty
+    }
+
+    /**
+     * Looks up the DNS value of the key.
+     *
+     * @param key the key to be looked up, may be null
+     * @return The DNS value.
+     */
+    @Override
+    public String lookup(final String key) {
+        if (key == null) {
+            return null;
+        }
+        final String[] keys = key.trim().split("\\|");
+        final int keyLen = keys.length;
+        final String subKey = keys[0].trim();
+        final String subValue = keyLen < 2 ? key : keys[1].trim();
+        try {
+            final InetAddress inetAddress = InetAddress.getByName(subValue);
+            switch (subKey) {
+            case InetAddressKeys.KEY_NAME:
+                return inetAddress.getHostName();
+            case InetAddressKeys.KEY_CANONICAL_NAME:
+                return inetAddress.getCanonicalHostName();
+            case InetAddressKeys.KEY_ADDRESS:
+                return inetAddress.getHostAddress();
+            default:
+                return inetAddress.getHostAddress();
+            }
+        } catch (final UnknownHostException e) {
+            return null;
+        }
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java b/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java
new file mode 100644
index 0000000..2465614
--- /dev/null
+++ b/src/main/java/org/apache/commons/text/lookup/InetAddressKeys.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.commons.text.lookup;
+
+import java.net.InetAddress;
+
+/**
+ * Constants for referring to {@link InetAddress} APIs.
+ *
+ * @since 1.8
+ */
+class InetAddressKeys {
+
+    /**
+     * Constants for referring to {@link InetAddress#getAddress()}.
+     */
+    static final String KEY_ADDRESS = "address";
+
+    /**
+     * Constants for referring to {@link InetAddress#getCanonicalAddress()}.
+     */
+    static final String KEY_CANONICAL_NAME = "canonical-name";
+
+    /**
+     * Constants for referring to {@link InetAddress#getName()}.
+     */
+    static final String KEY_NAME = "name";
+
+}
diff --git a/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java b/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java
index 9f4ee34..8bdc24d 100644
--- a/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java
+++ b/src/main/java/org/apache/commons/text/lookup/LocalHostStringLookup.java
@@ -59,11 +59,11 @@ final class LocalHostStringLookup extends AbstractStringLookup {
         }
         try {
             switch (key) {
-            case "name":
+            case InetAddressKeys.KEY_NAME:
                 return InetAddress.getLocalHost().getHostName();
-            case "canonical-name":
+            case InetAddressKeys.KEY_CANONICAL_NAME:
                 return InetAddress.getLocalHost().getCanonicalHostName();
-            case "address":
+            case InetAddressKeys.KEY_ADDRESS:
                 return InetAddress.getLocalHost().getHostAddress();
             default:
                 throw new IllegalArgumentException(key);
diff --git a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
index da61c6f..8fbf9b4 100644
--- a/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
+++ b/src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java
@@ -57,6 +57,12 @@ import java.util.Map;
  * <td>1.5</td>
  * </tr>
  * <tr>
+ * <td>{@value #KEY_DNS}</td>
+ * <td>{@link DnsStringLookup}</td>
+ * <td>{@link #dnsStringLookup()}</td>
+ * <td>1.8</td>
+ * </tr>
+ * <tr>
  * <td>{@value #KEY_ENV}</td>
  * <td>{@link EnvironmentVariableStringLookup}</td>
  * <td>{@link #environmentVariableStringLookup()}</td>
@@ -170,6 +176,13 @@ public final class StringLookupFactory {
     /**
      * Default lookup key for interpolation.
      *
+     * @since 1.8
+     */
+    public static final String KEY_DNS = "dns";
+
+    /**
+     * Default lookup key for interpolation.
+     *
      * @since 1.6
      */
     public static final String KEY_ENV = "env";
@@ -455,6 +468,21 @@ public final class StringLookupFactory {
     }
 
     /**
+     * Returns the DnsStringLookup singleton instance where the lookup key is one of:
+     * <ul>
+     * <li><b>name</b>: for the local host name, for example {@code EXAMPLE} but also {@code EXAMPLE.apache.org}.</li>
+     * <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li>
+     * <li><b>address</b>: for the local host address, for example {@code 192.168.56.1}.</li>
+     * </ul>
+     *
+     * @return the DateStringLookup singleton instance.
+     * @since 1.8
+     */
+    public StringLookup dnsStringLookup() {
+        return DnsStringLookup.INSTANCE;
+    }
+
+    /**
      * Returns a new map-based lookup where the request for a lookup is answered with the value for that key.
      *
      * @param <V>
diff --git a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
index e70e953..ed4dc03 100644
--- a/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
+++ b/src/test/java/org/apache/commons/text/StringSubstitutorWithInterpolatorStringLookupTest.java
@@ -45,7 +45,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest {
         final Map<String, StringLookup> stringLookupMap = new HashMap<>();
         stringLookupMap.put("customLookup", mapStringLookup);
         final StringSubstitutor strSubst = new StringSubstitutor(
-                StringLookupFactory.INSTANCE.interpolatorStringLookup(stringLookupMap, null, addDefaultLookups));
+            StringLookupFactory.INSTANCE.interpolatorStringLookup(stringLookupMap, null, addDefaultLookups));
         if (addDefaultLookups) {
             final String spKey = "user.name";
             Assertions.assertEquals(System.getProperty(spKey), strSubst.replace("${sys:" + spKey + "}"));
@@ -69,6 +69,53 @@ public class StringSubstitutorWithInterpolatorStringLookupTest {
     }
 
     @Test
+    public void testDnsLookup() throws UnknownHostException {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        final String hostName = InetAddress.getLocalHost().getHostName();
+        Assertions.assertEquals(InetAddress.getByName(hostName).getHostAddress(),
+            strSubst.replace("${dns:" + hostName + "}"));
+    }
+
+    @Test
+    public void testDnsLookupAddress() throws UnknownHostException {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        Assertions.assertEquals(InetAddress.getByName("apache.org").getHostAddress(),
+            strSubst.replace("${dns:address|apache.org}"));
+    }
+
+    @Test
+    public void testDnsLookupCanonicalName() throws UnknownHostException {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        final String address = InetAddress.getLocalHost().getHostAddress();
+        final InetAddress inetAddress = InetAddress.getByName(address);
+        Assertions.assertEquals(inetAddress.getCanonicalHostName(),
+            strSubst.replace("${dns:canonical-name|" + address + "}"));
+    }
+
+    @Test
+    public void testDnsLookupName() throws UnknownHostException {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        final String address = InetAddress.getLocalHost().getHostAddress();
+        final InetAddress inetAddress = InetAddress.getByName(address);
+        Assertions.assertEquals(inetAddress.getHostName(), strSubst.replace("${dns:name|" + address + "}"));
+    }
+
+    @Test
+    public void testDnsLookupNameUntrimmed() throws UnknownHostException {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        final String address = InetAddress.getLocalHost().getHostAddress();
+        final InetAddress inetAddress = InetAddress.getByName(address);
+        Assertions.assertEquals(inetAddress.getHostName(), strSubst.replace("${dns:name| " + address + " }"));
+    }
+
+    @Test
+    public void testDnsLookupUnknown() {
+        final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
+        final String unknown = "${dns: u n k n o w n}";
+        Assertions.assertEquals(unknown, strSubst.replace(unknown));
+    }
+
+    @Test
     public void testLocalHostLookup_Address() throws UnknownHostException {
         final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
         Assertions.assertEquals(InetAddress.getLocalHost().getHostAddress(), strSubst.replace("${localhost:address}"));
@@ -78,7 +125,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest {
     public void testLocalHostLookup_CanonicalName() throws UnknownHostException {
         final StringSubstitutor strSubst = StringSubstitutor.createInterpolator();
         Assertions.assertEquals(InetAddress.getLocalHost().getCanonicalHostName(),
-                strSubst.replace("${localhost:canonical-name}"));
+            strSubst.replace("${localhost:canonical-name}"));
     }
 
     @Test
@@ -94,7 +141,7 @@ public class StringSubstitutorWithInterpolatorStringLookupTest {
         final Map<String, String> map = new HashMap<>();
         map.put(key, value);
         final StringSubstitutor strSubst = new StringSubstitutor(
-                StringLookupFactory.INSTANCE.interpolatorStringLookup(map));
+            StringLookupFactory.INSTANCE.interpolatorStringLookup(map));
         final String spKey = "user.name";
         Assertions.assertEquals(System.getProperty(spKey), strSubst.replace("${sys:" + spKey + "}"));
         Assertions.assertEquals(value, strSubst.replace("${" + key + "}"));
diff --git a/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java
index 2302dd3..0fa967a 100644
--- a/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java
+++ b/src/test/java/org/apache/commons/text/lookup/DefaultStringLookupTest.java
@@ -46,6 +46,7 @@ public class DefaultStringLookupTest {
                 StringLookupFactory.INSTANCE.base64EncoderStringLookup());
         assertSame(DefaultStringLookup.CONST.getStringLookup(), StringLookupFactory.INSTANCE.constantStringLookup());
         assertSame(DefaultStringLookup.DATE.getStringLookup(), StringLookupFactory.INSTANCE.dateStringLookup());
+        assertSame(DefaultStringLookup.DNS.getStringLookup(), StringLookupFactory.INSTANCE.dnsStringLookup());
         assertSame(DefaultStringLookup.ENVIRONMENT.getStringLookup(),
                 StringLookupFactory.INSTANCE.environmentVariableStringLookup());
         assertSame(DefaultStringLookup.FILE.getStringLookup(), StringLookupFactory.INSTANCE.fileStringLookup());
diff --git a/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java b/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java
new file mode 100644
index 0000000..fed3797
--- /dev/null
+++ b/src/test/java/org/apache/commons/text/lookup/DnsStringLookupTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.commons.text.lookup;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link DnsStringLookup}.
+ */
+public class DnsStringLookupTest {
+
+    @Test
+    public void testAddressFromHostAddress() throws UnknownHostException {
+        final InetAddress localHost = InetAddress.getLocalHost();
+        Assertions.assertEquals(localHost.getHostAddress(),
+            DnsStringLookup.INSTANCE.lookup("address|" + localHost.getHostAddress()));
+    }
+
+    @Test
+    public void testAddressFromHostName() throws UnknownHostException {
+        final InetAddress localHost = InetAddress.getLocalHost();
+        Assertions.assertEquals(localHost.getHostAddress(),
+            DnsStringLookup.INSTANCE.lookup("address|" + localHost.getHostName()));
+    }
+
+    @Test
+    public void testCanonicalNameFromHostAddress() throws UnknownHostException {
+        final InetAddress localHost = InetAddress.getLocalHost();
+        Assertions.assertEquals(localHost.getCanonicalHostName(),
+            DnsStringLookup.INSTANCE.lookup("canonical-name|" + localHost.getHostAddress()));
+    }
+
+    @Test
+    public void testCanonicalNameFromHostName() throws UnknownHostException {
+        final InetAddress localHost = InetAddress.getLocalHost();
+        Assertions.assertEquals(localHost.getCanonicalHostName(),
+            DnsStringLookup.INSTANCE.lookup("canonical-name|" + localHost.getHostName()));
+    }
+
+    @Test
+    public void testName() throws UnknownHostException {
+        final String address = InetAddress.getLocalHost().getHostAddress();
+        final InetAddress localHost = InetAddress.getByName(address);
+        Assertions.assertEquals(localHost.getHostName(), DnsStringLookup.INSTANCE.lookup("name|" + address + ""));
+    }
+
+    @Test
+    public void testNull() {
+        Assertions.assertNull(DnsStringLookup.INSTANCE.lookup(null));
+    }
+
+}
diff --git a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
index 46893fd..e7731e7 100644
--- a/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
+++ b/src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java
@@ -34,6 +34,7 @@ public class StringLookupFactoryTest {
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_BASE64_ENCODER));
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_CONST));
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DATE));
+        assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_DNS));
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_ENV));
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_FILE));
         assertTrue(stringLookupMap.containsKey(StringLookupFactory.KEY_JAVA));
@@ -70,6 +71,7 @@ public class StringLookupFactoryTest {
         Assertions.assertSame(Base64EncoderStringLookup.INSTANCE, stringLookupFactory.base64EncoderStringLookup());
         Assertions.assertSame(ConstantStringLookup.INSTANCE, stringLookupFactory.constantStringLookup());
         Assertions.assertSame(DateStringLookup.INSTANCE, stringLookupFactory.dateStringLookup());
+        Assertions.assertSame(DnsStringLookup.INSTANCE, stringLookupFactory.dnsStringLookup());
         Assertions.assertSame(EnvironmentVariableStringLookup.INSTANCE,
                 stringLookupFactory.environmentVariableStringLookup());
         Assertions.assertSame(InterpolatorStringLookup.INSTANCE, stringLookupFactory.interpolatorStringLookup());