Skip to content

Commit 5597e21

Browse files
committed
Add support for a new StringLookup key "loopbackAddress", similar to
"localhost"
1 parent 486d650 commit 5597e21

File tree

10 files changed

+172
-28
lines changed

10 files changed

+172
-28
lines changed

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<version>75</version>
2424
</parent>
2525
<artifactId>commons-text</artifactId>
26-
<version>1.12.1-SNAPSHOT</version>
26+
<version>1.13.0-SNAPSHOT</version>
2727
<name>Apache Commons Text</name>
2828
<description>Apache Commons Text is a set of utility functions and reusable components for the purpose of processing
2929
and manipulating text that should be of use in a Java environment.
@@ -41,8 +41,8 @@
4141
<commons.packageId>text</commons.packageId>
4242
<commons.module.name>org.apache.commons.text</commons.module.name>
4343

44-
<commons.release.version>1.12.0</commons.release.version>
45-
<commons.release.next>1.12.1</commons.release.next>
44+
<commons.release.version>1.13.0</commons.release.version>
45+
<commons.release.next>1.13.1</commons.release.next>
4646
<commons.release.desc>(Java 8+)</commons.release.desc>
4747

4848
<commons.jira.id>TEXT</commons.jira.id>
@@ -59,7 +59,7 @@
5959

6060
<!-- Commons Release Plugin -->
6161
<!-- Previous version of the component (used for reporting binary compatibility check)-->
62-
<commons.bc.version>1.11.0</commons.bc.version>
62+
<commons.bc.version>1.12.0</commons.bc.version>
6363
<commons.rc.version>RC1</commons.rc.version>
6464
<commons.release.isDistModule>true</commons.release.isDistModule>
6565
<commons.distSvnStagingUrl>scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid}</commons.distSvnStagingUrl>

src/changes/changes.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ The <action> type attribute can be add,update,fix,remove.
4545
<title>Apache Commons Text Changes</title>
4646
</properties>
4747
<body>
48-
<release version="1.12.1" date="YYYY-MM-DD" description="Release 1.12.1. Requires Java 8 or above.">
48+
<release version="1.13.0" date="YYYY-MM-DD" description="Release 1.13.0. Requires Java 8 or above.">
49+
<!-- ADD -->
50+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StringLookupFactory.loopbackAddressStringLookup().</action>
51+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add StringLookupFactory.KEY_LOOPBACK_ADDRESS.</action>
52+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add DefaultStringLookup.LOOPBACK_ADDRESS.</action>
4953
<!-- FIX -->
5054
<action type="fix" dev="ggregory" due-to="Gary Gregory">Fix build on Java 22.</action>
5155
<action type="fix" dev="ggregory" due-to="Gary Gregory">Fix build on Java 23-ea.</action>

