View Javadoc

1   /*
2    * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/oac.hc3x/trunk/src/java/org/apache/commons/httpclient/HostConfiguration.java $
3    * $Revision$
4    * $Date$
5    *
6    * ====================================================================
7    *
8    *  Licensed to the Apache Software Foundation (ASF) under one or more
9    *  contributor license agreements.  See the NOTICE file distributed with
10   *  this work for additional information regarding copyright ownership.
11   *  The ASF licenses this file to You under the Apache License, Version 2.0
12   *  (the "License"); you may not use this file except in compliance with
13   *  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, software
18   *  distributed under the License is distributed on an "AS IS" BASIS,
19   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   *  See the License for the specific language governing permissions and
21   *  limitations under the License.
22   * ====================================================================
23   *
24   * This software consists of voluntary contributions made by many
25   * individuals on behalf of the Apache Software Foundation.  For more
26   * information on the Apache Software Foundation, please see
27   * <http://www.apache.org/>.
28   *
29   */
30  
31  package org.apache.commons.httpclient;
32  
33  import org.apache.commons.httpclient.params.HostParams;
34  import org.apache.commons.httpclient.protocol.Protocol;
35  import org.apache.commons.httpclient.util.LangUtils;
36  
37  import java.net.InetAddress;
38  
39  /***
40   * Holds all of the variables needed to describe an HTTP connection to a host.  This includes 
41   * remote host, port and protocol, proxy host and port, local address, and virtual host.
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@ural.ru">Oleg Kalnichevski</a>
46   * @author Laura Werner
47   * 
48   * @since 2.0 
49   */
50  public class HostConfiguration implements Cloneable {
51  
52      /***
53       * A value to represent any host configuration, instead of using something like
54       * <code>null</code>. This value should be treated as immutable and only used in 
55       * lookups and other such places to represent "any" host config.
56       */
57      public static final HostConfiguration ANY_HOST_CONFIGURATION = new HostConfiguration();
58  
59      /*** The host to use. */
60      private HttpHost host = null;
61  
62      /*** The host name of the proxy server */
63      private ProxyHost proxyHost = null;
64  
65      /*** The local address to use when creating the socket, or null to use the default */
66      private InetAddress localAddress = null;
67  
68      /*** Parameters specific to this host */
69      private HostParams params = new HostParams();
70  
71      /***
72       * Constructor for HostConfiguration.
73       */
74      public HostConfiguration() {
75          super();
76      }
77      
78      /***
79       * Copy constructor for HostConfiguration
80       * 
81       * @param hostConfiguration the hostConfiguration to copy
82       */
83      public HostConfiguration (final HostConfiguration hostConfiguration) {
84          init(hostConfiguration);        
85      }
86  
87  	private void init(final HostConfiguration hostConfiguration) {
88  		// wrap all of the assignments in a synchronized block to avoid
89          // having to negotiate the monitor for each method call
90          synchronized (hostConfiguration) {
91              try {
92                  if (hostConfiguration.host != null) {
93                      this.host = (HttpHost) hostConfiguration.host.clone();
94                  } else {
95                      this.host = null;
96                  }
97                  if (hostConfiguration.proxyHost != null) {
98                      this.proxyHost = (ProxyHost) hostConfiguration.proxyHost.clone();
99                  } else {
100                     this.proxyHost = null;
101                 }
102                 this.localAddress = hostConfiguration.getLocalAddress();
103                 this.params = (HostParams)hostConfiguration.getParams().clone();
104             } catch (CloneNotSupportedException e) {
105                 throw new IllegalArgumentException("Host configuration could not be cloned");
106             }
107         }        
108     }
109 
110     /***
111      * @see java.lang.Object#clone()
112      */
113     public Object clone() {
114     	HostConfiguration copy;
115 		try {
116 			copy = (HostConfiguration) super.clone();
117 		} catch (CloneNotSupportedException e) {
118             throw new IllegalArgumentException("Host configuration could not be cloned");
119 		}
120     	copy.init(this);
121         return copy;
122     }    
123     
124     /***
125      * @see java.lang.Object#toString()
126      */
127     public synchronized String toString() {
128         
129         boolean appendComma = false;
130         StringBuffer b = new StringBuffer(50);        
131         b.append("HostConfiguration[");
132         
133         if (this.host != null) {
134             appendComma = true;
135             b.append("host=").append(this.host);
136         }
137         if (this.proxyHost != null) {
138             if (appendComma) {
139                 b.append(", ");
140             } else {
141                 appendComma = true;
142             }
143             b.append("proxyHost=").append(this.proxyHost);
144         }
145         if (this.localAddress != null) {
146             if (appendComma) {
147                 b.append(", ");
148             } else {
149                 appendComma = true;
150             }
151             b.append("localAddress=").append(this.localAddress);
152             if (appendComma) {
153                 b.append(", ");
154             } else {
155                 appendComma = true;
156             }
157             b.append("params=").append(this.params);
158         }
159         b.append("]");
160         return b.toString();
161     }    
162     
163     /***
164      * Tests if the host configuration equals the configuration set on the
165      * connection. True only if the host, port, protocol, local address and virtual address
166      * are equal.  If no host configuration has been set false will be returned.
167      * 
168      * @param connection the connection to test against
169      * @return <code>true</code> if the connection's host information equals that of this
170      * configuration
171      * 
172      * @see #proxyEquals(HttpConnection)
173      */
174     public synchronized boolean hostEquals(final HttpConnection connection) {
175         if (connection == null) {
176             throw new IllegalArgumentException("Connection may not be null");
177         }
178         if (this.host != null) {
179             if (!this.host.getHostName().equalsIgnoreCase(connection.getHost())) {
180                 return false;
181             }
182             if (this.host.getPort() != connection.getPort()) {
183                 return false;
184             }
185             if (!this.host.getProtocol().equals(connection.getProtocol())) {
186                 return false;
187             }
188             if (this.localAddress != null) {
189                 if (!this.localAddress.equals(connection.getLocalAddress())) {
190                     return false;
191                 }
192             } else {
193                 if (connection.getLocalAddress() != null) {
194                     return false; 
195                 }
196             }
197             return true;
198         } else {
199             return false;   
200         }
201     }
202 
203     /***
204      * Tests if the proxy configuration equals the configuration set on the
205      * connection. True only if the proxyHost and proxyPort are equal.
206      *
207      * @param connection the connection to test against
208      * @return <code>true</code> if the connection's proxy information equals that of this
209      * configuration
210      *
211      * @see #hostEquals(HttpConnection)
212      */
213     public synchronized boolean proxyEquals(final HttpConnection connection) {
214         if (connection == null) {
215             throw new IllegalArgumentException("Connection may not be null");
216         }
217         if (this.proxyHost != null) {
218             return
219                 this.proxyHost.getHostName().equalsIgnoreCase(connection.getProxyHost())
220                 && this.proxyHost.getPort() == connection.getProxyPort();
221         } else {
222             return connection.getProxyHost() == null;
223         }
224     }    
225     
226     /***
227      * Returns true if the host is set.
228      * @return <code>true</code> if the host is set.
229      * 
230      * @deprecated no longer used
231      */
232     public synchronized boolean isHostSet() {
233         return this.host != null;
234     }
235 
236     /***
237      * Sets the given host
238      * 
239      * @param host the host
240      */
241     public synchronized void setHost(final HttpHost host) {
242         this.host = host;
243     }
244     
245     /***
246      * Sets the given host, port and protocol
247      * 
248      * @param host the host(IP or DNS name)
249      * @param port The port
250      * @param protocol The protocol.
251      */
252     public synchronized void setHost(final String host, int port, final String protocol) {
253         this.host = new HttpHost(host, port, Protocol.getProtocol(protocol));
254     }
255     
256     /***
257      * Sets the given host, virtual host, port and protocol.
258      * 
259      * @param host the host(IP or DNS name)
260      * @param virtualHost the virtual host name or <code>null</code>
261      * @param port the host port or -1 to use protocol default
262      * @param protocol the protocol
263      * 
264      * @deprecated #setHost(String, int, Protocol)
265      */
266     public synchronized void setHost(final String host, final String virtualHost, int port, 
267         final Protocol protocol) {
268         setHost(host, port, protocol);
269         this.params.setVirtualHost(virtualHost);
270     }
271 
272     /***
273      * Sets the given host, port and protocol.
274      *   
275      * @param host the host(IP or DNS name)
276      * @param port The port
277      * @param protocol the protocol
278      */
279     public synchronized void setHost(final String host, int port, final Protocol protocol) {
280         if (host == null) {
281             throw new IllegalArgumentException("host must not be null");   
282         }
283         if (protocol == null) {
284             throw new IllegalArgumentException("protocol must not be null");   
285         }
286         this.host = new HttpHost(host, port, protocol);
287     }
288 
289     /***
290      * Sets the given host and port.  Uses the default protocol "http".
291      * 
292      * @param host the host(IP or DNS name)
293      * @param port The port
294      */
295     public synchronized void setHost(final String host, int port) {
296         setHost(host, port, Protocol.getProtocol("http"));
297     }
298     
299     /***
300      * Set the given host. Uses the default protocol("http") and its port.
301      * 
302      * @param host The host(IP or DNS name).
303      */
304     public synchronized void setHost(final String host) {
305         Protocol defaultProtocol = Protocol.getProtocol("http"); 
306         setHost(host, defaultProtocol.getDefaultPort(), defaultProtocol);
307     }
308     
309     /***
310      * Sets the protocol, host and port from the given URI.
311      * @param uri the URI.
312      */
313     public synchronized void setHost(final URI uri) {
314         try {
315             setHost(uri.getHost(), uri.getPort(), uri.getScheme());
316         } catch (URIException e) {
317             throw new IllegalArgumentException(e.toString());
318         }
319     }
320 
321     /***
322      * Return the host url.
323      * 
324      * @return The host url.
325      */
326     public synchronized String getHostURL() {
327         if (this.host == null) {
328             throw new IllegalStateException("Host must be set to create a host URL");   
329         } else {
330             return this.host.toURI();
331         }
332     }
333 
334     /***
335      * Returns the host.
336      * 
337      * @return the host(IP or DNS name), or <code>null</code> if not set
338      * 
339      * @see #isHostSet()
340      */
341     public synchronized String getHost() {
342         if (this.host != null) {
343             return this.host.getHostName();
344         } else {
345             return null;
346         }
347     }
348 
349     /***
350      * Returns the virtual host.
351      * 
352      * @return the virtual host name, or <code>null</code> if not set
353      * 
354      * @deprecated use HostParams
355      */
356     public synchronized String getVirtualHost() {
357     	return this.params.getVirtualHost();
358     }
359 
360     /***
361      * Returns the port.
362      * 
363      * @return the host port, or <code>-1</code> if not set
364      * 
365      * @see #isHostSet()
366      */
367     public synchronized int getPort() {
368         if (this.host != null) {
369             return this.host.getPort();
370         } else {
371             return -1;
372         }
373     }
374 
375     /***
376      * Returns the protocol.
377      * @return The protocol.
378      */
379     public synchronized Protocol getProtocol() {
380         if (this.host != null) {
381             return this.host.getProtocol();
382         } else {
383             return null;
384         }
385     }
386 
387     /***
388      * Tests if the proxy host/port have been set.
389      * 
390      * @return <code>true</code> if a proxy server has been set.
391      * 
392      * @see #setProxy(String, int)
393      * 
394      * @deprecated no longer used
395      */    
396     public synchronized boolean isProxySet() {
397         return this.proxyHost != null;   
398     }
399 
400     /***
401      * Sets the given proxy host
402      * 
403      * @param proxyHost the proxy host
404      */
405     public synchronized void setProxyHost(final ProxyHost proxyHost) {
406         this.proxyHost = proxyHost;
407     }
408     
409     /***
410      * Set the proxy settings.
411      * @param proxyHost The proxy host
412      * @param proxyPort The proxy port
413      */
414     public synchronized void setProxy(final String proxyHost, int proxyPort) {
415         this.proxyHost = new ProxyHost(proxyHost, proxyPort); 
416     }
417 
418     /***
419      * Returns the proxyHost.
420      * 
421      * @return the proxy host, or <code>null</code> if not set
422      * 
423      * @see #isProxySet()
424      */
425     public synchronized String getProxyHost() {
426         if (this.proxyHost != null) {
427             return this.proxyHost.getHostName();
428         } else {
429             return null;
430         }
431     }
432 
433     /***
434      * Returns the proxyPort.
435      * 
436      * @return the proxy port, or <code>-1</code> if not set
437      * 
438      * @see #isProxySet()
439      */
440     public synchronized int getProxyPort() {
441         if (this.proxyHost != null) {
442             return this.proxyHost.getPort();
443         } else {
444             return -1;
445         }
446     }
447 
448     /***
449      * Set the local address to be used when creating connections.
450      * If this is unset, the default address will be used.
451      * This is useful for specifying the interface to use on multi-homed or clustered systems.
452      * 
453      * @param localAddress the local address to use
454      */
455     
456     public synchronized void setLocalAddress(InetAddress localAddress) {
457         this.localAddress = localAddress;
458     }
459 
460     /***
461      * Return the local address to be used when creating connections.
462      * If this is unset, the default address should be used.
463      * 
464      * @return the local address to be used when creating Sockets, or <code>null</code>
465      */
466     
467     public synchronized InetAddress getLocalAddress() {
468         return this.localAddress;
469     }
470     
471     /***
472      * Returns {@link HostParams HTTP protocol parameters} associated with this host.
473      *
474      * @return HTTP parameters.
475      *
476      * @since 3.0
477      */
478     public HostParams getParams() {
479         return this.params;
480     }
481 
482     /***
483      * Assigns {@link HostParams HTTP protocol parameters} specific to this host.
484      * 
485      * @since 3.0
486      * 
487      * @see HostParams
488      */
489     public void setParams(final HostParams params) {
490         if (params == null) {
491             throw new IllegalArgumentException("Parameters may not be null");
492         }
493         this.params = params;
494     }
495 
496     /***
497      * @see java.lang.Object#equals(java.lang.Object)
498      */
499     public synchronized boolean equals(final Object o) {
500         if (o instanceof HostConfiguration) {
501             // shortcut if we're comparing with ourselves
502             if (o == this) { 
503                 return true;
504             }
505             HostConfiguration that = (HostConfiguration) o;
506             return LangUtils.equals(this.host, that.host)
507                 && LangUtils.equals(this.proxyHost, that.proxyHost)
508                 && LangUtils.equals(this.localAddress, that.localAddress);
509         } else {
510             return false;
511         }
512         
513     }
514 
515     /***
516      * @see java.lang.Object#hashCode()
517      */
518     public synchronized int hashCode() {
519         int hash = LangUtils.HASH_SEED;
520         hash = LangUtils.hashCode(hash, this.host);
521         hash = LangUtils.hashCode(hash, this.proxyHost);
522         hash = LangUtils.hashCode(hash, this.localAddress);
523         return hash;
524     }
525 
526 }