You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2005/02/19 21:33:48 UTC

svn commit: r154449 - in jakarta/httpclient/trunk/http-common/src/java/org/apache/http: Header.java HeaderElement.java HttpException.java NameValuePair.java util/LangUtils.java

Author: olegk
Date: Sat Feb 19 12:33:45 2005
New Revision: 154449

URL: http://svn.apache.org/viewcvs?view=rev&rev=154449
Log:
Initial cleanup of classes imported from Commons HttpClient

Added:
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/util/LangUtils.java
Modified:
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/Header.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HeaderElement.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpException.java
    jakarta/httpclient/trunk/http-common/src/java/org/apache/http/NameValuePair.java

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/Header.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/Header.java?view=diff&r1=154448&r2=154449
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/Header.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/Header.java Sat Feb 19 12:33:45 2005
@@ -29,6 +29,8 @@
 
 package org.apache.http;
 
+import org.apache.http.util.LangUtils;
+
 /**
  * <p>An HTTP header.</p>
  *
@@ -37,30 +39,31 @@
  * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
  * @version $Revision: 1.17 $ $Date$
  */
-public class Header extends NameValuePair {
-
-    // ----------------------------------------------------------- Constructors
+public class Header {
 
+    private final String name;
+    private final String value;
+    
     /**
      * Autogenerated header flag.
      */
-    private boolean isAutogenerated = false;
+    private final boolean isAutogenerated;
     
     /**
-     * Default constructor.
-     */
-    public Header() {
-        this(null, null);
-    }
-
-    /**
-     * Constructor with name and value
+     * Constructor with name and value, and autogenerated flag
      *
      * @param name the header name
      * @param value the header value
+     * @param isAutogenerated <tt>true</tt> if the header is autogenerated,
      */
-    public Header(String name, String value) {
-        super(name, value);
+    public Header(final String name, final String value, boolean isAutogenerated) {
+        super();
+        if (name == null) {
+            throw new IllegalArgumentException("Name may not be null");
+        }
+        this.name = name;
+        this.value = value;
+        this.isAutogenerated = isAutogenerated;
     }
 
     /**
@@ -68,56 +71,59 @@
      *
      * @param name the header name
      * @param value the header value
-     * @param isAutogenerated <tt>true</tt> if the header is autogenerated,
      *  <tt>false</tt> otherwise.
      * 
      * @since 3.0
      */
-    public Header(String name, String value, boolean isAutogenerated) {
-        super(name, value);
-        this.isAutogenerated = isAutogenerated;
+    public Header(String name, String value) {
+        this(name, value, false);
     }
 
-    // --------------------------------------------------------- Public Methods
-
     /**
-     * Returns a {@link String} representation of the header.
+     * Returns the header name.
      *
-     * @return stringHEAD
+     * @return String name The name
      */
-    public String toExternalForm() {
-        return ((null == getName() ? "" : getName()) 
-            + ": " 
-            + (null == getValue() ? "" : getValue()) 
-            + "\r\n");
+    public String getName() {
+        return this.name;
     }
 
     /**
-     * Returns a {@link String} representation of the header.
+     * Returns the header value.
      *
-     * @return stringHEAD
+     * @return String value The current value.
      */
-    public String toString() {
-        return toExternalForm();
+    public String getValue() {
+        return this.value;
     }
 
     /**
-     * Returns an array of {@link HeaderElement}s
-     * constructed from my value.
-     *
-     * @see HeaderElement#parse
-     * @throws HttpException if the header cannot be parsed
-     * @return an array of header elements
+     * Returns the value of the auto-generated header flag.
+     * 
+     * @return <tt>true</tt> if the header is autogenerated,
+     *  <tt>false</tt> otherwise.
      * 
-     * @deprecated Use #getElements
+     * @since 3.0
      */
-    public HeaderElement[] getValues() throws HttpException {
-        return HeaderElement.parse(getValue());
+    public boolean isAutogenerated() {
+        return this.isAutogenerated;
+    }
+
+    /**
+     * Returns a {@link String} representation of the header.
+     *
+     * @return a string
+     */
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(this.name);
+        buffer.append(": ");
+        buffer.append(this.value);
+        return buffer.toString();
     }
 
     /**
-     * Returns an array of {@link HeaderElement}s
-     * constructed from my value.
+     * Returns an array of {@link HeaderElement}s constructed from my value.
      *
      * @see HeaderElement#parseElements(String)
      * 
@@ -129,16 +135,23 @@
         return HeaderElement.parseElements(getValue());
     }
 
-    /**
-     * Returns the value of the auto-generated header flag.
-     * 
-     * @return <tt>true</tt> if the header is autogenerated,
-     *  <tt>false</tt> otherwise.
-     * 
-     * @since 3.0
-     */
-    public boolean isAutogenerated() {
-        return isAutogenerated;
+    public boolean equals(final Object object) {
+        if (object == null) return false;
+        if (this == object) return true;
+        if (object instanceof Header) {
+            Header that = (Header) object;
+            return this.name.equals(that.name)
+                  && LangUtils.equals(this.value, that.value);
+        } else {
+            return false;
+        }
+    }
+
+    public int hashCode() {
+        int hash = LangUtils.HASH_SEED;
+        hash = LangUtils.hashCode(hash, this.name);
+        hash = LangUtils.hashCode(hash, this.value);
+        return hash;
     }
-
+    
 }

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HeaderElement.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HeaderElement.java?view=diff&r1=154448&r2=154449
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HeaderElement.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HeaderElement.java Sat Feb 19 12:33:45 2005
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.http.util.LangUtils;
 import org.apache.http.util.ParameterParser;
 
 /**
@@ -81,25 +82,11 @@
  * @since 1.0
  * @version $Revision: 1.23 $ $Date$
  */
-public class HeaderElement extends NameValuePair {
+public class HeaderElement {
 
-    // ----------------------------------------------------------- Constructors
-
-    /**
-     * Default constructor.
-     */
-    public HeaderElement() {
-        this(null, null, null);
-    }
-
-    /**
-      * Constructor.
-      * @param name my name
-      * @param value my (possibly <tt>null</tt>) value
-      */
-    public HeaderElement(String name, String value) {
-        this(name, value, null);
-    }
+    private final String name;
+    private final String value;
+    private final NameValuePair[] parameters;
 
     /**
      * Constructor with name, value and parameters.
@@ -108,13 +95,30 @@
      * @param value my (possibly <tt>null</tt>) value
      * @param parameters my (possibly <tt>null</tt>) parameters
      */
-    public HeaderElement(String name, String value,
-            NameValuePair[] parameters) {
-        super(name, value);
+    public HeaderElement(
+            final String name, 
+            final String value,
+            final NameValuePair[] parameters) {
+        super();
+        if (name == null) {
+            throw new IllegalArgumentException("Name may not be null");
+        }
+        this.name = name;
+        this.value = value;
         this.parameters = parameters;
     }
 
     /**
+     * Constructor with name and value.
+     * 
+     * @param name my name
+     * @param value my (possibly <tt>null</tt>) value
+     */
+    public HeaderElement(String name, String value) {
+       this(name, value, null);
+    }
+
+    /**
      * Constructor with array of characters.
      *
      * @param chars the array of characters
@@ -124,20 +128,21 @@
      * @since 3.0
      */
     public HeaderElement(char[] chars, int offset, int length) {
-        this();
-        if (chars == null) {
-            return;
-        }
+        super();
         ParameterParser parser = new ParameterParser();
         List params = parser.parse(chars, offset, length, ';');
         if (params.size() > 0) {
             NameValuePair element = (NameValuePair) params.remove(0);
-            setName(element.getName());  
-            setValue(element.getValue());
+            this.name = element.getName();
+            this.value = element.getValue();
             if (params.size() > 0) {
                 this.parameters = (NameValuePair[])
                     params.toArray(new NameValuePair[params.size()]);    
+            } else {
+                this.parameters = null;
             }
+        } else {
+            throw new IllegalArgumentException("Empty array of chars");
         }
     }
 
@@ -152,14 +157,23 @@
         this(chars, 0, chars.length);
     }
 
-    // -------------------------------------------------------- Constants
-
-    // ----------------------------------------------------- Instance Variables
-
-    /** My parameters, if any. */
-    private NameValuePair[] parameters = null;
+    /**
+     * Returns the name.
+     *
+     * @return String name The name
+     */
+    public String getName() {
+        return this.name;
+    }
 
-    // ------------------------------------------------------------- Properties
+    /**
+     * Returns the value.
+     *
+     * @return String value The current value.
+     */
+    public String getValue() {
+        return this.value;
+    }
 
     /**
      * Get parameters, if any.
@@ -188,7 +202,6 @@
             return new HeaderElement[] {};
         }
         List elements = new ArrayList(); 
-        
         int i = 0;
         int from = 0;
         int len = headerValue.length;
@@ -205,7 +218,7 @@
             } else if (i == len - 1) {
                 element = new HeaderElement(headerValue, from, len);
             }
-            if ((element != null) && (element.getName() != null)) {
+            if (element != null) {
                 elements.add(element);
             }
             i++;
@@ -224,7 +237,7 @@
      * 
      * @since 3.0
      */
-    public static final HeaderElement[] parseElements(String headerValue) {
+    public static final HeaderElement[] parseElements(final String headerValue) {
         if (headerValue == null) {
             return new HeaderElement[] {};
         }
@@ -232,33 +245,13 @@
     }
 
     /**
-     * This parses the value part of a header. The result is an array of
-     * HeaderElement objects.
-     *
-     * @param headerValue  the string representation of the header value
-     *                     (as received from the web server).
-     * @return array of {@link HeaderElement}s.
-     * @throws HttpException if the above syntax rules are violated.
-     * 
-     * @deprecated Use #parseElements(String).
-     */
-    public static final HeaderElement[] parse(String headerValue)
-        throws HttpException {
-        if (headerValue == null) {
-            return new HeaderElement[] {};
-        }
-        return parseElements(headerValue.toCharArray());
-    }
-         
-
-    /**
      * Returns parameter with the given name, if found. Otherwise null 
      * is returned
      *
      * @param name The name to search by.
      * @return NameValuePair parameter with the given name
      */
-    public NameValuePair getParameterByName(String name) {
+    public NameValuePair getParameterByName(final String name) {
         if (name == null) {
             throw new IllegalArgumentException("Name may not be null");
         } 
@@ -276,5 +269,31 @@
         return found;
     }
 
+    public boolean equals(final Object object) {
+        if (object == null) return false;
+        if (this == object) return true;
+        if (object instanceof HeaderElement) {
+            HeaderElement that = (HeaderElement) object;
+            return this.name.equals(that.name)
+                && LangUtils.equals(this.value, that.value)
+                && LangUtils.equals(this.parameters, that.parameters);
+        } else {
+            return false;
+        }
+    }
+
+    public int hashCode() {
+        int hash = LangUtils.HASH_SEED;
+        hash = LangUtils.hashCode(hash, this.name);
+        hash = LangUtils.hashCode(hash, this.value);
+        if (this.parameters != null) {
+            for (int i = 0; i < this.parameters.length; i++) {
+                hash = LangUtils.hashCode(hash, this.parameters[i]);
+            }
+        }
+        return hash;
+    }
+    
+    
 }
 

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpException.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpException.java?view=diff&r1=154448&r2=154449
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpException.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/HttpException.java Sat Feb 19 12:33:45 2005
@@ -29,26 +29,20 @@
 
 package org.apache.http;
 
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-
 /**
- * Signals that an HTTP or HttpClient exception has occurred.
+ * Signals that an HTTP exception has occurred.
  * 
  * @author Laura Werner
  * 
  * @version $Revision: 1.19 $ $Date$
  */
-public class HttpException extends IOException {
+public class HttpException extends Exception {
 
     /**
      * Creates a new HttpException with a <tt>null</tt> detail message.
      */
     public HttpException() {
         super();
-        this.cause = null;
     }
 
     /**
@@ -56,9 +50,8 @@
      *
      * @param message the exception detail message
      */
-    public HttpException(String message) {
+    public HttpException(final String message) {
         super(message);
-        this.cause = null;
     }
 
     /**
@@ -70,165 +63,8 @@
      * 
      * @since 3.0
      */
-    public HttpException(String message, Throwable cause) {
-        super(message);
-        this.cause = cause;
-        
-        // If we're running on JDK 1.4 or later, tell Throwable what the cause was
-        try {
-            Class[] paramsClasses = new Class[] { Throwable.class };
-            Method initCause = Throwable.class.getMethod("initCause", paramsClasses);
-            initCause.invoke(this, new Object[] { cause });
-        } catch (Exception e) {
-            // The setCause method must not be available
-        }
-    }
-
-    /**
-     * Return the <tt>Throwable</tt> that caused this exception, or <tt>null</tt>
-     *         if the cause is unavailable, unknown, or not a <tt>Throwable</tt>.
-     * 
-     * @return the <tt>Throwable</tt> that caused this exception, or <tt>null</tt>
-     *         if the cause is unavailable, unknown, or not a <tt>Throwable</tt>
-     * 
-     * @since 3.0
-     */
-    public Throwable getCause() {
-        return cause;
-    }
-
-    /**
-     * Print this HttpException and its stack trace to the standard error stream.
-     * 
-     * @since 3.0
-     */
-    public void printStackTrace() {
-        printStackTrace(System.err);
+    public HttpException(final String message, final Throwable cause) {
+        super(message, cause);
     }
 
-    /**
-     * Print this HttpException and its stack trace to the specified print stream.
-     * 
-     * @param s the <tt>PrintStream</tt> to which the exception and its stack trace
-     * should be written
-     * 
-     * @since 3.0
-     */
-    public void printStackTrace(PrintStream s) {
-        try {
-            // JDK 1.4 has a nice printStackTrace method that prints the cause's stack
-            // trace too and prunes out duplicate stack frames.  Call it if possible,
-            // which is determined by checking whether JDK 1.4's getStackTrace method is present 
-            Class[] paramsClasses = new Class[] {  };
-            this.getClass().getMethod("getStackTrace", paramsClasses);
-            super.printStackTrace(s);
-        } catch (Exception ex) {
-            // If that didn't work, print it out ourselves
-            // First print this exception's stack trace.
-            super.printStackTrace(s);
-            if (cause != null) {
-                // Print out the exception that caused this one.
-                // This will recurse if the cause is another HttpException.
-                s.print("Caused by: ");
-                cause.printStackTrace(s);
-            }
-        }
-    }
-
-    /**
-     * Print this HttpException and its stack trace to the specified print writer.
-     * 
-     * @param s the <tt>PrintWriter</tt> to which the exception and its stack trace
-     * should be written
-     * 
-     * @since 3.0
-     */
-    public void printStackTrace(PrintWriter s) {
-        try {
-            // JDK 1.4 has a nice printStackTrace method that prints the cause's stack
-            // trace too and prunes out duplicate stack frames.  Call it if possible,
-            // which is determined by checking whether JDK 1.4's getStackTrace method is present 
-            Class[] paramsClasses = new Class[] {  };
-            this.getClass().getMethod("getStackTrace", paramsClasses);
-            super.printStackTrace(s);
-        } catch (Exception ex) {
-            // If that didn't work, print it out ourselves
-            // First print this exception's stack trace.
-            super.printStackTrace(s);
-            if (cause != null) {
-                // Print out the exception that caused this one.
-                // This will recurse if the cause is another HttpException.
-                s.print("Caused by: ");
-                cause.printStackTrace(s);
-            }
-        }
-    }
-
-    /**
-     * Sets the text description of the reason for an exception.
-     *
-     * @param reason The reason for the exception.
-     *
-     * @deprecated HttpClient no longer uses this for itself.  It is only
-     * provided for compatibility with existing clients, and will be removed
-     * in a future release.
-     */
-    public void setReason(String reason) {
-        this.reason = reason;
-    }
-
-    /**
-     * Get the text description of the reason for an exception.
-     *
-     * @deprecated HttpClient no longer uses this for itself.  It is only
-     * provided for compatibility with existing clients, and will be removed
-     * in a future release.
-     */
-    public String getReason() {
-        return reason;
-    }
-
-    /**
-     * Sets the status code description of the reason for an exception.
-     *
-     * @param code The reason for the exception.  This is intended to be an
-     *  HTTP status code.
-     *
-     * @deprecated HttpClient no longer uses this for itself.  It is only
-     * provided for compatibility with existing clients, and will be removed
-     * in a future release.
-     */
-    public void setReasonCode(int code) {
-        reasonCode = code;
-    }
-
-    /**
-     * Get the status code description of the reason for an exception.
-     *
-     * @deprecated HttpClient no longer uses this for itself.  It is only
-     * provided for compatibility with existing clients, and will be removed
-     * in a future release.
-     */
-    public int getReasonCode() {
-        return this.reasonCode;
-    }
-
-    /**
-     * A "reason" string provided for compatibility with older clients.
-     *
-     * @deprecated HttpClient no longer uses this field for itself.  It
-     * is only provided for compatibility with existing clients.
-     */
-    private String reason;
-
-    /**
-     * Reason code for compatibility with older clients.
-     *
-     * @deprecated  HttpClient no longer uses this field for itself.
-     *  It is only provided for compatibility with existing clients.
-     */
-    private int reasonCode = HttpStatus.SC_OK;
-
-    /** The original Throwable representing the cause of this error */
-    private final Throwable cause;
 }

Modified: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/NameValuePair.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/NameValuePair.java?view=diff&r1=154448&r2=154449
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/NameValuePair.java (original)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/NameValuePair.java Sat Feb 19 12:33:45 2005
@@ -31,6 +31,8 @@
 
 import java.io.Serializable;
 
+import org.apache.http.util.LangUtils;
+
 /**
  * <p>A simple class encapsulating a name/value pair.</p>
  * 
@@ -43,131 +45,72 @@
  */
 public class NameValuePair implements Serializable {
 
-    // ----------------------------------------------------------- Constructors
+    private final String name;
+    private final String value;
 
     /**
-     * Default constructor.
+     * Default Constructor taking a name and a value. The value may be null.
      * 
-     */
-    public NameValuePair() {
-        this (null, null);
-    }
-
-    /**
-     * Constructor.
      * @param name The name.
      * @param value The value.
      */
-    public NameValuePair(String name, String value) {
+    public NameValuePair(final String name, final String value) {
+        super();
+        if (name == null) {
+            throw new IllegalArgumentException("Name may not be null");
+        }
         this.name = name;
         this.value = value;
     }
 
-    // ----------------------------------------------------- Instance Variables
-
-    /**
-     * Name.
-     */
-    private String name = null;
-
-    /**
-     * Value.
-     */
-    private String value = null;
-
-    // ------------------------------------------------------------- Properties
-
-    /**
-     * Set the name.
-     *
-     * @param name The new name
-     * @see #getName()
-     */
-    public void setName(String name) {
-        this.name = name;
-    }
-
-
     /**
-     * Return the name.
+     * Returns the name.
      *
      * @return String name The name
-     * @see #setName(String)
      */
     public String getName() {
-        return name;
-    }
-
-
-    /**
-     * Set the value.
-     *
-     * @param value The new value.
-     */
-    public void setValue(String value) {
-        this.value = value;
+        return this.name;
     }
 
-
     /**
-     * Return the current value.
+     * Returns the value.
      *
      * @return String value The current value.
      */
     public String getValue() {
-        return value;
+        return this.value;
     }
 
-    // --------------------------------------------------------- Public Methods
-
     /**
-     * Get a String representation of this pair.
+     * Get a string representation of this pair.
+     * 
      * @return A string representation.
      */
     public String toString() {
-        return ("name=" + name + ", " + "value=" + value);
+        StringBuffer buffer = new StringBuffer();
+        buffer.append(this.name);
+        buffer.append(" = ");
+        buffer.append(this.value);
+        return buffer.toString();
     }
 
-    /**
-     * Test if the given <i>object</i> is equal to me. <tt>NameValuePair</tt>s
-     * are equals if both their <tt>name</tt> and <tt>value</tt> fields are equal.
-     * If <tt>object</tt> is <tt>null</tt> this method returns <tt>false</tt>.
-     *
-     * @param object the {@link Object} to compare to or <tt>null</tt>
-     * @return true if the objects are equal.
-     */
-    public boolean equals(Object object) {
+    public boolean equals(final Object object) {
         if (object == null) return false;
         if (this == object) return true;
-        if (!(object instanceof NameValuePair)) return false;
-        
-        NameValuePair pair = (NameValuePair) object;
-        return ((null == name ? null == pair.name : name.equals(pair.name))
-              && (null == value ? null == pair.value : value.equals(pair.value)));
+        if (object instanceof NameValuePair) {
+            NameValuePair that = (NameValuePair) object;
+            return this.name.equals(that.name)
+                  && LangUtils.equals(this.value, that.value);
+        } else {
+            return false;
+        }
     }
 
-    /**
-     * hashCode. Returns a hash code for this object such that if <tt>a.{@link
-     * #equals equals}(b)</tt> then <tt>a.hashCode() == b.hashCode()</tt>.
-     * @return The hash code.
-     */
     public int hashCode() {
-        return (this.getClass().hashCode() 
-            ^ (null == name ? 0 : name.hashCode()) 
-            ^ (null == value ? 0 : value.hashCode()));
-    }
-
-    /*
-    public Object clone() {
-        try {
-            NameValuePair that = (NameValuePair)(super.clone());
-            that.setName(this.getName());
-            that.setValue(this.getValue());
-            return that;
-        } catch(CloneNotSupportedException e) {
-            // this should never happen
-            throw new RuntimeException("Panic. super.clone not supported in NameValuePair.");
-        }
+        int hash = LangUtils.HASH_SEED;
+        hash = LangUtils.hashCode(hash, this.name);
+        hash = LangUtils.hashCode(hash, this.value);
+        return hash;
     }
-    */
+    
 }

Added: jakarta/httpclient/trunk/http-common/src/java/org/apache/http/util/LangUtils.java
URL: http://svn.apache.org/viewcvs/jakarta/httpclient/trunk/http-common/src/java/org/apache/http/util/LangUtils.java?view=auto&rev=154449
==============================================================================
--- jakarta/httpclient/trunk/http-common/src/java/org/apache/http/util/LangUtils.java (added)
+++ jakarta/httpclient/trunk/http-common/src/java/org/apache/http/util/LangUtils.java Sat Feb 19 12:33:45 2005
@@ -0,0 +1,78 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/util/ParameterParser.java,v 1.5 2004/05/13 04:01:22 mbecke Exp $
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 1999-2004 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.util;
+
+/**
+ * A set of utility methods to help produce consistent Object#equals(Object) and
+ * Object#hashCode methods.
+ *  
+ * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
+ * 
+ * @since 4.0
+ */
+public class LangUtils {
+    
+    public static int HASH_SEED = 17;
+    public static int HASH_OFFSET = 37;
+    
+    private LangUtils() {
+        super();
+    }
+
+    public static int hashCode(final int seed, final int hashcode) {
+        return seed * HASH_OFFSET + hashcode;
+    }
+
+    public static int hashCode(final int seed, final Object obj) {
+        return hashCode(seed, obj != null ? obj.hashCode() : 0);
+    }
+    
+    public static boolean equals(final Object obj1, final Object obj2) {
+        return obj1 == null ? obj2 == null : obj1.equals(obj2);
+    }
+
+    public static boolean equals(final Object[] a1, final Object[] a2) {
+        if (a1 == null) {
+            if (a2 != null) {
+                return false;
+            }
+        } else {
+            if (a2 != null && a1.length == a2.length) {
+                for (int i = 0; i < a1.length; i++) {
+                    if (!equals(a1[i], a2[i])) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+    
+}