src/main/java/org/apache/commons/text/StringSubstitutor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ public String toString() {
345345
* <td>{@link StringLookupFactory#localHostStringLookup()}</td>
346346
* </tr>
347347
* <tr>
348+
* <td>{@value org.apache.commons.text.lookup.StringLookupFactory#KEY_LOOPBACK_ADDRESS}</td>
349+
* <td>{@link StringLookupFactory#loopbackAddressStringLookup()}</td>
350+
* </tr>
351+
* <tr>
348352
* <td>{@value org.apache.commons.text.lookup.StringLookupFactory#KEY_PROPERTIES}</td>
349353
* <td>{@link StringLookupFactory#propertiesStringLookup()}</td>
350354
* </tr>

src/main/java/org/apache/commons/text/lookup/DefaultStringLookup.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ public enum DefaultStringLookup {
106106
*/
107107
LOCAL_HOST(StringLookupFactory.KEY_LOCALHOST, StringLookupFactory.INSTANCE.localHostStringLookup()),
108108

109+
/**
110+
* The lookup for local host information using the key {@code "loopbackAddress"}.
111+
*
112+
* @see StringLookupFactory#KEY_LOOPBACK_ADDRESS
113+
* @see StringLookupFactory#loopbackAddressStringLookup()
114+
*/
115+
LOOPBACK_ADDRESS(StringLookupFactory.KEY_LOOPBACK_ADDRESS, StringLookupFactory.INSTANCE.loopbackAddressStringLookup()),
116+
109117
/**
110118
* The lookup for properties using the key {@code "properties"}.
111119
*

src/main/java/org/apache/commons/text/lookup/InetAddressStringLookup.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
import java.net.InetAddress;
2020
import java.net.UnknownHostException;
21+
import java.util.Objects;
22+
23+
import org.apache.commons.lang3.function.FailableSupplier;
2124

2225
/**
2326
* Looks up keys related to an {@link InetAddresse}.
@@ -38,15 +41,30 @@
3841
final class InetAddressStringLookup extends AbstractStringLookup {
3942

4043
/**
41-
* Defines the singleton for this class.
44+
* Defines the LOCAL_HOST constant.
4245
*/
43-
static final InetAddressStringLookup INSTANCE = new InetAddressStringLookup();
46+
static final InetAddressStringLookup LOCAL_HOST = new InetAddressStringLookup(InetAddress::getLocalHost);
47+
48+
/**
49+
* Defines the LOCAL_HOST constant.
50+
*/
51+
static final InetAddressStringLookup LOOPACK_ADDRESS = new InetAddressStringLookup(InetAddress::getLoopbackAddress);
52+
53+
/**
54+
* Supplies the InetAddress.
55+
*/
56+
private final FailableSupplier<InetAddress, UnknownHostException> inetAddressSupplier;
4457

4558
/**
4659
* No need to build instances for now.
4760
*/
48-
private InetAddressStringLookup() {
49-
// empty
61+
private InetAddressStringLookup(final FailableSupplier<InetAddress, UnknownHostException> inetAddressSupplier) {
62+
this.inetAddressSupplier = Objects.requireNonNull(inetAddressSupplier, "inetAddressSupplier");
63+
}
64+
65+
private InetAddress getInetAddress() throws UnknownHostException {
66+
// Don't cache result, methods, like InetAddress::getLocalHost do their own cacheing.
67+
return inetAddressSupplier.get();
5068
}
5169

5270
/**
@@ -63,11 +81,11 @@ public String lookup(final String key) {
6381
try {
6482
switch (key) {
6583
case InetAddressKeys.KEY_NAME:
66-
return InetAddress.getLocalHost().getHostName();
84+
return getInetAddress().getHostName();
6785
case InetAddressKeys.KEY_CANONICAL_NAME:
68-
return InetAddress.getLocalHost().getCanonicalHostName();
86+
return getInetAddress().getCanonicalHostName();
6987
case InetAddressKeys.KEY_ADDRESS:
70-
return InetAddress.getLocalHost().getHostAddress();
88+
return getInetAddress().getHostAddress();
7189
default:
7290
throw new IllegalArgumentException(key);
7391
}

src/main/java/org/apache/commons/text/lookup/StringLookupFactory.java

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.commons.text.lookup;
1919

20+
import java.net.InetAddress;
2021
import java.nio.charset.StandardCharsets;
2122
import java.nio.file.Path;
2223
import java.util.Base64;
@@ -115,6 +116,12 @@
115116
* <td>1.3</td>
116117
* </tr>
117118
* <tr>
119+
* <td>{@value #KEY_LOOPBACK_ADDRESS}</td>
120+
* <td>{@link StringLookup}</td>
121+
* <td>{@link #loopbackAddressStringLookup()}</td>
122+
* <td>1.13.0</td>
123+
* </tr>
124+
* <tr>
118125
* <td>{@value #KEY_PROPERTIES}</td>
119126
* <td>{@link StringLookup}</td>
120127
* <td>{@link #propertiesStringLookup(Path...)}</td>
@@ -289,6 +296,7 @@ private static Map<String, StringLookup> createDefaultStringLookups() {
289296
addLookup(DefaultStringLookup.FILE, lookupMap);
290297
addLookup(DefaultStringLookup.JAVA, lookupMap);
291298
addLookup(DefaultStringLookup.LOCAL_HOST, lookupMap);
299+
addLookup(DefaultStringLookup.LOCAL_HOST, lookupMap);
292300
addLookup(DefaultStringLookup.PROPERTIES, lookupMap);
293301
addLookup(DefaultStringLookup.RESOURCE_BUNDLE, lookupMap);
294302
addLookup(DefaultStringLookup.SYSTEM_PROPERTIES, lookupMap);
@@ -502,6 +510,13 @@ Map<String, StringLookup> getDefaultStringLookups() {
502510
*/
503511
public static final String KEY_LOCALHOST = "localhost";
504512

513+
/**
514+
* Default lookup key for interpolation {@value #KEY_LOOPBACK_ADDRESS}.
515+
*
516+
* @since 1.13.0
517+
*/
518+
public static final String KEY_LOOPBACK_ADDRESS = "loobackAddress";
519+
505520
/**
506521
* Default lookup key for interpolation {@value #KEY_PROPERTIES}.
507522
*
@@ -1084,7 +1099,7 @@ public StringLookup javaPlatformStringLookup() {
10841099
}
10851100

10861101
/**
1087-
* Returns the LocalHostStringLookup singleton instance where the lookup key is one of:
1102+
* Returns the InetAddressStringLookup instance where the lookup key for {@link InetAddress#getLocalHost()} is one of:
10881103
* <ul>
10891104
* <li><b>name</b>: for the local host name, for example {@code EXAMPLE}.</li>
10901105
* <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li>
@@ -1109,10 +1124,42 @@ public StringLookup javaPlatformStringLookup() {
11091124
* The above examples convert {@code "canonical-name"} to the current host name, for example, {@code "EXAMPLE.apache.org"}.
11101125
* </p>
11111126
*
1112-
* @return The DateStringLookup singleton instance.
1127+
* @return The InetAddressStringLookup singleton instance.
11131128
*/
11141129
public StringLookup localHostStringLookup() {
1115-
return InetAddressStringLookup.INSTANCE;
1130+
return InetAddressStringLookup.LOCAL_HOST;
1131+
}
1132+
1133+
/**
1134+
* Returns the InetAddressStringLookup instance where the lookup key for {@link InetAddress#getLoopbackAddress()} is one of:
1135+
* <ul>
1136+
* <li><b>name</b>: for the local host name, for example {@code EXAMPLE}.</li>
1137+
* <li><b>canonical-name</b>: for the local canonical host name, for example {@code EXAMPLE.apache.org}.</li>
1138+
* <li><b>address</b>: for the local host address, for example {@code 192.168.56.1}.</li>
1139+
* </ul>
1140+
*
1141+
* <p>
1142+
* Using a {@link StringLookup} from the {@link StringLookupFactory}:
1143+
* </p>
1144+
*
1145+
* <pre>
1146+
* StringLookupFactory.INSTANCE.loopbackAddressStringLookup().lookup("canonical-name");
1147+
* </pre>
1148+
* <p>
1149+
* Using a {@link StringSubstitutor}:
1150+
* </p>
1151+
*
1152+
* <pre>
1153+
* StringSubstitutor.createInterpolator().replace("... ${loopbackAddress:canonical-name} ..."));
1154+
* </pre>
1155+
* <p>
1156+
* The above examples convert {@code "canonical-name"} to the current host name, for example, {@code "EXAMPLE.apache.org"}.
1157+
* </p>
1158+
*
1159+
* @return The InetAddressStringLookup singleton instance.
1160+
*/
1161+
public StringLookup loopbackAddressStringLookup() {
1162+
return InetAddressStringLookup.LOOPACK_ADDRESS;
11161163
}
11171164

11181165
/**

src/site/xdoc/userguide.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ final String text = interpolator.replace(
205205
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#environmentVariableStringLookup()">Environment Variable</a>: ${env:USERNAME}\n" +
206206
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#fileStringLookup(java.nio.file.Path...)()">File Content</a>: ${file:UTF-8:src/test/resources/document.properties}\n" +
207207
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#javaPlatformStringLookup()">Java</a>: ${java:version}\n" +
208-
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#localHostStringLookup()">Localhost</a>: ${localhost:canonical-name}\n" +
208+
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#localHostStringLookup()">Local host</a>: ${localhost:canonical-name}\n" +
209+
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#localHostStringLookup()">Loopback address</a>: ${loopbackAddress:canonical-name}\n" +
209210
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#propertiesStringLookup(java.nio.file.Path...)()">Properties File</a>: ${properties:src/test/resources/document.properties::mykey}\n" +
210211
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#resourceBundleStringLookup(java.lang.String)()">Resource Bundle</a>: ${resourceBundle:org.apache.commons.text.example.testResourceBundleLookup:mykey}\n" +
211212
"<a href="https://commons.apache.org/proper/commons-text/apidocs/org/apache/commons/text/lookup/StringLookupFactory.html#systemPropertyStringLookup()">System Property</a>: ${sys:user.dir}\n" +

src/test/java/org/apache/commons/text/lookup/LocalHostStringLookupTest.java renamed to src/test/java/org/apache/commons/text/lookup/InetAddressStringLookupLocalHostTest.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,42 +24,39 @@
2424
import org.junit.jupiter.api.Test;
2525

2626
/**
27-
* Tests {@link InetAddressStringLookup}.
27+
* Tests {@link InetAddressStringLookup#LOCAL_HOST}.
2828
*/
29-
public class LocalHostStringLookupTest {
29+
public class InetAddressStringLookupLocalHostTest {
3030

3131
@Test
3232
public void testAddress() throws UnknownHostException {
33-
Assertions.assertEquals(InetAddress.getLocalHost().getHostAddress(),
34-
InetAddressStringLookup.INSTANCE.lookup("address"));
33+
Assertions.assertEquals(InetAddress.getLocalHost().getHostAddress(), InetAddressStringLookup.LOCAL_HOST.lookup("address"));
3534
}
3635

3736
@Test
3837
public void testBadKey() {
39-
Assertions.assertThrows(IllegalArgumentException.class, () -> InetAddressStringLookup.INSTANCE.lookup("FOO"));
38+
Assertions.assertThrows(IllegalArgumentException.class, () -> InetAddressStringLookup.LOCAL_HOST.lookup("FOO"));
4039
}
4140

4241
@Test
4342
public void testCanonicalName() throws UnknownHostException {
44-
Assertions.assertEquals(InetAddress.getLocalHost().getCanonicalHostName(),
45-
InetAddressStringLookup.INSTANCE.lookup("canonical-name"));
43+
Assertions.assertEquals(InetAddress.getLocalHost().getCanonicalHostName(), InetAddressStringLookup.LOCAL_HOST.lookup("canonical-name"));
4644
}
4745

4846
@Test
4947
public void testName() throws UnknownHostException {
50-
Assertions.assertEquals(InetAddress.getLocalHost().getHostName(),
51-
InetAddressStringLookup.INSTANCE.lookup("name"));
48+
Assertions.assertEquals(InetAddress.getLocalHost().getHostName(), InetAddressStringLookup.LOCAL_HOST.lookup("name"));
5249
}
5350

5451
@Test
5552
public void testNull() {
56-
Assertions.assertNull(InetAddressStringLookup.INSTANCE.lookup(null));
53+
Assertions.assertNull(InetAddressStringLookup.LOCAL_HOST.lookup(null));
5754
}
5855

5956
@Test
6057
public void testToString() {
6158
// does not blow up and gives some kind of string.
62-
Assertions.assertFalse(InetAddressStringLookup.INSTANCE.toString().isEmpty());
59+
Assertions.assertFalse(InetAddressStringLookup.LOCAL_HOST.toString().isEmpty());
6360
}
6461

6562
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
18+
package org.apache.commons.text.lookup;
19+
20+
import java.net.InetAddress;
21+
22+
import org.junit.jupiter.api.Assertions;
23+
import org.junit.jupiter.api.Test;
24+
25+
/**
26+
* Tests {@link InetAddressStringLookup#LOOPACK_ADDRESS}.
27+
*/
28+
public class InetAddressStringLookupLoopbackAddressTest {
29+
30+
@Test
31+
public void testAddress() {
32+
Assertions.assertEquals(InetAddress.getLoopbackAddress().getHostAddress(), InetAddressStringLookup.LOOPACK_ADDRESS.lookup("address"));
33+
}
34+
35+
@Test
36+
public void testBadKey() {
37+
Assertions.assertThrows(IllegalArgumentException.class, () -> InetAddressStringLookup.LOOPACK_ADDRESS.lookup("FOO"));
38+
}
39+
40+
@Test
41+
public void testCanonicalName() {
42+
Assertions.assertEquals(InetAddress.getLoopbackAddress().getCanonicalHostName(), InetAddressStringLookup.LOOPACK_ADDRESS.lookup("canonical-name"));
43+
}
44+
45+
@Test
46+
public void testName() {
47+
Assertions.assertEquals(InetAddress.getLoopbackAddress().getHostName(), InetAddressStringLookup.LOOPACK_ADDRESS.lookup("name"));
48+
}
49+
50+
@Test
51+
public void testNull() {
52+
Assertions.assertNull(InetAddressStringLookup.LOOPACK_ADDRESS.lookup(null));
53+
}
54+
55+
@Test
56+
public void testToString() {
57+
// does not blow up and gives some kind of string.
58+
Assertions.assertFalse(InetAddressStringLookup.LOOPACK_ADDRESS.toString().isEmpty());
59+
}
60+
61+
}

src/test/java/org/apache/commons/text/lookup/StringLookupFactoryTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public static void assertDefaultKeys(final Map<String, StringLookup> stringLooku
4444
StringLookupFactory.KEY_FILE,
4545
StringLookupFactory.KEY_JAVA,
4646
StringLookupFactory.KEY_LOCALHOST,
47+
StringLookupFactory.KEY_LOOPBACK_ADDRESS,
4748
StringLookupFactory.KEY_PROPERTIES,
4849
StringLookupFactory.KEY_RESOURCE_BUNDLE,
4950
StringLookupFactory.KEY_SYS,
@@ -120,6 +121,7 @@ public void testDefaultStringLookupsHolder_allLookups() {
120121
StringLookupFactory.KEY_FILE,
121122
StringLookupFactory.KEY_JAVA,
122123
StringLookupFactory.KEY_LOCALHOST,
124+
StringLookupFactory.KEY_LOOPBACK_ADDRESS,
123125
StringLookupFactory.KEY_PROPERTIES,
124126
StringLookupFactory.KEY_RESOURCE_BUNDLE,
125127
StringLookupFactory.KEY_SYS,
@@ -185,6 +187,7 @@ public void testDefaultStringLookupsHolder_lookupsPropertyNotPresent() {
185187
StringLookupFactory.KEY_FILE,
186188
StringLookupFactory.KEY_JAVA,
187189
StringLookupFactory.KEY_LOCALHOST,
190+
StringLookupFactory.KEY_LOOPBACK_ADDRESS,
188191
StringLookupFactory.KEY_PROPERTIES,
189192
StringLookupFactory.KEY_RESOURCE_BUNDLE,
190193
StringLookupFactory.KEY_SYS,
@@ -223,7 +226,8 @@ public void testSingletons() {
223226
stringLookupFactory.environmentVariableStringLookup());
224227
Assertions.assertSame(InterpolatorStringLookup.INSTANCE, stringLookupFactory.interpolatorStringLookup());
225228
Assertions.assertSame(JavaPlatformStringLookup.INSTANCE, stringLookupFactory.javaPlatformStringLookup());
226-
Assertions.assertSame(InetAddressStringLookup.INSTANCE, stringLookupFactory.localHostStringLookup());
229+
Assertions.assertSame(InetAddressStringLookup.LOCAL_HOST, stringLookupFactory.localHostStringLookup());
230+
Assertions.assertSame(InetAddressStringLookup.LOOPACK_ADDRESS, stringLookupFactory.loopbackAddressStringLookup());
227231
Assertions.assertSame(StringLookupFactory.INSTANCE_NULL, stringLookupFactory.nullStringLookup());
228232
Assertions.assertSame(ResourceBundleStringLookup.INSTANCE, stringLookupFactory.resourceBundleStringLookup());
229233
Assertions.assertSame(ScriptStringLookup.INSTANCE, stringLookupFactory.scriptStringLookup());

0 commit comments

Comments
 (0)