001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 * $Id$
013 */
014
015package org.nuxeo.runtime;
016
017import java.io.Serializable;
018
019/**
020 * A version consists of three fields, denoting the major version, the minor version, and the update version. Example:
021 * 3.1.2.
022 *
023 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
024 */
025public class Version implements Serializable, Comparable<Version> {
026
027    public static final Version ZERO = new Version(0, 0, 0);
028
029    public static final Version MIN = ZERO;
030
031    public static final Version MAX = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
032
033    private static final long serialVersionUID = 4287621413157054503L;
034
035    private final int major;
036
037    private final int minor;
038
039    private final int update;
040
041    /**
042     * Creates a new version object given the major, minor and update version numbers.
043     *
044     * @param major the major version
045     * @param minor the minor version
046     * @param update the update version
047     */
048    public Version(int major, int minor, int update) {
049        this.major = major;
050        this.minor = minor;
051        this.update = update;
052    }
053
054    /**
055     * Creates a new version object given a string representation of the version.
056     *
057     * @param version the version string
058     * @return the version object
059     * @throws NumberFormatException if the version string is invalid
060     */
061    public static Version parseString(String version) {
062        int p = version.indexOf('.', 0);
063        if (p > -1) {
064            int major = Integer.parseInt(version.substring(0, p));
065            int q = version.indexOf('.', p + 1);
066            if (q > -1) {
067                int minor = Integer.parseInt(version.substring(p + 1, q));
068                int update = Integer.parseInt(version.substring(q + 1));
069                return new Version(major, minor, update);
070            } else {
071                return new Version(major, Integer.parseInt(version.substring(p + 1)), 0);
072            }
073        } else {
074            return new Version(Integer.parseInt(version), 0, 0);
075        }
076    }
077
078    /**
079     * Tests if the current version is greater than the given one.
080     *
081     * @param version the version to compare to the current one
082     * @return true if the current version is greater, false otherwise
083     */
084    public boolean isGreaterThan(Version version) {
085        if (major > version.major) {
086            return true;
087        }
088        if (major < version.major) {
089            return false;
090        }
091        if (minor > version.minor) {
092            return true;
093        }
094        if (minor < version.minor) {
095            return false;
096        }
097        return update > version.update;
098    }
099
100    /**
101     * Tests if the current version is greater or equal to the given one.
102     *
103     * @param version the version to compare to the current one
104     * @return if the current version is greater or equal, false otherwise
105     */
106    public boolean isGreaterOrEqualThan(Version version) {
107        if (major > version.major) {
108            return true;
109        }
110        if (major < version.major) {
111            return false;
112        }
113        if (minor > version.minor) {
114            return true;
115        }
116        if (minor < version.minor) {
117            return false;
118        }
119        return update >= version.update;
120    }
121
122    /**
123     * Tests if the current version is equal to the given one.
124     *
125     * @param version the version to compare to the current one
126     * @return if the current version is equal to the given one, false otherwise
127     */
128    public boolean isEqualTo(Version version) {
129        return major == version.major && minor == version.minor && update == version.update;
130    }
131
132    /**
133     * Gets the minor version field.
134     *
135     * @return the minor
136     */
137    public int getMinorVersion() {
138        return minor;
139    }
140
141    /**
142     * Gets the major version field.
143     *
144     * @return the major
145     */
146    public int getMajorVersion() {
147        return major;
148    }
149
150    /**
151     * Gets the update version field.
152     *
153     * @return the update
154     */
155    public int getUpdateVersion() {
156        return update;
157    }
158
159    /**
160     * Gets the string representation of this version.
161     * <p>
162     * The string representation can be used in {@link Version#parseString(String)} to create a version object.
163     */
164    @Override
165    public String toString() {
166        return new StringBuffer().append(major).append('.').append(minor).append('.').append(update).toString();
167    }
168
169    @Override
170    public int hashCode() {
171        return major ^ (minor << 8) ^ (update << 16);
172    }
173
174    @Override
175    public boolean equals(Object object) {
176        if (object == this) {
177            return true;
178        }
179        if (object instanceof Version) {
180            return isEqualTo((Version) object);
181        }
182        return false;
183    }
184
185    @Override
186    public int compareTo(Version v) {
187        if (v == null) {
188            return -1;
189        }
190        if (isEqualTo(v)) {
191            return 0;
192        } else {
193            return isGreaterThan(v) ? 1 : 0;
194        }
195    }
196
197}