Index: Cookie.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java,v
retrieving revision 1.10
diff -c -r1.10 Cookie.java
*** Cookie.java	5 Jan 2002 11:15:59 -0000	1.10
--- Cookie.java	31 Jan 2002 18:34:57 -0000
***************
*** 68,73 ****
--- 68,78 ----
  import java.util.Enumeration;
  import java.util.Vector;
  import java.util.Locale;
+ import java.util.Set;
+ import java.util.TreeSet;
+ import java.util.Comparator;
+ import java.util.Iterator;
+ import java.text.RuleBasedCollator;
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.text.ParseException;
***************
*** 83,89 ****
   * @version $Revision: 1.10 $ $Date: 2002/01/05 11:15:59 $
   */
  
! public class Cookie extends NameValuePair implements Serializable {
  
      // ----------------------------------------------------------- Constructors
  
--- 88,94 ----
   * @version $Revision: 1.10 $ $Date: 2002/01/05 11:15:59 $
   */
  
! public class Cookie extends NameValuePair implements Serializable, Comparator {
  
      // ----------------------------------------------------------- Constructors
  
***************
*** 455,470 ****
      public static Header createCookieHeader(String domain, int port, String path, boolean secure, Date now, Cookie[] cookies) {
          boolean added = false;
          StringBuffer value = new StringBuffer("$Version=1");
!         // FIXME: cookies are supposed to be ordered with "better"
!         //        matches (more specific path) first
          for(int i=0;i<cookies.length;i++) {
!             if(cookies[i].matches(domain,port,path,secure,now)) {
!                 added = true;
!                 value.append(";");
!                 value.append(cookies[i].toExternalForm());
!             }
!         }
          if(added) {
              return new Header("Cookie", value.toString());
          } else {
              return null;
--- 460,485 ----
      public static Header createCookieHeader(String domain, int port, String path, boolean secure, Date now, Cookie[] cookies) {
          boolean added = false;
          StringBuffer value = new StringBuffer("$Version=1");
! 	if (cookies.length <= 0)
! 	{
! 	    return null;
! 	}
! 	Set addedCookies = new TreeSet(cookies[0]);
          for(int i=0;i<cookies.length;i++) {
! 	    if(cookies[i].matches(domain,port,path,secure,now)) {
! 		addedCookies.add(cookies[i]);
! 		added = true;
! 	    }
! 	}
          if(added) {
+ 	    for (Iterator itr = addedCookies.iterator(); itr.hasNext(); ) {
+ 		Cookie cookie = (Cookie)itr.next();
+ 		if(cookie.matches(domain,port,path,secure,now)) {
+ 		    value.append(";");
+ 		    value.append(cookie.toExternalForm());
+ 		}
+ 	    }
+ 
              return new Header("Cookie", value.toString());
          } else {
              return null;
***************
*** 472,477 ****
--- 487,525 ----
      }
  
      /**
+      * Compares two cookies to determine order for cookie header.  Most specific should be first.
+      * This method is implemented so a cookie can be used as a comparator for a SortedSet of 
+      * cookies. Specifically it's used above in the createCookieHeader method.
+      */
+     public int compare(Object o1, Object o2)
+ 	throws ClassCastException
+     {
+ 	if (!(o1 instanceof Cookie)) {
+ 	    throw new ClassCastException(o1.getClass().getName());
+ 	}
+ 	if (!(o2 instanceof Cookie)) {
+ 	    throw new ClassCastException(o2.getClass().getName());
+ 	}
+ 	Cookie c1 = (Cookie)o1;
+ 	Cookie c2 = (Cookie)o2;
+ 	if (c1.getDomain().equals(c2.getDomain())) {
+ 	    if (c1.getPath().equals(c2.getPath())) {
+ 		return 0; // same domain, same path
+ 	    }
+ 	    // same domain, different path	
+ 	    if (c1.getPath().length() == c2.getPath().length()) {
+ 		// same length path
+ 		return stringCollator.compare(c1.getPath(), c2.getPath());
+ 	    } else {
+ 		// different length paths
+ 		return c1.getPath().length() < c2.getPath().length() ? -1 : 1;
+ 	    }
+ 	}
+ 	// different domain
+ 	return stringCollator.compare(c1.getDomain(), c2.getDomain());
+     }
+ 
+     /**
       * Return a {@link String} representation of me.
       * @see #toExternalForm
       */
***************
*** 776,781 ****
--- 824,832 ----
  
     /** List of valid date formats for the "expires" cookie attribute. */
     private static final DateFormat[] expiryFormats = new DateFormat[4];
+ 
+    /** Collator for Cookie comparisons.  Could be replaced with references to specific Locales. */
+    private static final RuleBasedCollator stringCollator = (RuleBasedCollator)RuleBasedCollator.getInstance(new Locale("en", "US", ""));
  
     /** Static initializer for {@link #expiryFormats} constant. */
     static {
