View Javadoc
1   /*
2    * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and contributors.
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the GNU Lesser General Public License
6    * (LGPL) version 2.1 which accompanies this distribution, and is available at
7    * http://www.gnu.org/licenses/lgpl-2.1.html
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * Contributors:
15   *     bstefanescu, jcarsique
16   */
17  package org.nuxeo.connect.update;
18  import java.util.regex.Pattern;
19  
20  import org.codehaus.plexus.logging.Logger;
21  import org.codehaus.plexus.logging.console.ConsoleLogger;
22  
23  
24  /**
25   * IMPORTANT: this file is copied from
26   * org.nuxeo.connect:nuxeo-connect-client:1.4.13
27   *
28   * Those versions are used in the Marketplace packages. They are in the form
29   * major.minor.patch-classifier with some "special" classifiers which are "rc",
30   * "alpha", "beta" (upper or lower case), a letter followed by a date in the
31   * form AAAAMMDD (for instance "I20131022") and the SNAPSHOT classifier.<br>
32   * Order is the following:<br>
33   * <code>
34   * x.y.z-beta<br>
35   * x.y.z-r20131022<br>
36   * x.y.z-SNAPSHOT<br>
37   * x.y.z<br>
38   * x.y.z-anyclassifier<br>
39   * </code><br>
40   *
41   * Classifiers are alphabetically ordered between themselves.<br>
42   * Special classifiers are before the SNAPSHOT.<br>
43   * SNAPSHOT is always just before the release (without classifier).<br>
44   * Non-special classifiers are after the release.<br>
45   *
46   * See <a href=
47   * "https://github.com/nuxeo/nuxeo-connect/blob/master/nuxeo-connect-client/src/test/java/org/nuxeo/connect/pm/tests/TestVersions.java"
48   * >TestVersions</a>.
49   */
50  public class Version implements Comparable<Version> {
51  
52      private static final Logger log = new ConsoleLogger();
53  
54      /**
55       * @since 1.4
56       */
57      public static final String SNAPSHOT = "-SNAPSHOT";
58  
59      public final static Version ZERO = new Version(0);
60  
61      /**
62       * @since 1.4.4
63       */
64      public static final Pattern SPECIAL_CLASSIFIER = Pattern.compile("^(((RC)|(rc)|(alpha)|(ALPHA)|(beta)|(BETA)\\d*)|([a-zA-Z][0-9]{8})).*$");
65  
66      /**
67       * @since 1.4.4
68       */
69      protected boolean specialClassifier = false;
70  
71      /**
72       * Special classifiers are considered as earlier than versions without
73       * classifier or with a non-special classifier
74       *
75       * @since 1.4.4
76       */
77      public boolean isSpecialClassifier() {
78          return specialClassifier;
79      }
80  
81      protected int major;
82  
83      protected int minor;
84  
85      protected int patch;
86  
87      protected String classifier;
88  
89      protected boolean snapshot = false;
90  
91      public Version(String version) {
92          int i = version.indexOf(SNAPSHOT);
93          if (i > 0) {
94              version = version.substring(0, i);
95              snapshot = true;
96          }
97          int p = version.lastIndexOf('-');
98          if (p > 0) { // classifier found
99              classifier = version.substring(p + 1);
100             version = version.substring(0, p);
101             specialClassifier = SPECIAL_CLASSIFIER.matcher(classifier).matches();
102         }
103         p = version.indexOf('.', 0);
104         if (p > -1) {
105             major = Integer.parseInt(version.substring(0, p));
106             int q = version.indexOf('.', p + 1);
107             if (q > -1) {
108                 minor = Integer.parseInt(version.substring(p + 1, q));
109                 patch = Integer.parseInt(version.substring(q + 1));
110             } else {
111                 minor = Integer.parseInt(version.substring(p + 1));
112             }
113         } else {
114             major = Integer.parseInt(version);
115         }
116     }
117 
118     public Version(int major) {
119         this(major, 0, 0);
120     }
121 
122     public Version(int major, int minor) {
123         this(major, minor, 0);
124     }
125 
126     public Version(int major, int minor, int patch) {
127         this(major, minor, patch, null);
128     }
129 
130     public Version(int major, int minor, int patch, String classifier) {
131         this.major = major;
132         this.minor = minor;
133         this.patch = patch;
134         this.classifier = classifier;
135         if (classifier != null) {
136             specialClassifier = SPECIAL_CLASSIFIER.matcher(classifier).matches();
137         }
138     }
139 
140     public int major() {
141         return major;
142     }
143 
144     public int minor() {
145         return minor;
146     }
147 
148     public int patch() {
149         return patch;
150     }
151 
152     public String classifier() {
153         return classifier;
154     }
155 
156     public boolean lessThan(Version v) {
157         return compareTo(v) < 0;
158     }
159 
160     public boolean lessOrEqualsThan(Version v) {
161         return compareTo(v) <= 0;
162     }
163 
164     public boolean equalsTo(Version v) {
165         return compareTo(v) == 0;
166     }
167 
168     public boolean greaterThan(Version v) {
169         return compareTo(v) > 0;
170     }
171 
172     public boolean greaterOrEqualThan(Version v) {
173         return compareTo(v) >= 0;
174     }
175 
176     @Override
177     public int compareTo(Version o) {
178         log.debug("Comparing " + this + " with " + o);
179         int d = major - o.major;
180         if (d != 0) {
181             return d;
182         }
183         d = minor - o.minor;
184         if (d != 0) {
185             return d;
186         }
187         d = patch - o.patch;
188         if (d != 0) {
189             return d;
190         }
191 
192         String mClassifier = (classifier == null) ? "" : classifier;
193         String oClassifier = (o.classifier == null) ? "" : o.classifier;
194 
195         if (mClassifier.equals(oClassifier)) {
196             if (snapshot == o.isSnapshot()) {
197                 log.debug(" case 1 => 0");
198                 return 0;
199             } else {
200                 if (isSnapshot()) {
201                     log.debug(" case 2 => -1");
202                     return -1;
203                 } else {
204                     log.debug(" case 3 => 1");
205                     return 1;
206                 }
207             }
208         } else {
209             if (specialClassifier && o.isSpecialClassifier()
210                     || !specialClassifier && !o.isSpecialClassifier()) {
211                 log.debug(" case 4 => compare classifiers");
212                 return mClassifier.compareTo(oClassifier);
213             } else if (specialClassifier) {
214                 log.debug(" case 1 => -1");
215                 return -1;
216             } else {
217                 log.debug(" case 6 => 1");
218                 return 1;
219             }
220         }
221     }
222 
223     @Override
224     public boolean equals(Object o) {
225         return (this == o || o != null && (o instanceof Version)
226                 && compareTo((Version) o) == 0);
227     }
228 
229     @Override
230     public int hashCode() {
231         return (major << 16) | (minor << 8) | patch;
232     }
233 
234     @Override
235     public String toString() {
236         String v;
237         if (classifier == null) {
238             v = major + "." + minor + "." + patch;
239         } else {
240             v = major + "." + minor + "." + patch + "-" + classifier;
241         }
242         if (isSnapshot()) {
243             v = v + SNAPSHOT;
244         }
245         return v;
246     }
247 
248     public boolean isSnapshot() {
249         return snapshot;
250     }
251 
252     /**
253      * @since 1.4
254      */
255     public void setSnapshot(boolean isSnapshot) {
256         snapshot = isSnapshot;
257     }
258 
259     /**
260      * @since 1.4
261      */
262     public void setClassifier(String classifier) {
263         this.classifier = classifier;
264     }
265 
266 }