summaryrefslogtreecommitdiffstats
path: root/jrt/src/com/yahoo/jrt/Spec.java
blob: e20bb9109dc84fb750ddce1a84013e80c0f43372 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jrt;


import java.net.InetSocketAddress;
import java.net.SocketAddress;


/**
 * A Spec is a network address used for either listening or
 * connecting.
 */
public class Spec {

    private SocketAddress address;
    private String        host;
    private int           port;
    private boolean       malformed;

    /**
     * Create a Spec from a string. The form of the input string is
     * 'tcp/host:port' or 'tcp/port' where 'host' is the host name and
     * 'port' is the port number.
     *
     * @param spec input string to be parsed
     * @see #malformed
     */
    public Spec(String spec) {
        if (spec.startsWith("tcp/")) {
            int sep = spec.indexOf(':');
            String portStr;
            if (sep == -1) {
                portStr = spec.substring(4);
            } else {
                host = spec.substring(4, sep);
                portStr = spec.substring(sep + 1);
            }
            try {
                port = Integer.parseInt(portStr);
            } catch (NumberFormatException e) {
                host = null;
                port = 0;
                malformed = true;
            }
        } else {
            malformed = true;
        }
    }

    /**
     * Create a Spec from a host name and a port number.
     *
     * @param host host name
     * @param port port number
     */
    public Spec(String host, int port) {
        this.host = host;
        this.port = port;
    }

    /**
     * Create a Spec that will produce a wildcard address with address, and the
     * hostname of the localhost with connectAddress.
     *
     * WARNING: Do not use omit host if connecting (to localhost) - use Spec("localhost", port) instead.
     * Why? Because the SocketAddress obtained from spec is independent on whether to use the address
     * for listening socket or connecting socket.  A listening socket without host means the wildcard address
     * is used. But when using the wildcard address for connecting, Java ends up getting the canonical
     * hostname for localhost, which may not be reachable if on WiFi-only, see HostName.getLocalhost for details.
     *
     * @param port
     */
    public Spec(int port) {
        this.port = port;
    }

    /**
     * Obtain the host name of this address
     *
     * @return host name
     */
    public String host() {
        return host;
    }

    /**
     * Obtain the port number if this address
     *
     * @return port number
     */
    public int port() {
        return port;
    }

    /**
     * If this Spec was created from a string, this method will tell
     * you whether that string was malformed.
     *
     * @return true if this address is malformed
     */
    public boolean malformed() {
        return malformed;
    }

    /**
     * Resolve the listening socket address for this Spec. If this Spec is
     * malformed, this method will return null.
     *
     * @return listening socket address
     */
    SocketAddress address() {
        if (malformed) {
            return null;
        }
        if (address == null) {
            if (host == null) {
                return new InetSocketAddress(port);
            } else {
                return new InetSocketAddress(host, port);
            }
        }
        return address;
    }

    /**
     * Obtain a string representation of this address. The return
     * value from this method may be used to create a new Spec.
     *
     * @return string representation of this address
     */
    public String toString() {
        if (malformed) {
            return "MALFORMED";
        }
        if (host == null) {
            return "tcp/" + port;
        }
        return "tcp/" + host + ":" + port;
    }

}