content: package org.apache.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.lang3.StringUtils;
  
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  /**
   * Version utility methods.
   */
  public class VersionUtil
  {
      /**
       * These are the version patterns found in the filenames of the various artifact's versions IDs.
       * These patterns are all tackling lowercase version IDs.
       */
      private static final String versionPatterns[] =
          new String[]{ "([0-9][_.0-9a-z]*)", "(snapshot)", "(g?[_.0-9ab]*(pre|rc|g|m)[_.0-9]*)", "(dev[_.0-9]*)",
              "(alpha[_.0-9]*)", "(beta[_.0-9]*)", "(rc[_.0-9]*)",
  //        "(test[_.0-9]*)", -- omitted for MRM-681, can be reinstated as part of MRM-712
              "(debug[_.0-9]*)", "(unofficial[_.0-9]*)", "(current)", "(latest)", "(fcs)", "(release[_.0-9]*)",
              "(nightly)", "(final)", "(incubating)", "(incubator)", "([ab][_.0-9]+)" };
  
      public static final String SNAPSHOT = "SNAPSHOT";
  
      public static final Pattern UNIQUE_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}\\.[0-9]{6})-([0-9]+)$" );
  
      public static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "^([0-9]{8})\\.([0-9]{6})$" );
  
      public static final Pattern GENERIC_SNAPSHOT_PATTERN = Pattern.compile( "^(.*)-" + SNAPSHOT );
  
      private static final Pattern VERSION_MEGA_PATTERN =
          Pattern.compile( StringUtils.join( versionPatterns, '|' ), Pattern.CASE_INSENSITIVE );
  
      /**
       * <p>
       * Tests if the unknown string contains elements that identify it as a version string (or not).
       * </p>
       *
       * <p>
       * The algorithm tests each part of the string that is delimited by a '-' (dash) character.
       * If 75% or more of the sections are identified as 'version' strings, the result is
       * determined to be of a high probability to be version identifier string.
       * </p>
       *
       * @param unknown the unknown string to test.
       * @return true if the unknown string is likely a version string.
       */
      public static boolean isVersion( String unknown )
      {
          String versionParts[] = StringUtils.split( unknown, '-' );
  
          Matcher mat;
  
          int countValidParts = 0;
  
          for ( int i = 0; i < versionParts.length; i++ )
          {
              String part = versionParts[i];
              mat = VERSION_MEGA_PATTERN.matcher( part );
  
              if ( mat.matches() )
              {
                  if ( i == 0 ) // loosen rule to return true if first token matches
                  {
                      return true;
                  }
                  countValidParts++;
              }
          }
  
          /* Calculate version probability as true if 3/4's of the input string has pieces of
           * of known version identifier strings.
           */
          int threshold = (int) Math.floor( Math.max( (double) 1.0, (double) ( versionParts.length * 0.75 ) ) );
  
          return ( countValidParts >= threshold );
      }
  
      /**
       * <p>
       * Tests if the identifier is a known simple version keyword.
       * </p>
       *
       * <p>
       * This method is different from {@link #isVersion(String)} in that it tests the whole input string in
       * one go as a simple identifier. (eg "alpha", "1.0", "beta", "debug", "latest", "rc#", etc...)
       * </p>
       *
       * @param identifier the identifier to test.
       * @return true if the unknown string is likely a version string.
       */
      public static boolean isSimpleVersionKeyword( String identifier )
      {
          Matcher mat = VERSION_MEGA_PATTERN.matcher( identifier );
  
          return mat.matches();
      }
  
      public static boolean isSnapshot( String version )
      {
          Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
          if ( m.matches() )
          {
              return true;
          }
          else
          {
              return isGenericSnapshot( version );
          }
      }
  
      public static String getBaseVersion( String version )
      {
          Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
          if ( m.matches() )
          {
              return m.group( 1 ) + "-" + SNAPSHOT;
          }
          else
          {
              return version;
          }
      }
  
      /**
       * <p>
       * Get the release version of the snapshot version.
       * </p>
       * 
       * <p>
       * If snapshot version is 1.0-SNAPSHOT, then release version would be 1.0
       * And if snapshot version is 1.0-20070113.163208-1.jar, then release version would still be 1.0
       * </p>
       *
       * @param snapshotVersion snapshot version
       * @return release version
       */
      public static String getReleaseVersion( String snapshotVersion )
      {
          Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( snapshotVersion );
  
          if ( isGenericSnapshot( snapshotVersion ) )
          {
              m = GENERIC_SNAPSHOT_PATTERN.matcher( snapshotVersion );
          }
  
          if ( m.matches() )
          {
              return m.group( 1 );
          }
          else
          {
              return snapshotVersion;
          }
      }
  
      public static boolean isUniqueSnapshot( String version )
      {
          Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version );
          return m.matches();
      }
  
      public static boolean isGenericSnapshot( String version )
      {
          return version.endsWith( SNAPSHOT );
      }
  
      public static String getVersionFromGenericSnapshot( String version )
      {
          Matcher m = GENERIC_SNAPSHOT_PATTERN.matcher( version );
          if ( m.matches() )
          {
              return m.group( 1 );
          }
          return version;
      }
  
  
  }
  