001/* 002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Julien Carsique 016 * 017 */ 018 019package org.nuxeo.common.utils; 020 021import java.util.ArrayList; 022import java.util.List; 023import java.util.regex.Pattern; 024 025/** 026 * Compare versions of files as they are usually set. Maven classifiers are not managed: a classifier will be considered 027 * as being part of the version. Maven "SNAPSHOT" keyword is taken in account. Rule is: x-SNAPSHOT < x < 028 * x-AnythingButSNAPSHOT < x.y-SNAPSHOT < x.y 029 * 030 * @since 5.5 031 */ 032public class FileVersion implements Comparable<FileVersion> { 033 034 protected static final String SNAPSHOT = "-SNAPSHOT"; 035 036 protected String version; 037 038 protected boolean snapshot; 039 040 protected boolean specialQualifier; 041 042 protected Integer[] splitVersion; 043 044 protected String qualifier = ""; 045 046 private String separator = ""; 047 048 private String tmpVersion; 049 050 private static final Pattern SPECIAL_QUALIFIER = Pattern.compile("^-(((RC)|(rc)|(alpha)|(ALPHA)|(beta)|(BETA)\\d+)|([a-zA-Z][0-9]{8})).*$"); 051 052 public String getQualifier() { 053 return qualifier; 054 } 055 056 public Integer[] getSplitVersion() { 057 return splitVersion; 058 } 059 060 public FileVersion(String value) { 061 this.version = value; 062 this.snapshot = value.endsWith(SNAPSHOT); 063 split(getVersionWithoutSnapshot()); 064 this.specialQualifier = SPECIAL_QUALIFIER.matcher(qualifier).matches(); 065 } 066 067 public void split(String value) { 068 if (value.startsWith("r")) { 069 // special case for caja-r1234 versions 070 value = value.substring(1); 071 } 072 List<Integer> versions = new ArrayList<Integer>(); 073 this.tmpVersion = value; 074 do { 075 if (".".equals(separator)) { 076 try { 077 versions.add(Integer.valueOf(tmpVersion)); 078 break; 079 } catch (NumberFormatException e) { 080 } 081 } 082 if (splitWith(".", versions)) { 083 continue; 084 } 085 if (splitWith("-", versions)) { 086 continue; 087 } 088 if (splitWith("_", versions)) { 089 continue; 090 } 091 qualifier = separator + tmpVersion; 092 break; 093 } while (true); 094 splitVersion = versions.toArray(new Integer[0]); 095 } 096 097 private boolean splitWith(String token, List<Integer> versions) { 098 try { 099 int index = tmpVersion.indexOf(token); 100 if (index > 0) { 101 versions.add(Integer.valueOf(tmpVersion.substring(0, index))); 102 separator = tmpVersion.substring(index, index + 1); 103 tmpVersion = tmpVersion.substring(index + 1); 104 return true; 105 } else { 106 // treat versions containing only major versions: "1-q", "2" 107 // etc. 108 if (versions.isEmpty()) { 109 versions.add(Integer.valueOf(tmpVersion)); 110 return false; 111 } 112 } 113 } catch (NumberFormatException e) { 114 } 115 return false; 116 } 117 118 @Override 119 public int compareTo(FileVersion o) { 120 if (snapshot && getVersionWithoutSnapshot().equals(o.getVersion()) || specialQualifier 121 && getVersionWithoutQualifier().equals(o.getVersion())) { 122 return -1; 123 } else if (o.isSnapshot() && version.equals(o.getVersionWithoutSnapshot()) || o.hasSpecialQualifier() 124 && version.equals(o.getVersionWithoutQualifier())) { 125 return 1; 126 } 127 128 int index = 0, number, oNumber, result; 129 do { 130 if (splitVersion.length > index) { 131 number = splitVersion[index]; 132 } else { 133 number = 0; 134 } 135 if (o.getSplitVersion().length > index) { 136 oNumber = o.getSplitVersion()[index]; 137 } else { 138 oNumber = 0; 139 } 140 result = number - oNumber; 141 index++; 142 } while (result == 0 && (splitVersion.length > index || o.getSplitVersion().length > index)); 143 if (result == 0) { 144 result = qualifier.compareTo(o.getQualifier()); 145 } 146 return result; 147 } 148 149 @Override 150 public boolean equals(Object o) { 151 return (this == o || o != null && (o instanceof FileVersion) && compareTo((FileVersion) o) == 0); 152 } 153 154 public String getVersion() { 155 return version; 156 } 157 158 public String getVersionWithoutSnapshot() { 159 if (snapshot) { 160 return version.substring(0, version.lastIndexOf(SNAPSHOT)); 161 } 162 return version; 163 } 164 165 public boolean greaterThan(FileVersion other) { 166 return compareTo(other) > 0; 167 } 168 169 public boolean lessThan(FileVersion other) { 170 return compareTo(other) < 0; 171 } 172 173 public boolean isSnapshot() { 174 return snapshot; 175 } 176 177 /** 178 * @since 5.6 179 */ 180 public boolean hasSpecialQualifier() { 181 return specialQualifier; 182 } 183 184 /** 185 * @since 5.6 186 */ 187 public String getVersionWithoutQualifier() { 188 return version.substring(0, version.lastIndexOf(qualifier)); 189 } 190 191 @Override 192 public String toString() { 193 return version; 194 } 195 196}