View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.named.ipc;
20  
21  import java.io.IOException;
22  import java.net.Inet6Address;
23  import java.net.InetAddress;
24  import java.net.InetSocketAddress;
25  import java.net.SocketAddress;
26  import java.net.StandardProtocolFamily;
27  import java.net.UnixDomainSocketAddress;
28  import java.net.UnknownHostException;
29  import java.nio.channels.ServerSocketChannel;
30  
31  /**
32   * Socket factory.
33   *
34   * @since 2.0.1
35   */
36  public enum SocketFamily {
37      inet,
38      unix;
39  
40      public ServerSocketChannel openServerSocket() throws IOException {
41          switch (this) {
42              case inet:
43                  return ServerSocketChannel.open().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
44              case unix:
45                  return ServerSocketChannel.open(StandardProtocolFamily.UNIX).bind(null, 0);
46              default:
47                  throw new IllegalStateException();
48          }
49      }
50  
51      public static SocketAddress fromString(String str) {
52          if (str.startsWith("inet:")) {
53              String s = str.substring("inet:".length());
54              int ic = s.lastIndexOf(':');
55              String ia = s.substring(0, ic);
56              int is = ia.indexOf('/');
57              String h = ia.substring(0, is);
58              String a = ia.substring(is + 1);
59              String p = s.substring(ic + 1);
60              InetAddress addr;
61              if ("<unresolved>".equals(a)) {
62                  return InetSocketAddress.createUnresolved(h, Integer.parseInt(p));
63              } else {
64                  if (a.indexOf('.') > 0) {
65                      String[] as = a.split("\\.");
66                      if (as.length != 4) {
67                          throw new IllegalArgumentException("Unsupported socket address: '" + str + "'");
68                      }
69                      byte[] ab = new byte[4];
70                      for (int i = 0; i < 4; i++) {
71                          ab[i] = (byte) Integer.parseInt(as[i]);
72                      }
73                      try {
74                          addr = InetAddress.getByAddress(h.isEmpty() ? null : h, ab);
75                      } catch (UnknownHostException e) {
76                          throw new IllegalArgumentException("Unsupported address: " + str, e);
77                      }
78                  } else {
79                      throw new IllegalArgumentException("Unsupported address: " + str);
80                  }
81                  return new InetSocketAddress(addr, Integer.parseInt(p));
82              }
83          } else if (str.startsWith("unix:")) {
84              return UnixDomainSocketAddress.of(str.substring("unix:".length()));
85          } else {
86              throw new IllegalArgumentException("Unsupported socket address: '" + str + "'");
87          }
88      }
89  
90      public static String toString(SocketAddress address) {
91          switch (familyOf(address)) {
92              case inet:
93                  InetSocketAddress isa = (InetSocketAddress) address;
94                  String host = isa.getHostString();
95                  InetAddress addr = isa.getAddress();
96                  int port = isa.getPort();
97                  String formatted;
98                  if (addr == null) {
99                      formatted = host + "/<unresolved>";
100                 } else {
101                     formatted = addr.toString();
102                     if (addr instanceof Inet6Address) {
103                         int i = formatted.lastIndexOf("/");
104                         formatted = formatted.substring(0, i + 1) + "[" + formatted.substring(i + 1) + "]";
105                     }
106                 }
107                 return "inet:" + formatted + ":" + port;
108             case unix:
109                 // to keep address string unchanged across all OSes
110                 return "unix:" + address.toString().replace('\\', '/');
111             default:
112                 throw new IllegalArgumentException("Unsupported socket address: '" + address + "'");
113         }
114     }
115 
116     public static SocketFamily familyOf(SocketAddress address) {
117         if (address instanceof InetSocketAddress) {
118             return SocketFamily.inet;
119         } else if ("java.net.UnixDomainSocketAddress".equals(address.getClass().getName())) {
120             return SocketFamily.unix;
121         } else {
122             throw new IllegalArgumentException("Unsupported socket address '" + address + "'");
123         }
124     }
125 }