1package org.apache.archiva.common.utils;
23/*4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122import org.apache.commons.lang.StringUtils;
2324import java.util.regex.Matcher;
25import java.util.regex.Pattern;
2627/**28 * Version utility methods.29 */30publicclassVersionUtil31 {
32/**33 * These are the version patterns found in the filenames of the various artifact's versions IDs.34 * These patterns are all tackling lowercase version IDs.35 */36privatestaticfinal String versionPatterns[] =
37new String[]{ "([0-9][_.0-9a-z]*)", "(snapshot)", "(g?[_.0-9ab]*(pre|rc|g|m)[_.0-9]*)", "(dev[_.0-9]*)",
38"(alpha[_.0-9]*)", "(beta[_.0-9]*)", "(rc[_.0-9]*)",
39// "(test[_.0-9]*)", -- omitted for MRM-681, can be reinstated as part of MRM-71240"(debug[_.0-9]*)", "(unofficial[_.0-9]*)", "(current)", "(latest)", "(fcs)", "(release[_.0-9]*)",
41"(nightly)", "(final)", "(incubating)", "(incubator)", "([ab][_.0-9]+)" };
4243publicstaticfinal String SNAPSHOT = "SNAPSHOT";
4445publicstaticfinal Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}\\.[0-9]{6})-([0-9]+)$" );
4647publicstaticfinal Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" );
4849publicstaticfinal Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT );
5051privatestaticfinal Pattern VERSION_MEGA_PATTERN =
52 Pattern.compile( StringUtils.join( versionPatterns, '|' ), Pattern.CASE_INSENSITIVE );
5354/**55 * <p>56 * Tests if the unknown string contains elements that identify it as a version string (or not).57 * </p>58 *59 * <p>60 * The algorithm tests each part of the string that is delimited by a '-' (dash) character.61 * If 75% or more of the sections are identified as 'version' strings, the result is62 * determined to be of a high probability to be version identifier string.63 * </p>64 *65 * @param unknown the unknown string to test.66 * @return true if the unknown string is likely a version string.67 */68publicstaticboolean isVersion( String unknown )
69 {
70 String versionParts[] = StringUtils.split( unknown, '-' );
7172 Matcher mat;
7374int countValidParts = 0;
7576for ( int i = 0; i < versionParts.length; i++ )
77 {
78 String part = versionParts[i];
79 mat = VERSION_MEGA_PATTERN.matcher( part );
8081if ( mat.matches() )
82 {
83if ( i == 0 ) // loosen rule to return true if first token matches84 {
85returntrue;
86 }
87 countValidParts++;
88 }
89 }
9091/* Calculate version probability as true if 3/4's of the input string has pieces of92 * of known version identifier strings.93 */94int threshold = (int) Math.floor( Math.max( (double) 1.0, (double) ( versionParts.length * 0.75 ) ) );
9596return ( countValidParts >= threshold );
97 }
9899/**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 in106 * 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 */112publicstaticboolean isSimpleVersionKeyword( String identifier )
113 {
114 Matcher mat = VERSION_MEGA_PATTERN.matcher( identifier );
115116return mat.matches();
117 }
118119publicstaticboolean isSnapshot( String version )
120 {
121 Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
122if ( m.matches() )
123 {
124returntrue;
125 }
126else127 {
128return isGenericSnapshot( version );
129 }
130 }
131132publicstatic String getBaseVersion( String version )
133 {
134 Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
135if ( m.matches() )
136 {
137return m.group( 1 ) + "-" + SNAPSHOT;
138 }
139else140 {
141return version;
142 }
143 }
144145/**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.0152 * And if snapshot version is 1.0-20070113.163208-1.jar, then release version would still be 1.0153 * </p>154 *155 * @param snapshotVersion snapshot version156 * @return release version157 */158publicstatic String getReleaseVersion( String snapshotVersion )
159 {
160 Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( snapshotVersion );
161162if ( isGenericSnapshot( snapshotVersion ) )
163 {
164 m = GENERIC_SNAPSHOT_PATTERN.matcher( snapshotVersion );
165 }
166167if ( m.matches() )
168 {
169return m.group( 1 );
170 }
171else172 {
173return snapshotVersion;
174 }
175 }
176177publicstaticboolean isUniqueSnapshot( String version )
178 {
179 Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
180return m.matches();
181 }
182183publicstaticboolean isGenericSnapshot( String version )
184 {
185return version.endsWith( SNAPSHOT );
186 }
187188publicstatic String getVersionFromGenericSnapshot( String version )
189 {
190 Matcher m = GENERIC_SNAPSHOT_PATTERN.matcher( version );
191if ( m.matches() )
192 {
193return m.group( 1 );
194 }
195return version;
196 }
197 }