This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.common.utils;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.commons.lang.StringUtils;
023
024import java.util.regex.Matcher;
025import java.util.regex.Pattern;
026
027/**
028 * Version utility methods.
029 */
030public class VersionUtil
031{
032    /**
033     * These are the version patterns found in the filenames of the various artifact's versions IDs.
034     * These patterns are all tackling lowercase version IDs.
035     */
036    private static final String versionPatterns[] =
037        new String[]{ "([0-9][_.0-9a-z]*)", "(snapshot)", "(g?[_.0-9ab]*(pre|rc|g|m)[_.0-9]*)", "(dev[_.0-9]*)",
038            "(alpha[_.0-9]*)", "(beta[_.0-9]*)", "(rc[_.0-9]*)",
039//        "(test[_.0-9]*)", -- omitted for MRM-681, can be reinstated as part of MRM-712
040            "(debug[_.0-9]*)", "(unofficial[_.0-9]*)", "(current)", "(latest)", "(fcs)", "(release[_.0-9]*)",
041            "(nightly)", "(final)", "(incubating)", "(incubator)", "([ab][_.0-9]+)" };
042
043    public static final String SNAPSHOT = "SNAPSHOT";
044
045    public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}\\.[0-9]{6})-([0-9]+)$" );
046
047    public static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" );
048
049    public static final Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT );
050
051    private static final Pattern VERSION_MEGA_PATTERN =
052        Pattern.compile( StringUtils.join( versionPatterns, '|' ), Pattern.CASE_INSENSITIVE );
053
054    /**
055     * <p>
056     * Tests if the unknown string contains elements that identify it as a version string (or not).
057     * </p>
058     *
059     * <p>
060     * The algorithm tests each part of the string that is delimited by a '-' (dash) character.
061     * If 75% or more of the sections are identified as 'version' strings, the result is
062     * determined to be of a high probability to be version identifier string.
063     * </p>
064     *
065     * @param unknown the unknown string to test.
066     * @return true if the unknown string is likely a version string.
067     */
068    public static boolean isVersion( String unknown )
069    {
070        String versionParts[] = StringUtils.split( unknown, '-' );
071
072        Matcher mat;
073
074        int countValidParts = 0;
075
076        for ( int i = 0; i < versionParts.length; i++ )
077        {
078            String part = versionParts[i];
079            mat = VERSION_MEGA_PATTERN.matcher( part );
080
081            if ( mat.matches() )
082            {
083                if ( i == 0 ) // loosen rule to return true if first token matches
084                {
085                    return true;
086                }
087                countValidParts++;
088            }
089        }
090
091        /* Calculate version probability as true if 3/4's of the input string has pieces of
092         * of known version identifier strings.
093         */
094        int threshold = (int) Math.floor( Math.max( (double) 1.0, (double) ( versionParts.length * 0.75 ) ) );
095
096        return ( countValidParts >= threshold );
097    }
098
099    /**
100     * <p>
101     * Tests if the identifier is a known simple version keyword.
102     * </p>
103     *
104     * <p>
105     * This method is different from {@link #isVersion(String)} in that it tests the whole input string in
106     * one go as a simple identifier. (eg "alpha", "1.0", "beta", "debug", "latest", "rc#", etc...)
107     * </p>
108     *
109     * @param identifier the identifier to test.
110     * @return true if the unknown string is likely a version string.
111     */
112    public static boolean isSimpleVersionKeyword( String identifier )
113    {
114        Matcher mat = VERSION_MEGA_PATTERN.matcher( identifier );
115
116        return mat.matches();
117    }
118
119    public static boolean isSnapshot( String version )
120    {
121        Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
122        if ( m.matches() )
123        {
124            return true;
125        }
126        else
127        {
128            return isGenericSnapshot( version );
129        }
130    }
131
132    public static String getBaseVersion( String version )
133    {
134        Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
135        if ( m.matches() )
136        {
137            return m.group( 1 ) + "-" + SNAPSHOT;
138        }
139        else
140        {
141            return version;
142        }
143    }
144
145    /**
146     * <p>
147     * Get the release version of the snapshot version.
148     * </p>
149     * 
150     * <p>
151     * If snapshot version is 1.0-SNAPSHOT, then release version would be 1.0
152     * And if snapshot version is 1.0-20070113.163208-1.jar, then release version would still be 1.0
153     * </p>
154     *
155     * @param snapshotVersion snapshot version
156     * @return release version
157     */
158    public static String getReleaseVersion( String snapshotVersion )
159    {
160        Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( snapshotVersion );
161
162        if ( isGenericSnapshot( snapshotVersion ) )
163        {
164            m = GENERIC_SNAPSHOT_PATTERN.matcher( snapshotVersion );
165        }
166
167        if ( m.matches() )
168        {
169            return m.group( 1 );
170        }
171        else
172        {
173            return snapshotVersion;
174        }
175    }
176
177    public static boolean isUniqueSnapshot( String version )
178    {
179        Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
180        return m.matches();
181    }
182
183    public static boolean isGenericSnapshot( String version )
184    {
185        return version.endsWith( SNAPSHOT );
186    }
187
188    public static String getVersionFromGenericSnapshot( String version )
189    {
190        Matcher m = GENERIC_SNAPSHOT_PATTERN.matcher( version );
191        if ( m.matches() )
192        {
193            return m.group( 1 );
194        }
195        return version;
196    }
197}