001/* Abstract base class for version specifications.
002
003   Copyright (c) 2014-2016 The Regents of the University of California; iSencia Belgium NV.
004   All rights reserved.
005
006   Permission is hereby granted, without written agreement and without
007   license or royalty fees, to use, copy, modify, and distribute this
008   software and its documentation for any purpose, provided that the above
009   copyright notice and the following two paragraphs appear in all copies
010   of this software.
011
012   IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA LIABLE TO ANY PARTY
013   FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014   ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015   THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016   SUCH DAMAGE.
017
018   THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021   PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022   CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023   ENHANCEMENTS, OR MODIFICATIONS.
024
025   PT_COPYRIGHT_VERSION_2
026   COPYRIGHTENDKEY
027*/
028package org.ptolemy.commons;
029
030import java.io.Serializable;
031import java.util.Arrays;
032
033/**
034 * Abstract base class for version specifications.
035 *
036 * <p> The most important thing for a version specification is that it
037 * can be compared to another one.</p>
038 *
039 * <p> Versions can be specified in two formats : a simple 3-digit
040 * spec (+ qualifiers) or a code/tag (not yet ;-) ).  </p>
041 *
042 * @author ErwinDL
043 * @version $Id$
044 * @since Ptolemy II 11.0
045 * @Pt.ProposedRating Yellow (ErwinDL)
046 * @Pt.AcceptedRating Yellow (ErwinDL)
047 */
048public abstract class VersionSpecification
049        implements Comparable<VersionSpecification>, Serializable {
050    private static final long serialVersionUID = 4728405057895700793L;
051
052    ///////////////////////////////////////////////////////////////////
053    ////                         public methods                    ////
054
055    /**
056     * Parses the given version String, using '.' , '-' , '_' as potential delimiters.
057     *
058     * <p> For 3-digit version spec, currently the only supported
059     * format, the first 3 version ids are mandatory and should be
060     * integer numbers.  Extra (optional) trailing ids can be
061     * textual. Spaces are not allowed in a version string.
062     * E.g. "1.2_3-hello.world" is a valid version identifier.
063     * </p>
064     *
065     * @param version The version
066     * @return the version specification based on the passed string representation
067     * @exception IllegalArgumentException when the overall string format is not valid
068     * @exception NumberFormatException if one of the first 3 segments is not an integer
069     */
070    public static VersionSpecification parse(String version) {
071        VersionSpecification versionSpec = null;
072
073        String[] versionIds = version.split("[\\.\\-_]");
074
075        if (versionIds.length < 3) {
076            throw new IllegalArgumentException(
077                    "Version must consist of minimally 3 digits <" + version
078                            + ">");
079        } else {
080            if (version.indexOf(' ') != -1) {
081                throw new IllegalArgumentException(
082                        "3-digit Version can not contain spaces <" + version
083                                + ">");
084            }
085
086            int major = Integer.parseInt(versionIds[0]);
087            int minor = Integer.parseInt(versionIds[1]);
088            int micro = Integer.parseInt(versionIds[2]);
089            if (versionIds.length == 3) {
090                versionSpec = new ThreeDigitVersionSpecification(major, minor,
091                        micro);
092            } else {
093                versionSpec = new ThreeDigitVersionSpecification(major, minor,
094                        micro,
095                        Arrays.copyOfRange(versionIds, 3, versionIds.length));
096            }
097            versionSpec._versionString = version;
098        }
099        return versionSpec;
100    }
101
102    ///////////////////////////////////////////////////////////////////
103    ////                         protected ariables                ////
104
105    /** The version string. */
106    protected String _versionString;
107}