/ org.apache.commons.httpclient / src / org / apache / commons / httpclient / HostConfiguration.java
HostConfiguration.java
  1  /*
  2   * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/HostConfiguration.java,v 1.23 2005/01/14 21:16:40 olegk Exp $
  3   * $Revision: 510585 $
  4   * $Date: 2007-02-22 17:52:16 +0100 (Thu, 22 Feb 2007) $
  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  }