Repository: netty/netty
Issue: Allow retrieving the domain match lists in DomainNameMapping
Labels: improvement
feature

Currently, there's no way to retrieve the list of all domain name patterns and their mapped values. It would be very useful when you have to build another `DomainNameMapping` (or an arbitrary `Mapping`) based on that list. e.g.

``` java
DomainNameMapping<SslContext> mapping = ...;
MyNameMapping<MyService> newMapping = ...;
mapping.entries().stream().forEach(e -> newMapping.add(e.getKey(), ...));
```


Issue comments:
Fixed by https://github.com/netty/netty/pull/5265


Pull request review comments:
use `new LinkedHashSet<...>(domanNamePatterns.length)`

Also ensure this is read-only ?

Added the length hint. Is there any `Map.Entry` implementation in netty?

> Also ensure this is read-only ?

Done.


Patch that resolved the issue:
diff --git a/common/src/main/java/io/netty/util/DomainMappingBuilder.java b/common/src/main/java/io/netty/util/DomainMappingBuilder.java
index 0cdb9712b7d..4d497456710 100644
--- a/common/src/main/java/io/netty/util/DomainMappingBuilder.java
+++ b/common/src/main/java/io/netty/util/DomainMappingBuilder.java
@@ -16,6 +16,8 @@
 
 package io.netty.util;
 
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -137,6 +139,16 @@ public V map(String hostname) {
             return defaultValue;
         }
 
+        @Override
+        public Set<Map.Entry<String, V>> entries() {
+            int length = domainNamePatterns.length;
+            Map<String, V> map = new HashMap<String, V>(length);
+            for (int index = 0; index < length; ++index) {
+                map.put(domainNamePatterns[index], values[index]);
+            }
+            return Collections.unmodifiableSet(map.entrySet());
+        }
+
         @Override
         public String toString() {
             String defaultValueStr = defaultValue.toString();
diff --git a/common/src/main/java/io/netty/util/DomainNameMapping.java b/common/src/main/java/io/netty/util/DomainNameMapping.java
index ff9aeb9cb0a..f31da8643c3 100644
--- a/common/src/main/java/io/netty/util/DomainNameMapping.java
+++ b/common/src/main/java/io/netty/util/DomainNameMapping.java
@@ -19,9 +19,11 @@
 import io.netty.util.internal.StringUtil;
 
 import java.net.IDN;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 import static io.netty.util.internal.ObjectUtil.checkNotNull;
 import static io.netty.util.internal.StringUtil.commonSuffixOfLength;
@@ -132,6 +134,13 @@ public V map(String hostname) {
         return defaultValue;
     }
 
+    /**
+     * Returns a read-only {@link Set} of the domain mapping patterns and their associated value objects.
+     */
+    public Set<Map.Entry<String, V>> entries() {
+        return Collections.unmodifiableSet(map.entrySet());
+    }
+
     @Override
     public String toString() {
         return StringUtil.simpleClassName(this) + "(default: " + defaultValue + ", map: " + map + ')';


Test patch:
diff --git a/common/src/test/java/io/netty/util/DomainNameMappingTest.java b/common/src/test/java/io/netty/util/DomainNameMappingTest.java
index bd369e93018..606d6fca68d 100644
--- a/common/src/test/java/io/netty/util/DomainNameMappingTest.java
+++ b/common/src/test/java/io/netty/util/DomainNameMappingTest.java
@@ -16,6 +16,9 @@
 
 package io.netty.util;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -181,4 +184,37 @@ public void testToString() {
             "ImmutableDomainNameMapping(default: NotFound, map: {*.netty.io=Netty, downloads.netty.io=Netty-Download})",
             mapping.toString());
     }
+
+    @Test
+    public void testEntries() {
+        DomainNameMapping<String> mapping = new DomainNameMapping<String>("NotFound")
+            .add("netty.io", "Netty")
+            .add("downloads.netty.io", "Netty-Downloads");
+
+        Map<String, String> entries = new HashMap<String, String>();
+        for (Map.Entry<String, String> entry: mapping.entries()) {
+            entries.put(entry.getKey(), entry.getValue());
+        }
+
+        assertEquals(2, entries.size());
+        assertEquals("Netty", entries.get("netty.io"));
+        assertEquals("Netty-Downloads", entries.get("downloads.netty.io"));
+    }
+
+    @Test
+    public void testEntriesWithImmutableDomainNameMapping() {
+        DomainNameMapping<String> mapping = new DomainMappingBuilder<String>("NotFound")
+            .add("netty.io", "Netty")
+            .add("downloads.netty.io", "Netty-Downloads")
+            .build();
+
+        Map<String, String> entries = new HashMap<String, String>();
+        for (Map.Entry<String, String> entry: mapping.entries()) {
+            entries.put(entry.getKey(), entry.getValue());
+        }
+
+        assertEquals(2, entries.size());
+        assertEquals("Netty", entries.get("netty.io"));
+        assertEquals("Netty-Downloads", entries.get("downloads.netty.io"));
+    }
 }