1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.util;
17
18 import java.util.LinkedHashMap;
19 import java.util.Map;
20
21 import static java.util.Objects.requireNonNull;
22
23
24
25
26
27
28 public class DomainWildcardMappingBuilder<V> {
29
30 private final V defaultValue;
31 private final Map<String, V> map;
32
33
34
35
36
37
38
39 public DomainWildcardMappingBuilder(V defaultValue) {
40 this(4, defaultValue);
41 }
42
43
44
45
46
47
48
49
50 public DomainWildcardMappingBuilder(int initialCapacity, V defaultValue) {
51 this.defaultValue = requireNonNull(defaultValue, "defaultValue");
52 map = new LinkedHashMap<>(initialCapacity);
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public DomainWildcardMappingBuilder<V> add(String hostname, V output) {
73 map.put(normalizeHostName(hostname),
74 requireNonNull(output, "output"));
75 return this;
76 }
77
78 private String normalizeHostName(String hostname) {
79 requireNonNull(hostname, "hostname");
80 if (hostname.isEmpty() || hostname.charAt(0) == '.') {
81 throw new IllegalArgumentException("Hostname '" + hostname + "' not valid");
82 }
83 hostname = ImmutableDomainWildcardMapping.normalize(requireNonNull(hostname, "hostname"));
84 if (hostname.charAt(0) == '*') {
85 if (hostname.length() < 3 || hostname.charAt(1) != '.') {
86 throw new IllegalArgumentException("Wildcard Hostname '" + hostname + "'not valid");
87 }
88 return hostname.substring(1);
89 }
90 return hostname;
91 }
92
93
94
95
96
97 public Mapping<String, V> build() {
98 return new ImmutableDomainWildcardMapping<>(defaultValue, map);
99 }
100
101 private static final class ImmutableDomainWildcardMapping<V> implements Mapping<String, V> {
102 private static final String REPR_HEADER = "ImmutableDomainWildcardMapping(default: ";
103 private static final String REPR_MAP_OPENING = ", map: ";
104 private static final String REPR_MAP_CLOSING = ")";
105
106 private final V defaultValue;
107 private final Map<String, V> map;
108
109 ImmutableDomainWildcardMapping(V defaultValue, Map<String, V> map) {
110 this.defaultValue = defaultValue;
111 this.map = new LinkedHashMap<>(map);
112 }
113
114 @Override
115 public V map(String hostname) {
116 if (hostname != null) {
117 hostname = normalize(hostname);
118
119
120 V value = map.get(hostname);
121 if (value != null) {
122 return value;
123 }
124
125
126 int idx = hostname.indexOf('.');
127 if (idx != -1) {
128 value = map.get(hostname.substring(idx));
129 if (value != null) {
130 return value;
131 }
132 }
133 }
134
135 return defaultValue;
136 }
137
138 @SuppressWarnings("deprecation")
139 static String normalize(String hostname) {
140 return DomainNameMapping.normalizeHostname(hostname);
141 }
142
143 @Override
144 public String toString() {
145 StringBuilder sb = new StringBuilder();
146 sb.append(REPR_HEADER).append(defaultValue).append(REPR_MAP_OPENING).append('{');
147
148 for (Map.Entry<String, V> entry : map.entrySet()) {
149 String hostname = entry.getKey();
150 if (hostname.charAt(0) == '.') {
151 hostname = '*' + hostname;
152 }
153 sb.append(hostname).append('=').append(entry.getValue()).append(", ");
154 }
155 sb.setLength(sb.length() - 2);
156 return sb.append('}').append(REPR_MAP_CLOSING).toString();
157 }
158 }
159 }