View Javadoc
1   /*
2    * Copyright 2015 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.resolver;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.Reader;
21  import java.net.Inet4Address;
22  import java.net.Inet6Address;
23  import java.net.InetAddress;
24  import java.nio.charset.Charset;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  /**
30   * A parser for hosts files.
31   * The produced mappings contain only the first entry per hostname.
32   * Consider using {@link HostsFileEntriesProvider} when mappings with all entries per hostname are needed.
33   */
34  public final class HostsFileParser {
35  
36      /**
37       * Parse hosts file at standard OS location using the systems default {@link Charset} for decoding.
38       *
39       * @return a {@link HostsFileEntries}
40       */
41      public static HostsFileEntries parseSilently() {
42          return hostsFileEntries(HostsFileEntriesProvider.parser().parseSilently());
43      }
44  
45      /**
46       * Parse hosts file at standard OS location using the given {@link Charset}s one after each other until
47       * we were able to parse something or none is left.
48       *
49       * @param charsets the {@link Charset}s to try as file encodings when parsing.
50       * @return a {@link HostsFileEntries}
51       */
52      public static HostsFileEntries parseSilently(Charset... charsets) {
53          return hostsFileEntries(HostsFileEntriesProvider.parser().parseSilently(charsets));
54      }
55  
56      /**
57       * Parse hosts file at standard OS location using the system default {@link Charset} for decoding.
58       *
59       * @return a {@link HostsFileEntries}
60       * @throws IOException file could not be read
61       */
62      public static HostsFileEntries parse() throws IOException {
63          return hostsFileEntries(HostsFileEntriesProvider.parser().parse());
64      }
65  
66      /**
67       * Parse a hosts file using the system default {@link Charset} for decoding.
68       *
69       * @param file the file to be parsed
70       * @return a {@link HostsFileEntries}
71       * @throws IOException file could not be read
72       */
73      public static HostsFileEntries parse(File file) throws IOException {
74          return hostsFileEntries(HostsFileEntriesProvider.parser().parse(file));
75      }
76  
77      /**
78       * Parse a hosts file.
79       *
80       * @param file the file to be parsed
81       * @param charsets the {@link Charset}s to try as file encodings when parsing.
82       * @return a {@link HostsFileEntries}
83       * @throws IOException file could not be read
84       */
85      public static HostsFileEntries parse(File file, Charset... charsets) throws IOException {
86          return hostsFileEntries(HostsFileEntriesProvider.parser().parse(file, charsets));
87      }
88  
89      /**
90       * Parse a reader of hosts file format.
91       *
92       * @param reader the file to be parsed
93       * @return a {@link HostsFileEntries}
94       * @throws IOException file could not be read
95       */
96      public static HostsFileEntries parse(Reader reader) throws IOException {
97          return hostsFileEntries(HostsFileEntriesProvider.parser().parse(reader));
98      }
99  
100     /**
101      * Can't be instantiated.
102      */
103     private HostsFileParser() {
104     }
105 
106     @SuppressWarnings("unchecked")
107     private static HostsFileEntries hostsFileEntries(HostsFileEntriesProvider provider) {
108         return provider == HostsFileEntriesProvider.EMPTY ? HostsFileEntries.EMPTY :
109                 new HostsFileEntries((Map<String, Inet4Address>) toMapWithSingleValue(provider.ipv4Entries()),
110                         (Map<String, Inet6Address>) toMapWithSingleValue(provider.ipv6Entries()));
111     }
112 
113     private static Map<String, ?> toMapWithSingleValue(Map<String, List<InetAddress>> fromMapWithListValue) {
114         Map<String, InetAddress> result = new HashMap<>(fromMapWithListValue.size());
115         for (Map.Entry<String, List<InetAddress>> entry : fromMapWithListValue.entrySet()) {
116             List<InetAddress> value = entry.getValue();
117             if (!value.isEmpty()) {
118                 result.put(entry.getKey(), value.get(0));
119             }
120         }
121         return result;
122     }
123 }