001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.common;
020
021import icy.util.StringUtil;
022
023/**
024 * Version class.<br>
025 * This class is used to describe a version number encoded on 4 digits.<br>
026 * Each digit should not exceed 99.
027 * 
028 * @author Stephane
029 */
030public class Version implements Comparable<Version>
031{
032    private int major;
033    private int minor;
034    private int revision;
035    private int build;
036    private boolean beta;
037
038    public Version()
039    {
040        this(0, 0, 0, 0, false);
041    }
042
043    public Version(int major)
044    {
045        this(major, 0, 0, 0, false);
046    }
047
048    public Version(int major, int minor)
049    {
050        this(major, minor, 0, 0, false);
051    }
052
053    public Version(int major, int minor, int revision)
054    {
055        this(major, minor, revision, 0, false);
056    }
057
058    public Version(int major, int minor, int revision, int build)
059    {
060        this(major, minor, revision, build, false);
061    }
062
063    public Version(int major, int minor, int revision, int build, boolean beta)
064    {
065        super();
066
067        this.major = major;
068        this.minor = minor;
069        this.revision = revision;
070        this.build = build;
071        this.beta = beta;
072    }
073
074    public Version(String version)
075    {
076        this(0, 0, 0, 0, version.toUpperCase().indexOf('B') != -1);
077
078        final String[] values = version.replaceAll("[a-zA-Z ]", "").split("\\.");
079
080        if (values != null)
081        {
082            if ((values.length > 0) && (!StringUtil.isEmpty(values[0], true)))
083                major = Integer.parseInt(values[0]);
084            if ((values.length > 1) && (!StringUtil.isEmpty(values[1], true)))
085                minor = Integer.parseInt(values[1]);
086            if ((values.length > 2) && (!StringUtil.isEmpty(values[2], true)))
087                revision = Integer.parseInt(values[2]);
088            if ((values.length > 3) && (!StringUtil.isEmpty(values[3], true)))
089                build = Integer.parseInt(values[3]);
090        }
091    }
092
093    /**
094     * @return the major
095     */
096    public int getMajor()
097    {
098        return major;
099    }
100
101    /**
102     * @param major
103     *        the major to set
104     */
105    public void setMajor(int major)
106    {
107        this.major = major;
108    }
109
110    /**
111     * @return the minor
112     */
113    public int getMinor()
114    {
115        return minor;
116    }
117
118    /**
119     * @param minor
120     *        the minor to set
121     */
122    public void setMinor(int minor)
123    {
124        this.minor = minor;
125    }
126
127    /**
128     * @return the revision
129     */
130    public int getRevision()
131    {
132        return revision;
133    }
134
135    /**
136     * @param revision
137     *        the revision to set
138     */
139    public void setRevision(int revision)
140    {
141        this.revision = revision;
142    }
143
144    /**
145     * @return the build
146     */
147    public int getBuild()
148    {
149        return build;
150    }
151
152    /**
153     * @param build
154     *        the build to set
155     */
156    public void setBuild(int build)
157    {
158        this.build = build;
159    }
160
161    /**
162     * @return the beta
163     */
164    public boolean isBeta()
165    {
166        return beta;
167    }
168
169    /**
170     * @param beta
171     *        the beta to set
172     */
173    public void setBeta(boolean beta)
174    {
175        this.beta = beta;
176    }
177
178    /**
179     * special isEmpty case (0.0.0.0)
180     */
181    public boolean isEmpty()
182    {
183        return (major == 0) && (minor == 0) && (revision == 0) && (build == 0) && !beta;
184    }
185
186    public String toShortString()
187    {
188        if (isEmpty())
189            return "";
190
191        String result;
192
193        result = Integer.toString(major) + ".";
194        result += Integer.toString(minor) + ".";
195        result += Integer.toString(revision) + ".";
196        result += Integer.toString(build);
197        if (beta)
198            result += "b";
199
200        return result;
201    }
202
203    @Override
204    public boolean equals(Object obj)
205    {
206        if (obj instanceof Version)
207            return compareTo((Version) obj) == 0;
208
209        return super.equals(obj);
210    }
211
212    @Override
213    public int hashCode()
214    {
215        // assume 7 bits for each number (0-127 range)
216        final int result = (build << 22) | (major << 15) | (minor << 8) | (revision << 1);
217
218        if (beta)
219            return result + 1;
220
221        return result;
222
223    }
224
225    @Override
226    public String toString()
227    {
228        if (isEmpty())
229            return "";
230
231        String result;
232
233        result = Integer.toString(major) + ".";
234        result += Integer.toString(minor) + ".";
235        result += Integer.toString(revision) + ".";
236        result += Integer.toString(build);
237        if (beta)
238            result += " beta";
239
240        return result;
241    }
242
243    @Override
244    public int compareTo(Version o)
245    {
246        if (o == null)
247            return 1;
248        else if (o.isEmpty() || isEmpty())
249            return 0;
250        else if (o.major < major)
251            return 1;
252        else if (o.major > major)
253            return -1;
254        else if (o.minor < minor)
255            return 1;
256        else if (o.minor > minor)
257            return -1;
258        else if (o.revision < revision)
259            return 1;
260        else if (o.revision > revision)
261            return -1;
262        else if (o.build < build)
263            return 1;
264        else if (o.build > build)
265            return -1;
266        else if (o.beta && !beta)
267            return 1;
268        else if (!o.beta && beta)
269            return -1;
270        else
271            return 0;
272    }
273
274    public boolean isGreater(Version version)
275    {
276        return compareTo(version) > 0;
277    }
278
279    public boolean isGreaterOrEqual(Version version)
280    {
281        return compareTo(version) >= 0;
282    }
283
284    public boolean isLower(Version version)
285    {
286        return compareTo(version) < 0;
287    }
288
289    public boolean isLowerOrEqual(Version version)
290    {
291        return compareTo(version) <= 0;
292    }
293
294    public boolean isNewer(Version version)
295    {
296        return isGreater(version);
297    }
298
299    public boolean isNewerOrEqual(Version version)
300    {
301        return isGreaterOrEqual(version);
302    }
303
304    public boolean isOlder(Version version)
305    {
306        return isLower(version);
307    }
308
309    public boolean isOlderOrEqual(Version version)
310    {
311        return isLowerOrEqual(version);
312    }
313
314}