1/*
2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/HttpHost.java $
3 * $Revision: 653058 $
4 * $Date: 2008-05-03 05:01:10 -0700 (Sat, 03 May 2008) $
5 *
6 * ====================================================================
7 * Licensed to the Apache Software Foundation (ASF) under one
8 * or more contributor license agreements.  See the NOTICE file
9 * distributed with this work for additional information
10 * regarding copyright ownership.  The ASF licenses this file
11 * to you under the Apache License, Version 2.0 (the
12 * "License"); you may not use this file except in compliance
13 * with the License.  You may obtain a copy of the License at
14 *
15 *   http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing,
18 * software distributed under the License is distributed on an
19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20 * KIND, either express or implied.  See the License for the
21 * specific language governing permissions and limitations
22 * under the License.
23 * ====================================================================
24 *
25 * This software consists of voluntary contributions made by many
26 * individuals on behalf of the Apache Software Foundation.  For more
27 * information on the Apache Software Foundation, please see
28 * <http://www.apache.org/>.
29 *
30 */
31
32package org.apache.http;
33
34import java.util.Locale;
35
36import org.apache.http.util.CharArrayBuffer;
37import org.apache.http.util.LangUtils;
38
39/**
40 * Holds all of the variables needed to describe an HTTP connection to a host.
41 * This includes remote host name, port and scheme.
42 *
43 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
44 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
45 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
46 * @author Laura Werner
47 *
48 * @since 4.0
49 */
50public final class HttpHost implements Cloneable {
51
52    /** The default scheme is "http". */
53    public static final String DEFAULT_SCHEME_NAME = "http";
54
55    /** The host to use. */
56    protected final String hostname;
57
58    /** The lowercase host, for {@link #equals} and {@link #hashCode}. */
59    protected final String lcHostname;
60
61
62    /** The port to use. */
63    protected final int port;
64
65    /** The scheme */
66    protected final String schemeName;
67
68
69    /**
70     * Creates a new {@link HttpHost HttpHost}, specifying all values.
71     * Constructor for HttpHost.
72     *
73     * @param hostname  the hostname (IP or DNS name)
74     * @param port      the port number.
75     *                  <code>-1</code> indicates the scheme default port.
76     * @param scheme    the name of the scheme.
77     *                  <code>null</code> indicates the
78     *                  {@link #DEFAULT_SCHEME_NAME default scheme}
79     */
80    public HttpHost(final String hostname, int port, final String scheme) {
81        super();
82        if (hostname == null) {
83            throw new IllegalArgumentException("Host name may not be null");
84        }
85        this.hostname   = hostname;
86        this.lcHostname = hostname.toLowerCase(Locale.ENGLISH);
87        if (scheme != null) {
88            this.schemeName = scheme.toLowerCase(Locale.ENGLISH);
89        } else {
90            this.schemeName = DEFAULT_SCHEME_NAME;
91        }
92        this.port = port;
93    }
94
95    /**
96     * Creates a new {@link HttpHost HttpHost}, with default scheme.
97     *
98     * @param hostname  the hostname (IP or DNS name)
99     * @param port      the port number.
100     *                  <code>-1</code> indicates the scheme default port.
101     */
102    public HttpHost(final String hostname, int port) {
103        this(hostname, port, null);
104    }
105
106    /**
107     * Creates a new {@link HttpHost HttpHost}, with default scheme and port.
108     *
109     * @param hostname  the hostname (IP or DNS name)
110     */
111    public HttpHost(final String hostname) {
112        this(hostname, -1, null);
113    }
114
115    /**
116     * Copy constructor for {@link HttpHost HttpHost}.
117     *
118     * @param httphost the HTTP host to copy details from
119     */
120    public HttpHost (final HttpHost httphost) {
121        this(httphost.hostname, httphost.port, httphost.schemeName);
122    }
123
124    /**
125     * Returns the host name.
126     *
127     * @return the host name (IP or DNS name)
128     */
129    public String getHostName() {
130        return this.hostname;
131    }
132
133    /**
134     * Returns the port.
135     *
136     * @return the host port, or <code>-1</code> if not set
137     */
138    public int getPort() {
139        return this.port;
140    }
141
142    /**
143     * Returns the scheme name.
144     *
145     * @return the scheme name
146     */
147    public String getSchemeName() {
148        return this.schemeName;
149    }
150
151    /**
152     * Return the host URI, as a string.
153     *
154     * @return the host URI
155     */
156    public String toURI() {
157        CharArrayBuffer buffer = new CharArrayBuffer(32);
158        buffer.append(this.schemeName);
159        buffer.append("://");
160        buffer.append(this.hostname);
161        if (this.port != -1) {
162            buffer.append(':');
163            buffer.append(Integer.toString(this.port));
164        }
165        return buffer.toString();
166    }
167
168
169    /**
170     * Obtains the host string, without scheme prefix.
171     *
172     * @return  the host string, for example <code>localhost:8080</code>
173     */
174    public String toHostString() {
175        CharArrayBuffer buffer = new CharArrayBuffer(32);
176        buffer.append(this.hostname);
177        if (this.port != -1) {
178            buffer.append(':');
179            buffer.append(Integer.toString(this.port));
180        }
181        return buffer.toString();
182    }
183
184
185    public String toString() {
186        return toURI();
187    }
188
189
190    public boolean equals(final Object obj) {
191        if (obj == null) return false;
192        if (this == obj) return true;
193        if (obj instanceof HttpHost) {
194            HttpHost that = (HttpHost) obj;
195            return this.lcHostname.equals(that.lcHostname)
196                && this.port == that.port
197                && this.schemeName.equals(that.schemeName);
198        } else {
199            return false;
200        }
201    }
202
203    /**
204     * @see java.lang.Object#hashCode()
205     */
206    public int hashCode() {
207        int hash = LangUtils.HASH_SEED;
208        hash = LangUtils.hashCode(hash, this.lcHostname);
209        hash = LangUtils.hashCode(hash, this.port);
210        hash = LangUtils.hashCode(hash, this.schemeName);
211        return hash;
212    }
213
214    public Object clone() throws CloneNotSupportedException {
215        return super.clone();
216    }
217
218}
219