Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

package com.erggroup.mass.ant;

import java.util.StringTokenizer;

/**
 * <p><code>PackageVersion</code> represents an identifying version of a 
 * package, using the MASS versioning scheme.
 * 
 * <p>The MASS package versioning scheme is as follows:
 * 
 * <blockquote>
 * <pre>
 *      xx.yy.zz.ppp
 *  
 *      where xx = major version 
 *            yy = minor version
 *            zz = patch version
 *           ppp = project abbreviation (default = mas)
 * </pre>
 * </blockquote>
 */
public class PackageVersion implements Comparable, Cloneable
{
        /**
         * The major version of the package.
         */
        private int major = 0;
        
        /**
         * The minor version of the package.
         */
        private int minor = 0;
        
        /**
         * The patch version of the package.
         */
        private int patch = 0;
        
        /**
         * The scope (aka project abbreviation)
         */
        private String scope = "";

        /**
         * Constructs a PackageVersion with the default major / minor / patch versions,
         * and an empty scope (project abbreviation).
         */
        public PackageVersion()
        {
                major = 0;
                minor = 0;
                patch = 0;
                scope = "";
        }

        /**
         * Constructs a PackageVersion with the specified version information.
         * 
         * @param major the major version of the PackageVersion
         * @param minor the minor version of the PackageVersion
         * @param patch the patch version of the PackageVersion
         * @param scope the scope (project abbreviation) of the PackageVersion
         */
        public PackageVersion( int major, int minor, int patch, String scope )
        {
                this.major = major;
                this.minor = minor;
                this.patch = patch;
                this.scope = scope;
        }

        /**
         * Constructs a PackageVersion by parsing the provided string into 
         * composite elements. 
         * 
         * @param version a non-null string containing a PackageVersion in the form
         *        xx.yy.zz.ppp (see class documentation)
         * 
         * @throws NullPointerException if the version string provided is null.
         * @throws NumberFormatException if the string is in an inappropriate form.
         */
        public PackageVersion( String version ) throws NumberFormatException
        {
                if (version == null)
                {
                        throw new NullPointerException();
                }

                StringTokenizer st = new StringTokenizer(version, ".");
                if (st.countTokens() == 4)
                {
                        major = Integer.parseInt(st.nextToken());
                        minor = Integer.parseInt(st.nextToken());
                        patch = Integer.parseInt(st.nextToken());
                        scope = st.nextToken();
                }
                else
                {
                        throw new NumberFormatException("Invalid package version - '" + version + "'");
                }
        }

        /**
         * Gets the value for the major version of this PackageVersion.
         * 
         * @return the major version of this PackageVersion.
         */
        public int getMajor()
        {
                return major;
        }

        /**
         * Gets the value for the minor version of this PackageVersion.
         * 
         * @return the minor version of this PackageVersion.
         */
        public int getMinor()
        {
                return minor;
        }

        /**
         * Gets the value for the patch version of this PackageVersion.
         * 
         * @return the patch version of this PackageVersion.
         */
        public int getPatch()
        {
                return patch;
        }

        /**
         * Gets the value for the scope (project abbreviation) of this 
         * PackageVersion.
         * 
         * @return the scope of this PackageVersion.
         */
        public String getScope()
        {
                return scope;
        }

        /**
         * Sets the value of the major version of this PackageVersion.
         * 
         * @param newValue the new major version of this PackageVersion.
         */
        public void setMajor( int newValue )
        {
                major = newValue;
        }

        /**
         * Sets the value of the minor version of this PackageVersion.
         * 
         * @param newValue the new minor version of this PackageVersion.
         */
        public void setMinor( int newValue )
        {
                minor = newValue;
        }

        /**
         * Sets the value of the patch version of this PackageVersion.
         * 
         * @param newValue the new patch version of this PackageVersion.
         */
        public void setPatch( int newValue )
        {
                patch = newValue;
        }

        /**
         * Sets the value of the scope of this PackageVersion.
         * 
         * @param newValue the new scope of this PackageVersion.
         */
        public void setScope( String newValue )
        {
                scope = newValue;
        }

        /**
         * Obtain a string representation of this PackageVersion. This
         * method provides the string in standard form.
         * 
         * @return the well-formed string representation of this PackageVersion.
         */
        public String toString()
        {
                String stringValue = major + "." + minor + "." + patch;
                if ( scope != null && scope.length() > 0 )
                {
                        stringValue = stringValue + "." + scope;
                }
                return stringValue;
        }

        /**
         * Compares this PackageVersion to the specified object. The result is
         * true if and only if the argument is not <code>null</code> and is a
         * <code>PackageVersion</code> object that represents the same version
         * as this object. 
         * 
         * @param obj the object to compare with.
         * 
         * @return <code>true</code> if the objects are the same, 
         *         <code>false</code> otherwise.
         */
        public boolean equals( Object obj )
        {
                if ( this == obj ) return true;
                if ( obj == null || getClass() != obj.getClass() ) return false;

                PackageVersion other = (PackageVersion)obj;
                if ( major != other.major ) return false;
                if ( minor != other.minor ) return false;
                if ( patch != other.patch ) return false;
                if ( scope == null )
                {
                        if ( other.scope != null ) return false;
                }
                else if ( !scope.equals(other.scope)) return false;
                return true;
        }

        /**
         * Returns a hash code representing this PackageVersion instance.
         * 
         * @return a hash code value for this object.
         */
        public int hashCode()
        {
                int result = 0;
                result = 37*result + major;
                result = 37*result + minor;
                result = 37*result + patch;
                result = 37*result + (scope != null ? scope.hashCode() : 0);
                return result;
        }

        /**
         * Compares this <code>PackageVersion</code> object to another object.
         * If the object is a <code>PackageVersion</code>, this function 
         * performs a numerical ranking based on major / minor / patch versions,
         * followed by an alphanumerical ranking based on the scope.
         * 
         * @param obj the <code>Object</code> to be compared.
         * 
         * @throws <code>ClassCastException</code> if the argument is not a 
         *         <code>PackageVersion</code>.
         */
        public int compareTo( Object obj )
        {
                PackageVersion other = (PackageVersion)obj;

                if ( major > other.major ) return 1;
                if ( major < other.major ) return -1;

                if ( minor > other.minor ) return 1;
                if ( minor < other.minor ) return -1;

                if ( patch > other.patch ) return 1;
                if ( patch < other.patch ) return -1;

                if ( scope == null )
                {
                        if ( other.scope != null )
                                return -1;
                        else
                                return 0;
                }

                return scope.compareTo(other.scope);
        }

        /**
         * Obtain a clone of this instance.
         * 
         * @return a clone of this instance.
         */
        protected Object clone() throws CloneNotSupportedException
        {
                return super.clone();
        }

        /**
         * Increment the major version by 1, and reset the minor and patch versions
         * to 0.
         */
        public void incrementMajor()
        {
                major++;
                minor = 0;
                patch = 0;
        }

        /**
         * Increment the minor version by 1, and reset the patch version to 0. The 
         * major version remains unaffected.
         */
        public void incrementMinor()
        {
                minor++;
                patch = 0;
        }

        /**
         * Increment the patch version by 1 The major and minor versions remain 
         * unaffected.
         */
        public void incrementPatch()
        {
                patch++;
        }
}