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