Coverage Report - org.jtheque.utils.bean.Version
 
Classes in this File Line Coverage Branch Coverage Complexity
Version
95%
70/73
90%
45/50
3.727
 
 1  
 package org.jtheque.utils.bean;
 2  
 
 3  
 /*
 4  
  * This file is part of JTheque.
 5  
  *
 6  
  * JTheque is free software: you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation, either version 3 of the License.
 9  
  *
 10  
  * JTheque is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  
  * GNU General Public License for more details.
 14  
  *
 15  
  * You should have received a copy of the GNU General Public License
 16  
  * along with JTheque.  If not, see <http://www.gnu.org/licenses/>.
 17  
  */
 18  
 
 19  
 import org.jtheque.utils.Constants;
 20  
 import org.jtheque.utils.StringUtils;
 21  
 
 22  
 import java.util.LinkedHashMap;
 23  
 import java.util.Map;
 24  
 import java.util.StringTokenizer;
 25  
 import java.util.regex.Pattern;
 26  
 
 27  
 /**
 28  
  * A version of a module or an other part of the application.
 29  
  *
 30  
  * @author Baptiste Wicht
 31  
  */
 32  0
 public final class Version implements Comparable<Version> {
 33  
     private final String strVersion;
 34  
 
 35  
     private int hash;
 36  
     private final boolean snapshot;
 37  
 
 38  
     private static final Map<String, Integer> CODES;
 39  
 
 40  
     private static final int HIGHEST_CODE = 10;
 41  
 
 42  2
     private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("-SNAPSHOT");
 43  2
     private static final Pattern SNAPSHOT_PATTERN_2 = Pattern.compile("-snapshot");
 44  
 
 45  
     static {
 46  2
         CODES = new LinkedHashMap<String, Integer>(11);
 47  
 
 48  2
         CODES.put("beta", 2);
 49  2
         CODES.put("b", 2);
 50  2
         CODES.put("B", 2);
 51  
 
 52  2
         CODES.put("alpha", 1);
 53  2
         CODES.put("a", 1);
 54  2
         CODES.put("A", 1);
 55  
 
 56  2
         CODES.put("milestone", 3);
 57  2
         CODES.put("m", 3);
 58  2
         CODES.put("M", 3);
 59  
 
 60  2
         CODES.put("rc", 4);
 61  2
         CODES.put("RC", 4);
 62  2
     }
 63  
 
 64  
     /**
 65  
      * Construct a new JThequeVersion with the String version.
 66  
      *
 67  
      * @param version The version
 68  
      */
 69  
     public Version(String version) {
 70  76
         super();
 71  
 
 72  76
         if (version.endsWith("-SNAPSHOT") || version.endsWith("-snapshot")) {
 73  8
             snapshot = true;
 74  8
             strVersion = SNAPSHOT_PATTERN_2.matcher(SNAPSHOT_PATTERN.matcher(version).replaceAll("")).replaceAll("");
 75  
         } else {
 76  68
             snapshot = false;
 77  68
             strVersion = version;
 78  
         }
 79  76
     }
 80  
 
 81  
     /**
 82  
      * Indicate if the version is greater than an other version.
 83  
      *
 84  
      * @param otherVersion The version we want to compare to
 85  
      * @return true if the current version is greater than the other else false
 86  
      */
 87  
     public boolean isGreaterThan(Version otherVersion) {
 88  46
         return compareTo(otherVersion) > 0;
 89  
     }
 90  
 
 91  
     /**
 92  
      * Compare the codes of two version.
 93  
      *
 94  
      * @param current        The current version.
 95  
      * @param other          The other version.
 96  
      * @param codeStrCurrent The code of the current version.
 97  
      * @param codeStrOther   The code of the other version.
 98  
      * @return true if the current code is most valued than the other.
 99  
      */
 100  
     private static boolean compareCode(String current, String other, String codeStrCurrent, String codeStrOther) {
 101  20
         int codeCurrent = intCode(codeStrCurrent);
 102  20
         int codeOther = intCode(codeStrOther);
 103  
 
 104  20
         if (codeCurrent == codeOther) {
 105  8
             String strCurrent = current.replace(codeStrCurrent, StringUtils.EMPTY_STRING);
 106  8
             String strOther = other.replace(codeStrOther, StringUtils.EMPTY_STRING);
 107  
 
 108  8
             return Integer.valueOf(strCurrent).compareTo(Integer.valueOf(strOther)) >= 0;
 109  
         } else {
 110  12
             return codeCurrent > codeOther;
 111  
         }
 112  
     }
 113  
 
 114  
     /**
 115  
      * Return the int code of the string code.
 116  
      *
 117  
      * @param strCode The string code.
 118  
      * @return The int value of the string code.
 119  
      */
 120  
     private static int intCode(String strCode) {
 121  40
         return StringUtils.isEmpty(strCode) ? HIGHEST_CODE : CODES.get(strCode);
 122  
     }
 123  
 
 124  
     /**
 125  
      * Extract the code contained in the version.
 126  
      *
 127  
      * @param version The version string.
 128  
      * @return The code contained in the version or an empty String if there is no code in this version.
 129  
      */
 130  
     private static String extractCode(String version) {
 131  168
         for (Map.Entry<String, Integer> entry : CODES.entrySet()) {
 132  1550
             if (version.contains(entry.getKey())) {
 133  36
                 return entry.getKey();
 134  
             }
 135  
         }
 136  
 
 137  132
         return "";
 138  
     }
 139  
 
 140  
     /**
 141  
      * Returns the string version.
 142  
      *
 143  
      * @return The version
 144  
      */
 145  
     public String getVersion() {
 146  8
         return strVersion;
 147  
     }
 148  
 
 149  
     @Override
 150  
     public String toString() {
 151  10
         return strVersion + (snapshot ? "-SNAPSHOT" : "");
 152  
     }
 153  
 
 154  
     @Override
 155  
     public int hashCode() {
 156  52
         if (hash == 0) {
 157  16
             hash = Constants.HASH_CODE_START;
 158  
 
 159  16
             if (strVersion != null) {
 160  16
                 hash = Constants.HASH_CODE_PRIME * hash + strVersion.hashCode();
 161  
             }
 162  
 
 163  16
             hash = Constants.HASH_CODE_PRIME * hash + (snapshot ? 1 : 0);
 164  
         }
 165  
 
 166  52
         return hash;
 167  
     }
 168  
 
 169  
     @Override
 170  
     public boolean equals(Object obj) {
 171  70
         if (this == obj) {
 172  6
             return true;
 173  
         }
 174  
 
 175  64
         if (EqualsUtils.areObjectIncompatible(this, obj)) {
 176  2
             return false;
 177  
         }
 178  
 
 179  62
         Version version = (Version) obj;
 180  
 
 181  62
         if (version.snapshot != snapshot) {
 182  2
             return false;
 183  
         }
 184  
 
 185  60
         return !EqualsUtils.areNotEquals(strVersion, version.strVersion);
 186  
 
 187  
     }
 188  
 
 189  
     @Override
 190  
     public int compareTo(Version o) {
 191  46
         if (equals(o)) {
 192  6
             return 0;
 193  
         }
 194  
 
 195  40
         StringTokenizer currentTokens = new StringTokenizer(strVersion, ".");
 196  40
         StringTokenizer otherTokens = new StringTokenizer(o.strVersion, ".");
 197  
 
 198  84
         while (currentTokens.hasMoreTokens()) {
 199  84
             String current = currentTokens.nextToken();
 200  
 
 201  84
             if (otherTokens.hasMoreTokens()) {
 202  84
                 String other = otherTokens.nextToken();
 203  
 
 204  84
                 int compare = compareTwoToken(current, other);
 205  
                 
 206  
                 //If the two tokens are not equals, we could assume than the result of the comparison is the result of the
 207  
                 //comparison of the complete version
 208  84
                 if(compare != 0){
 209  40
                     return compare;
 210  
                 }
 211  44
             } else {
 212  0
                 return StringUtils.isEmpty(extractCode(current)) ? 1 : -1;
 213  
             }
 214  44
         }
 215  
 
 216  0
         return -1;
 217  
     }
 218  
 
 219  
     /**
 220  
      * Compare two tokens of two version. 
 221  
      * 
 222  
      * @param current The current token. 
 223  
      * @param other The other token. 
 224  
      * 
 225  
      * @return  a negative integer, zero, or a positive integer as this object
 226  
      *                is less than, equal to, or greater than the specified object.
 227  
      */
 228  
     private int compareTwoToken(String current, String other) {
 229  84
         String codeStrCurrent = extractCode(current);
 230  84
         String codeStrOther = extractCode(other);
 231  
 
 232  84
         if (StringUtils.isEmpty(codeStrCurrent) && StringUtils.isEmpty(codeStrOther)) {
 233  64
             int compare = Integer.valueOf(current).compareTo(Integer.valueOf(other));
 234  
 
 235  64
             return compare;
 236  
         } else {
 237  20
             return compareCode(current, other, codeStrCurrent, codeStrOther) ? 1 : -1;
 238  
         }
 239  
     }
 240  
 }