VersionComparator.java
001 /*
002  * VersionComparator.java
003  
004  * Copyright (c) 2011, The University of Sheffield. See the file COPYRIGHT.txt
005  * in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  
007  * This file is part of GATE (see http://gate.ac.uk/), and is free software,
008  * licenced under the GNU Library General Public License, Version 2, June 1991
009  * (in the distribution as file licence.html, and also available at
010  * http://gate.ac.uk/gate/licence.html).
011  
012  * Mark A. Greenwood, 26/11/2011
013  */
014 
015 package gate.util;
016 
017 import gate.Main;
018 
019 import java.util.Comparator;
020 import java.util.regex.Matcher;
021 import java.util.regex.Pattern;
022 
023 /**
024  * A comparator that can be used for comparing GATE version strings. This
025  * includes comparing SNAPSHOT versions as well as releases. This is needed to
026  * be able to determine if a CREOLE plugin is compatible with a specific GATE
027  * version.
028  
029  @author Mark A. Greenwood
030  */
031 public class VersionComparator implements Comparator<String> {
032 
033   // this pattern matches any dot separated sequence of digits
034   private static final Pattern VERSION_PATTERN = Pattern
035           .compile("(\\d+)(?:\\.(\\d+))*");
036 
037   @Override
038   public int compare(String v1, String v2) {
039     return compareVersions(v1, v2);
040   }
041 
042   public static int compareVersions(String v1, String v2) {
043 
044     // if the two strings are identical then they must represent the same
045     // version so just return quickly
046     if(v1.equalsIgnoreCase(v2)) return 0;
047 
048     // use the regex to find the digit groupings
049     Matcher m1 = VERSION_PATTERN.matcher(v1);
050     Matcher m2 = VERSION_PATTERN.matcher(v2);
051 
052     if(!m1.find() || !m2.find()) {
053       // these don't represent versions so sort as strings
054       return v1.compareTo(v2);
055     }
056 
057     // get the maximum number of digit groups
058     int groups = Math.max(m1.groupCount(), m2.groupCount());
059 
060     for(int i = 1; i <= groups; i++) {
061       // for each digit group get the string and convert it to an int
062       // if the version string doesn't have this group then set it to 0
063       int g1 = (m1.group(i!= null ? Integer.parseInt(m1.group(i)) 0);
064       int g2 = (m2.group(i!= null ? Integer.parseInt(m2.group(i)) 0);
065 
066       // now compare the numeric value of the group and return as appropriate
067       if(g1 < g2return -1;
068       if(g1 > g2return 1;
069     }
070 
071     // we have checked all the numbers and the versions are equal
072     // so let's check if either is a snapshot (snapshots are considered lower
073     // than non-snapshot versions with the same number)
074     boolean v1IsSnapshot = v1.toUpperCase().endsWith("-SNAPSHOT");
075     boolean v2IsSnapshot = v2.toUpperCase().endsWith("-SNAPSHOT");
076 
077     if(v1IsSnapshot && !v2IsSnapshotreturn -1;
078     if(!v1IsSnapshot && v2IsSnapshotreturn 1;
079 
080     // if we get all the way to here then the two strings represent the same
081     // version
082     return 0;
083   }
084 
085   /**
086    * Returns true if the specified version is the same or newer than the version
087    * of GATE being used.
088    
089    @param version
090    *          the version number to check
091    @return true if the specified version is the same or newer than the version
092    *         of GATE being used, false otherwise
093    */
094   public static boolean isGATENewEnough(String version) {
095     if(version == nullreturn true;
096 
097     version = version.trim();
098 
099     if(version.equals(""|| version.equals("*")) return true;
100 
101     return (compareVersions(Main.version, version>= 0);
102   }
103 
104   /**
105    * Returns true if the specified version is the same or older than the version
106    * of GATE being used.
107    
108    @param version
109    *          the version number to check
110    @return true if the specified version is the same or older than the version
111    *         of GATE being used, false otherwise
112    */
113   public static boolean isGATEOldEnough(String version) {
114     if(version == nullreturn true;
115 
116     version = version.trim();
117 
118     if(version.equals(""|| version.equals("*")) return true;
119 
120     return (compareVersions(Main.version, version<= 0);
121   }
122 
123   /**
124    * Checks to see if the version of GATE falls between the two specified
125    * versions (this is an inclusive check).
126    
127    @param min
128    *          the minimum compatible GATE version
129    @param max
130    *          the maximum compatible GATE version
131    @return if the version of GATE falls between the two specified versions
132    *         (this is an inclusive check), false otherwise
133    */
134   public static boolean isCompatible(String min, String max) {
135     return isGATENewEnough(min&& isGATEOldEnough(max);
136   }
137 }