You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ba...@apache.org on 2002/02/21 06:04:01 UTC

cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java NumericStringComparator.java PackageNameComparator.java ReverseComparator.java SoundexComparator.java UrlComparator.java package.html

bayard      02/02/20 21:04:01

  Added:       util/src/java/org/apache/commons/util/compare
                        ComparableComparator.java
                        NumericStringComparator.java
                        PackageNameComparator.java ReverseComparator.java
                        SoundexComparator.java UrlComparator.java
                        package.html
  Log:
  Added initial set of comparators, plus a package.html explaining
  the package very tersely.
  
  Comparable: This is very useful when you want to code generically.
  It lets you not worry about whether the object is Comparable or not,
  instead you just blindly use a Comparator and Collections.sort.
  
  NumericString: Sorts words alphabetically, but any numbers in those words
  are sorted numerically. So 10 1st Street will sort before 10 2nd Street and
  after 2 1st Street.
  
  PackageName: Sorts java package names into a standard way.
  
  Reverse: Very useful. Flips any other comparator around. Great way to
  implement those lists where the user clicks the sort button again
  to reverse sort it.
  
  Soundex: Sort on the soundex. No idea if this has any use tbh.
  
  Url: Sorts urls. Reorders the importance of hosts, protocols, paths and
  ports from the standard string based sorting.
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/ComparableComparator.java
  
  Index: ComparableComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  import java.lang.Comparable;
  
  /**
   * A Comparator that compares Comparable objects.
   *
   * @author bayard@generationjava.com
   * @version $Id: ComparableComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class ComparableComparator implements Comparator {
  
      public ComparableComparator() {
      }
  
      public int compare(Object o1, Object o2) {
          if(o1 instanceof Comparable) {
              return ((Comparable)o1).compareTo(o2);
          }
          return 0;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/NumericStringComparator.java
  
  Index: NumericStringComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  
  /**
   * A Comparator which deals with alphabet characters 'naturally', but 
   * deals with numerics numerically. Leading 0's are ignored numerically,
   * but do come into play if the number is equal. Thus aaa119yyyy comes before 
   * aaa0119xxxx regardless of x or y.
   *
   * The comparison should be very performant as it only ever deals with 
   * issues at a character level and never tries to consider the 
   * numerics as numbers.
   *
   * @author bayard@generationjava.com
   * @version $Id: NumericStringComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class NumericStringComparator implements Comparator {
  
      public NumericStringComparator() {
      }
  
      public int compare(Object o1, Object o2) {
          if(o1 == null) {
              return 1;
          } else
          if(o2 == null) {
              return -1;
          }
  
          String s1 = o1.toString();
          String s2 = o2.toString();
  
          // find the first digit.
          int idx1 = getFirstDigitIndex(s1);
          int idx2 = getFirstDigitIndex(s2);
  
          if( ( idx1 == -1 )   || 
              ( idx2 == -1 ) ||
              ( !s1.substring(0,idx1).equals(s2.substring(0,idx2)) )
            )
          {
              return s1.compareTo(s2);
          }
  
          // find the last digit
          int edx1 = getLastDigitIndex(s1, idx1);
          int edx2 = getLastDigitIndex(s2, idx2);
  
          String sub1 = null;
          String sub2 = null;
  
          if(edx1 == -1) {
              sub1 = s1.substring(idx1);
          } else {
              sub1 = s1.substring(idx1, edx1);
          }
  
          if(edx2 == -1) {
              sub2 = s2.substring(idx2);
          } else {
              sub2 = s2.substring(idx2, edx2);
          }
  
          // deal with zeros at start of each number
          int zero1 = countZeroes(sub1);
          int zero2 = countZeroes(sub2);
  
          sub1 = sub1.substring(zero1);
          sub2 = sub2.substring(zero2);
  
          // if equal, then recurse with the rest of the string
          // need to deal with zeroes so that 00119 appears after 119
          if(sub1.equals(sub2)) {
              int ret = 0;
              if(zero1 > zero2) {
                  ret = 1;
              } else
              if(zero1 < zero2) {
                  ret = -1;
              }
              if(edx1 != -1) {
                  int comp = compare(s1.substring(edx1), s2.substring(edx2));
                  if(comp != 0) {
                      ret = comp;
                  }
              }
              return ret;
          } else {
              // if a numerical string is smaller in length than another
              // then it must be less. 
              if(sub1.length() != sub2.length()) {
                  return ( sub1.length() < sub2.length() ) ? -1 : 1;
              }
          }
  
  
          // now we get to do the string based numerical thing :)
          // going to assume that the individual character for the 
          // number has the right order. ie) '9' > '0'
          // possibly bad in i18n.
          char[] chr1 = sub1.toCharArray();
          char[] chr2 = sub2.toCharArray();
  
          int sz = chr1.length;
          for(int i=0; i<sz; i++) {
              // this should give better speed
              if(chr1[i] != chr2[i]) {
                  return (chr1[i] < chr2[i]) ? -1 : 1;
              }
          }
  
          return 0;
      }
  
      /// TODO: Consider moving these to a lang helper class.
      private int getFirstDigitIndex(String str) {
          return getFirstDigitIndex(str, 0);
      }
      private int getFirstDigitIndex(String str, int start) {
          return getFirstDigitIndex(str.toCharArray(), start);
      }
      // Get the index of the first digit (number) in the array 
      // of characters, starting at the specified digit.
      private int getFirstDigitIndex(char[] chrs, int start) {
          int sz = chrs.length;
  
          for(int i=start; i<sz; i++) {
              if(Character.isDigit(chrs[i])) {
                  return i;
              }
          }
  
          return -1;
      }
  
      private int getLastDigitIndex(String str, int start) {
          return getLastDigitIndex(str.toCharArray(), start);
      }
      // Get the index of the digit at the end of a collection 
      // of digit characters in a character array, starting 
      // at the provided start index.
      private int getLastDigitIndex(char[] chrs, int start) {
          int sz = chrs.length;
  
          for(int i=start; i<sz; i++) {
              if(!Character.isDigit(chrs[i])) {
                  return i;
              }
          }
  
          return -1;
      }
  
      public int countZeroes(String str) {
          int count = 0;
  
          // assuming str is small...
          for(int i=0; i<str.length(); i++) {
              if(str.charAt(i) == '0') {
                  count++;
              } else {
                  break;
              }
          }
  
          return count;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/PackageNameComparator.java
  
  Index: PackageNameComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  
  /**
   * Sorts java package names.
   * Packages are grouped into java, javax, and other.
   * Inside each one they are alphabetical.
   *
   * @author bayard@generationjava.com
   * @version $Id: PackageNameComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class PackageNameComparator implements Comparator {
  
      static private int JAVA = 1;
      static private int JAVAX = 2;
      static private int OTHER = 3;
  
      public int compare(Object obj1, Object obj2) {
          if( (obj1 instanceof String) && (obj2 instanceof String) ) {
              String str1 = (String)obj1;
              String str2 = (String)obj2;
              int type1 = getType(str1);
              int type2 = getType(str2);
              
              if(type1 == JAVA) {
                  if(type2 == JAVA) {
                      str1 = str1.substring(4);
                      str2 = str2.substring(4);
                  } else {
                      return -1;
                  }
              } else
              if(type2 == JAVA) {
                  return 1;
              } else
              if(type1 == JAVAX) {
                  if(type2 == JAVAX) {
                      str1 = str1.substring(5);
                      str2 = str2.substring(5);
                  } else {
                      return -1;
                  }
              } else
              if(type2 == JAVAX) {
                  return 1;
              }
  
              return str1.compareTo(str2);
          } else {
              return 0;
          }
      }
  
      private static int getType(String str) {
          if(str.startsWith("java")) {
              if(str.charAt(4) == '.') {
                  return JAVA;
              } else 
              if( (str.charAt(4) == 'x') && (str.charAt(5) == '.') ) {
                  return JAVAX;
              }            
          }
          return OTHER;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/ReverseComparator.java
  
  Index: ReverseComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  
  /**
   * Reverses the order of another comparator.
   *
   * @author bayard@generationjava.com
   * @version $Id: ReverseComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class ReverseComparator implements Comparator {
  
      private Comparator comparator;
  
      /**
       * Creates a reverse comparator that will invert any list.
       */
      public ReverseComparator() {
      }
  
      /**
       * Creates a reverse comparator that inverts the comparison 
       * of the passed in comparator.
       */
      public ReverseComparator(Comparator comparator) {
          this.comparator = comparator;
      }
  
      public int compare(Object o1, Object o2) {
          if(comparator == null) {
              return -1;
          } else {
              return -1*comparator.compare(o1,o2);
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/SoundexComparator.java
  
  Index: SoundexComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  
  import org.apache.commons.util.Soundex;
  
  /**
   * Compare using the Soundex algorithm.
   *
   * @author bayard@generationjava.com
   * @version $Id: SoundexComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class SoundexComparator implements Comparator {
  
      private Soundex soundex;
  
      /**
       * Use the default soundex algorithm, US_ENGLISH.
       */
      public SoundexComparator() {
          this(Soundex.US_ENGLISH);
      }
  
      /**
       * Use the provided soundex algorithm.
       */
      public SoundexComparator(Soundex sx) {
          this.soundex = sx;
      }
  
      public int compare(Object o1, Object o2) {
          String s1 = soundex.soundex(o1.toString());
          String s2 = soundex.soundex(o2.toString());
          return s1.compareTo(s2);
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/UrlComparator.java
  
  Index: UrlComparator.java
  ===================================================================
  package org.apache.commons.util.compare;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * 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/>.
   */
  
  import java.util.Comparator;
  import java.net.URL;
  
  /**
   * Compares URLs. Initially ignores protocol, so 
   * ftp://sun.com and * http://sun.com will compare 
   * near each other. Also pays attention to ports last, so 
   * http://www:8080/index.html and http://www/index.html 
   * will sort near each other.
   *
   * @author bayard@generationjava.com
   * @version $Id: UrlComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
   */
  public class UrlComparator implements Comparator {
  
      public UrlComparator() {
      }
  
      public int compare(Object o1, Object o2) {
          if( (o1 instanceof URL) && (o2 instanceof URL)) {
              URL u1 = (URL)o1;
              URL u2 = (URL)o2;
              int ret = 0;
  
              ret = u1.getHost().compareTo(u2.getHost());
              if(ret != 0) {
                  return ret;
              }
  
              ret = u1.getPath().compareTo(u2.getPath());
              if(ret != 0) {
                  return ret;
              }
  
              ret = u1.getProtocol().compareTo(u2.getProtocol());
              if(ret != 0) {
                  return ret;
              }
  
              if(u1.getPort() < u2.getPort()) {
                  return -1;
              } else
              if(u1.getPort() < u2.getPort()) {
                  return 1;
              }
  
          }
  
          return 0;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare/package.html
  
  Index: package.html
  ===================================================================
  <html>
  <body>
  <p>Generic Comparator classes. Most often used with java.util.Collections.sort</p>
  </body>
  </html>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by ba...@generationjava.com.
> IllegalArgumentException is a bit weird here in this context.  While I
> agree it it probably the most appropriate exception when the arguments
> aren't comparable, the Comparator javadoc declares it throws a
> ClassCastException "if the arguments' types prevent it from being
> compared".  I'm ok with the IllegalArgument, but you should still add
> javadoc to declare it since it isn't declared in the Comparator's API
> docs.

Ack. You're right. Change made to ClassCastException.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by "Michael A. Smith" <mi...@iammichael.org>.
On Thu, 21 Feb 2002 bayard@generationjava.com wrote:
> And so I had no reason not to add it :) See latest cvs commit message. The
> only change I made in your code is that I return result1 rather than -1 or
> 1. Maintaining the size might be important I guess.

IllegalArgumentException is a bit weird here in this context.  While I
agree it it probably the most appropriate exception when the arguments
aren't comparable, the Comparator javadoc declares it throws a
ClassCastException "if the arguments' types prevent it from being
compared".  I'm ok with the IllegalArgument, but you should still add
javadoc to declare it since it isn't declared in the Comparator's API 
docs.

As for returning result1 rather than 1 or -1, it doesn't matter to me.  

regards,
michael


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by ba...@generationjava.com.

On Thu, 21 Feb 2002 bayard@generationjava.com wrote:

> I've also not gone for your ultra paranoid option. It is a good idea
> though I believe.

And so I had no reason not to add it :) See latest cvs commit message. The
only change I made in your code is that I return result1 rather than -1 or
1. Maintaining the size might be important I guess.

Thanks for the pointers,

Bay


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by ba...@generationjava.com.
Let me know how that latest change looks Michael. I took a slightly longer
route, mainly because the medium of email gave me time to sit and twiddle
my thumbs.

I've also not gone for your ultra paranoid option. It is a good idea
though I believe.

Bay

On Wed, 20 Feb 2002, Michael A. Smith wrote:

> On Thu, 21 Feb 2002 bayard@generationjava.com wrote:
> > Sounds valid. As far as the contract goes, how about if a
> > class-cast-exception is thrown in both cases, or if another 'illegal
> > input' decision is taken, ie) returning 0.
>
> Yup.  I'd be fine with:
>
>   int compare(Object o1, Object o2) {
>     return ((Comparable)o1).compareTo((Comparable)o2);
>   }
>
> With that, you're placing the burden on the comparable object to ensure it
> implements the compareTo method with regards to the Comparable contract,
> rather than keeping the burden of the Comparator contract.  Then, it's not
> your problem.  :)
>
> If you really want to be paranoid, you could do both and make sure they
> return inverses:
>
>   int compare(Object o1, Object o2) {
>     int result1 = ((Comparable)o1).compareTo(o2);
>     int result2 = ((Comparable)o2).compareTo(o1);
>
>     if(result1 == 0 && result2 == 0) return 0;
>     if(result1 < 0 && result2 > 0) return -1;
>     if(result1 > 0 && result2 < 0) return 1;
>
>     // results inconsistent
>     throw new ClassCastException("o1 not comparable to o2");
>   }
>
> that may be a bit too paranoid though.
>
> > As for its use, consider the following code:
>
> yeah, that's how I figured it would be used.  :)
>
> regards,
> Michael
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by "Michael A. Smith" <mi...@iammichael.org>.
On Thu, 21 Feb 2002 bayard@generationjava.com wrote:
> Sounds valid. As far as the contract goes, how about if a
> class-cast-exception is thrown in both cases, or if another 'illegal
> input' decision is taken, ie) returning 0.

Yup.  I'd be fine with:

  int compare(Object o1, Object o2) {
    return ((Comparable)o1).compareTo((Comparable)o2);
  }

With that, you're placing the burden on the comparable object to ensure it 
implements the compareTo method with regards to the Comparable contract, 
rather than keeping the burden of the Comparator contract.  Then, it's not 
your problem.  :)

If you really want to be paranoid, you could do both and make sure they 
return inverses:

  int compare(Object o1, Object o2) {
    int result1 = ((Comparable)o1).compareTo(o2);
    int result2 = ((Comparable)o2).compareTo(o1);

    if(result1 == 0 && result2 == 0) return 0;
    if(result1 < 0 && result2 > 0) return -1;
    if(result1 > 0 && result2 < 0) return 1;
 
    // results inconsistent
    throw new ClassCastException("o1 not comparable to o2");
  }

that may be a bit too paranoid though.

> As for its use, consider the following code:

yeah, that's how I figured it would be used.  :)

regards,
Michael



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java

Posted by ba...@generationjava.com.

Sounds valid. As far as the contract goes, how about if a
class-cast-exception is thrown in both cases, or if another 'illegal
input' decision is taken, ie) returning 0.

As for its use, consider the following code:

        Comparator cc = new ComparableComparator();
        registry.register(java.lang.Comparable.class, cc);

        // Do all these comparables to increase lookup speed
        registry.register(java.lang.String.class, cc);
        registry.register(java.lang.Number.class, cc);
        registry.register(java.io.File.class, cc);
        registry.register(java.lang.Character.class, cc);
        registry.register(java.lang.Byte.class, cc);

        registry.register(java.net.URL.class, new UrlComparator());
        registry.register(org.apache.commons.mail.Email.class, new EmailComparator());
        registry.register(com.oreilly.book.Isbn.class, new IsbnComparator());

This is an excerpt from a class I hope to add soon, ObjectComparator. This
comparator handles comparison on any object (or attempts to). Making the
Comparable interface special makes it impossible to override the
comparator for java.lang.String later with NumericStringComparator.

The next step is BeanComparator. This one is adorable [opinion]. It allows
me to have a Person object with address object which has a state field. I
can then sort by "address.state" on my collection of Person's, and not
even worry about the type if it's one that ObjectComparator
(BeanComparator's default internal comparator) can easily handle.

"address.line[3]", "address[home].state" and just "[1]" are also legal.
The latter sorts on the 1th index of a collection of arrays. My reason for
holding this back at the moment is that it relies on my own
bean-reflection library and I believe there's already one in jakarta.

Apologies if that all doesn't seem cool. It's one of those components that
got written as an itch, and then suddenly started to pay back many times.

Please let me know if making it throw an illegalargumentexception or some
such in both cases would be a good enough fix.

Bay

> This comparator does not implement the contract in Comparable, which
> requires the inverse comparison to have the inverse result.  That is,
>
> sign(compare(o1, o2)) = -(sign(compare(o2, o1)))
>
> which has a corollary that compare(x,y) should only throw an exception if
> and only it compare(y,x) throws an exception.
>
> Don't see what I mean?  consider o1 implements Comparable, and o2 does
> not.  compare(o1, o2) will probably throw a ClassCastException because the
> implementation of compareTo in o1 will not be able to convert o2 to an
> object suitable for comparing.  The reverse, compare(o2, o1) will return
> 0.
>
> I really don't see the need for this comparator in the first place, but at
> the very minimum, the fact that this comparator violates the Comparator
> contract should be documented and made obvious to any user of the class.
> Without such documentation, I will -1 its inclusion.
>
> regards,
> michael
>
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-commons-sandbox/util/src/java/org/apache/commons/util/compare ComparableComparator.java NumericStringComparator.java PackageNameComparator.java ReverseComparator.java SoundexCompar

Posted by "Michael A. Smith" <mi...@iammichael.org>.
On 21 Feb 2002 bayard@apache.org wrote:
>   Index: ComparableComparator.java
>   ===================================================================
>   package org.apache.commons.util.compare;
[snip]
>   /**
>    * A Comparator that compares Comparable objects.
>    *
>    * @author bayard@generationjava.com
>    * @version $Id: ComparableComparator.java,v 1.1 2002/02/21 05:04:01 bayard Exp $
>    */
>   public class ComparableComparator implements Comparator {
>   
>       public ComparableComparator() {
>       }
>   
>       public int compare(Object o1, Object o2) {
>           if(o1 instanceof Comparable) {
>               return ((Comparable)o1).compareTo(o2);
>           }
>           return 0;
>       }
>   
>   }

This comparator does not implement the contract in Comparable, which 
requires the inverse comparison to have the inverse result.  That is, 

sign(compare(o1, o2)) = -(sign(compare(o2, o1)))

which has a corollary that compare(x,y) should only throw an exception if
and only it compare(y,x) throws an exception.  

Don't see what I mean?  consider o1 implements Comparable, and o2 does 
not.  compare(o1, o2) will probably throw a ClassCastException because the 
implementation of compareTo in o1 will not be able to convert o2 to an 
object suitable for comparing.  The reverse, compare(o2, o1) will return 
0.  

I really don't see the need for this comparator in the first place, but at
the very minimum, the fact that this comparator violates the Comparator
contract should be documented and made obvious to any user of the class.  
Without such documentation, I will -1 its inclusion.

regards,
michael



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>