archiva-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From joak...@apache.org
Subject svn commit: r547259 - in /maven/archiva/trunk/archiva-base/archiva-common/src: main/java/org/apache/maven/archiva/common/artifact/ main/java/org/apache/maven/archiva/common/utils/ test/java/org/apache/maven/archiva/common/utils/
Date Thu, 14 Jun 2007 14:41:20 GMT
Author: joakime
Date: Thu Jun 14 07:41:19 2007
New Revision: 547259

URL: http://svn.apache.org/viewvc?view=rev&rev=547259
Log:
Creating VersionComparator for doing logical sorts of Lists of versions.

Added:
    maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
  (with props)
    maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
  (with props)
Removed:
    maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/artifact/

Added: maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java?view=auto&rev=547259
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
(added)
+++ maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
Thu Jun 14 07:41:19 2007
@@ -0,0 +1,271 @@
+package org.apache.maven.archiva.common.utils;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * VersionComparator - compare the parts of two version strings.
+ * 
+ * Technique.
+ * 
+ *  * Split the version strings into parts by splitting on <code>"-._"</code>
first, then breaking apart words from numbers.
+ * 
+ * <code>
+ *   "1.0"         = "1", "0"
+ *   "1.0-alpha-1" = "1", "0", "alpha", "1"
+ *   "2.0-rc2"     = "2", "0", "rc", "2"
+ *   "1.3-m2"      = "1", "3", "m", "3"
+ * </code>
+ * 
+ * compare each part individually, and when they do not match, perform the following test.
+ * 
+ * Numbers are calculated per normal comparison rules.
+ * Words that are part of the "special word list" will be treated as their index within that
heirarchy.
+ * Words that cannot be identified as special, are treated using normal case-insensitive
comparison rules.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class VersionComparator
+    implements Comparator
+{
+    private static Comparator INSTANCE = new VersionComparator();
+
+    private List specialWords;
+
+    public VersionComparator()
+    {
+        specialWords = new ArrayList();
+
+        // ids that refer to LATEST
+        specialWords.add( "final" );
+        specialWords.add( "release" );
+        specialWords.add( "current" );
+        specialWords.add( "latest" );
+        specialWords.add( "g" );
+        specialWords.add( "gold" );
+        specialWords.add( "fcs" );
+
+        // ids that are for a release cycle.
+        specialWords.add( "a" );
+        specialWords.add( "alpha" );
+        specialWords.add( "b" );
+        specialWords.add( "beta" );
+        specialWords.add( "pre" );
+        specialWords.add( "rc" );
+        specialWords.add( "m" );
+        specialWords.add( "milestone" );
+
+        // ids that are for dev / debug cycles.
+        specialWords.add( "dev" );
+        specialWords.add( "test" );
+        specialWords.add( "debug" );
+        specialWords.add( "unofficial" );
+        specialWords.add( "nightly" );
+        specialWords.add( "incubating" );
+        specialWords.add( "incubator" );
+        specialWords.add( "snapshot" );
+    }
+
+    public static Comparator getInstance()
+    {
+        return INSTANCE;
+    }
+
+    public int compare( Object o1, Object o2 )
+    {
+        if ( o1 == null && o2 == null )
+        {
+            return 0;
+        }
+
+        if ( o1 == null && o2 != null )
+        {
+            return 1;
+        }
+
+        if ( o1 != null && o2 == null )
+        {
+            return -1;
+        }
+
+        if ( ( o1 instanceof String ) && ( o2 instanceof String ) )
+        {
+            String s1 = ( (String) o1 );
+            String s2 = ( (String) o2 );
+
+            String parts1[] = toParts( s1 );
+            String parts2[] = toParts( s2 );
+
+            int diff;
+            int partLen = Math.max( parts1.length, parts2.length );
+            for ( int i = 0; i < partLen; i++ )
+            {
+                diff = comparePart( safePart( parts1, i ), safePart( parts2, i ) );
+                if ( diff != 0 )
+                {
+                    return diff;
+                }
+            }
+
+            diff = parts2.length - parts1.length;
+
+            if ( diff != 0 )
+            {
+                return diff;
+            }
+
+            return s1.compareToIgnoreCase( s2 );
+        }
+
+        return 0;
+    }
+
+    private String safePart( String parts[], int idx )
+    {
+        if ( idx < parts.length )
+        {
+            return parts[idx];
+        }
+
+        return "0";
+    }
+
+    private int comparePart( String s1, String s2 )
+    {
+        boolean is1Num = NumberUtils.isNumber( s1 );
+        boolean is2Num = NumberUtils.isNumber( s2 );
+
+        // (Special Case) Test for numbers both first.
+        if ( is1Num && is2Num )
+        {
+            int i1 = NumberUtils.toInt( s1 );
+            int i2 = NumberUtils.toInt( s2 );
+
+            return i1 - i2;
+        }
+
+        // Test for text both next.
+        if ( !is1Num && !is2Num )
+        {
+            int idx1 = specialWords.indexOf( s1.toLowerCase() );
+            int idx2 = specialWords.indexOf( s2.toLowerCase() );
+
+            // Only operate perform index based operation, if both strings
+            // are found in the specialWords index.
+            if ( ( idx1 >= 0 ) && ( idx2 >= 0 ) )
+            {
+                return idx1 - idx2;
+            }
+        }
+
+        // Comparing text to num
+        if ( !is1Num && is2Num )
+        {
+            return -1;
+        }
+
+        // Comparing num to text
+        if ( is1Num && !is2Num )
+        {
+            return 1;
+        }
+
+        // Return comparison of strings themselves.
+        return s1.compareToIgnoreCase( s2 );
+    }
+
+    public static String[] toParts( String version )
+    {
+        if ( StringUtils.isBlank( version ) )
+        {
+            return ArrayUtils.EMPTY_STRING_ARRAY;
+        }
+
+        final int modeOther = 0;
+        final int modeDigit = 1;
+        final int modeText = 2;
+
+        List parts = new ArrayList();
+        int len = version.length();
+        int i = 0;
+        int start = 0;
+        int mode = modeOther;
+
+        while ( i < len )
+        {
+            char c = version.charAt( i );
+
+            if ( Character.isDigit( c ) )
+            {
+                if ( mode != modeDigit )
+                {
+                    if ( mode != modeOther )
+                    {
+                        parts.add( version.substring( start, i ) );
+                    }
+                    mode = modeDigit;
+                    start = i;
+                }
+            }
+            else if ( Character.isLetter( c ) )
+            {
+                if ( mode != modeText )
+                {
+                    if ( mode != modeOther )
+                    {
+                        parts.add( version.substring( start, i ) );
+                    }
+                    mode = modeText;
+                    start = i;
+                }
+            }
+            else
+            {
+                // Other.
+                if ( mode != modeOther )
+                {
+                    if ( mode != modeOther )
+                    {
+                        parts.add( version.substring( start, i ) );
+                    }
+                    mode = modeOther;
+                }
+            }
+
+            i++;
+        }
+
+        // Add remainder
+        if ( mode != modeOther )
+        {
+            parts.add( version.substring( start, i ) );
+        }
+
+        return (String[]) parts.toArray( new String[parts.size()] );
+    }
+}

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionComparator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
URL: http://svn.apache.org/viewvc/maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java?view=auto&rev=547259
==============================================================================
--- maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
(added)
+++ maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
Thu Jun 14 07:41:19 2007
@@ -0,0 +1,99 @@
+package org.apache.maven.archiva.common.utils;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * VersionComparatorTest 
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class VersionComparatorTest
+    extends TestCase
+{
+    public void testComparator()
+    {
+        /* Sort order is oldest to newest */
+        
+        assertSort( new String[] { "1.0", "3.0", "2.0" }, new String[] { "1.0", "2.0", "3.0"
} );
+        assertSort( new String[] { "1.5", "1.2", "1.0" }, new String[] { "1.0", "1.2", "1.5"
} );
+
+        assertSort( new String[] { "1.5-SNAPSHOT", "1.2", "1.20" }, new String[] { "1.2",
"1.5-SNAPSHOT", "1.20" } );
+
+        assertSort( new String[] { "1.1", "1.0-SNAPSHOT", "1.1-m6", "1.1-rc1" }, new String[]
{
+            "1.0-SNAPSHOT",
+            "1.1-rc1",
+            "1.1-m6",
+            "1.1" } );
+        assertSort( new String[] { "1.1-m6", "1.0-SNAPSHOT", "1.1-rc1", "1.1" }, new String[]
{
+            "1.0-SNAPSHOT",
+            "1.1-rc1",
+            "1.1-m6",
+            "1.1" } );
+
+        assertSort( new String[] { "2.0.5", "2.0.4-SNAPSHOT", "2.0", "2.0-rc1" }, new String[]
{
+            "2.0-rc1",
+            "2.0",
+            "2.0.4-SNAPSHOT",
+            "2.0.5" } );
+
+        // TODO: write more unit tests.
+    }
+
+    private void assertSort( String[] rawVersions, String[] expectedSort )
+    {
+        List versions = new ArrayList();
+        versions.addAll( Arrays.asList( rawVersions ) );
+
+        Collections.sort( versions, VersionComparator.getInstance() );
+
+        assertEquals( "Versions.size()", expectedSort.length, versions.size() );
+        for ( int i = 0; i < expectedSort.length; i++ )
+        {
+            assertEquals( "Sorted Versions[" + i + "]", expectedSort[i], (String) versions.get(
i ) );
+        }
+    }
+
+    public void testToParts()
+    {
+        assertParts( "1.0", new String[] { "1", "0" } );
+        assertParts( "1.0-alpha-1", new String[] { "1", "0", "alpha", "1" } );
+        assertParts( "2.0-rc2", new String[] { "2", "0", "rc", "2" } );
+        assertParts( "1.3-m6", new String[] { "1", "3", "m", "6" } );
+    }
+
+    private void assertParts( String version, String[] expectedParts )
+    {
+        String actualParts[] = VersionComparator.toParts( version );
+        assertEquals( "Parts.length", expectedParts.length, actualParts.length );
+
+        for ( int i = 0; i < expectedParts.length; i++ )
+        {
+            assertEquals( "parts[" + i + "]", expectedParts[i], actualParts[i] );
+        }
+    }
+}

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: maven/archiva/trunk/archiva-base/archiva-common/src/test/java/org/apache/maven/archiva/common/utils/VersionComparatorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message