krysalis-version/src/java/org/krysalis/version/impl/data ReleaseLevel.java,NONE,1.1 VersionDataElementSet.java,NONE,1.1 VersionDataElement.java,NONE,1.1 VersionData.java,NONE,1.1 VersionDataElementReverseComparator.java,NONE,1.1 VersionDataComparator.java,NONE,1.1

[email protected] Sun, 23 Mar 2003 17:25:49 -0800
Newsgroups gmane.comp.krysalis.sandbox,gmane.spam.detected
Message-ID <[email protected]>
Update of /cvsroot/metamorphosis/krysalis-version/src/java/org/krysalis/version/impl/data
In directory sc8-pr-cvs1:/tmp/cvs-serv27679/src/java/org/krysalis/version/impl/data

Added Files:
	ReleaseLevel.java VersionDataElementSet.java 
	VersionDataElement.java VersionData.java 
	VersionDataElementReverseComparator.java 
	VersionDataComparator.java 
Log Message:
Cleaned up package naming

--- NEW FILE: ReleaseLevel.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

3. The end-user documentation included with the redistribution,
   if any, must include the following acknowledgment:
    "This product includes software developed for project 
       Krysalis (http://www.krysalis.org/)."
   Alternately, this acknowledgment may appear in the software itself,
   if and wherever such third-party acknowledgments normally appear.

4. The names "Krysalis" and "Nicola Ken Barozzi" and
   "Krysalis Centipede" must not be used to endorse or promote products
   derived from this software without prior written permission. For
   written permission, please contact [email protected].

5. Products derived from this software may not be called "Krysalis",
   "Krysalis Centipede", nor may "Krysalis" appear in their name, without
    prior written permission of Nicola Ken Barozzi.

6. This software may contain voluntary contributions made by many 
   individuals, who decided to donate the code to this project in respect 
   of this licence.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
====================================================================
*/
package org.krysalis.version.impl.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.krysalis.version.exception.VersionException;

/**
 * @author ajack
 */
public class ReleaseLevel implements Comparable {

    //:TODO: Somehow make these "protect" and only let
    // VersionDataElement put out the constants..
    // .. to track down strays...
    //

    /** Unset */
    private static final int LEVEL_UNSET = 0;
    private static final String UNSET_WORD = "unset";
    private static final String UNSET_ABRV = "?";

    /** Development */
    private static final int LEVEL_DEVELOPMENT = 1;
    private static final String DEVELOPMENT_WORD = "dev";
    private static final String DEVELOPMENT_ABRV = "d";

    /** Milestone */
    private static final int LEVEL_MILESTONE = 2;
    private static final String MILESTONE_WORD = "mile";
    private static final String MILESTONE_ABRV = "m";

    /** Alpha */
    private static final int LEVEL_ALPHA = 3;
    private static final String ALPHA_WORD = "alpha";
    private static final String ALPHA_ABRV = "a";

    /** Beta */
    private static final int LEVEL_BETA = 4;
    private static final String BETA_WORD = "beta";
    private static final String BETA_ABRV = "b";

    /** Early Access */
    private static final int LEVEL_EARLY_ACCESS = 5;
    private static final String EARLY_ACCESS_WORD = "ea";
    private static final String EARLY_ACCESS_ABRV = "ea";

    /** Release Candidate */
    private static final int LEVEL_RELEASE_CANDIDATE = 7;
    private static final String RELEASE_CANDIDATE_WORD = "rc";
    private static final String RELEASE_CANDIDATE_ABRV = "rc";

    /** Release*/
    private static final int LEVEL_RELEASE = 8;
    private static final String RELEASE_WORD = "";
    private static final String RELEASE_ABRV = "";

    /** MIN_LEVEL */
    public static final int MIN_RELEASE_LEVEL = ReleaseLevel.LEVEL_DEVELOPMENT;
    /** MAX_LEVEL */
    public static final int MAX_RELEASE_LEVEL = ReleaseLevel.LEVEL_RELEASE;

    /** Unset */
    public static final ReleaseLevel UNSET = new ReleaseLevel(LEVEL_UNSET);

    /** Development */
    public static final ReleaseLevel DEVELOPMENT =
        new ReleaseLevel(LEVEL_DEVELOPMENT);
    public static final ReleaseLevel MIN = DEVELOPMENT;

    /** Alpha */
    public static final ReleaseLevel ALPHA = new ReleaseLevel(LEVEL_ALPHA);
    /** Milestone */
    public static final ReleaseLevel MILESTONE =
        new ReleaseLevel(LEVEL_MILESTONE);
    /** Beta */
    public static final ReleaseLevel BETA = new ReleaseLevel(LEVEL_BETA);
    /** Early Access */
    public static final ReleaseLevel EARLY_ACCESS =
        new ReleaseLevel(LEVEL_EARLY_ACCESS);
    /** Release */
    public static final ReleaseLevel RELEASE_CANDIDATE =
        new ReleaseLevel(LEVEL_RELEASE_CANDIDATE);
    /** Release */
    public static final ReleaseLevel RELEASE = new ReleaseLevel(LEVEL_RELEASE);
    public static final ReleaseLevel MAX = RELEASE;
    public static final ReleaseLevel DEFAULT = RELEASE;

    /** Collections */
    public static final ArrayList RELEASE_LEVELS = new ArrayList();

    public static final HashMap WORD_FOR_LEVEL = new HashMap();
    public static final HashMap LEVEL_FOR_WORD = new HashMap();

    public static final HashMap ABBREVIATION_FOR_LEVEL = new HashMap();
    public static final HashMap LEVEL_FOR_ABBREVIATION = new HashMap();

    private final int m_level;

    static {
        RELEASE_LEVELS.add(ReleaseLevel.ALPHA);
        RELEASE_LEVELS.add(ReleaseLevel.MILESTONE);
        RELEASE_LEVELS.add(ReleaseLevel.DEVELOPMENT);
        RELEASE_LEVELS.add(ReleaseLevel.BETA);
        RELEASE_LEVELS.add(ReleaseLevel.EARLY_ACCESS);
        RELEASE_LEVELS.add(ReleaseLevel.RELEASE_CANDIDATE);
        RELEASE_LEVELS.add(ReleaseLevel.RELEASE);

        // :TODO: Clean this up, with less repetition, less chance for error...
        WORD_FOR_LEVEL.put(ReleaseLevel.UNSET, ReleaseLevel.UNSET_WORD);
        LEVEL_FOR_WORD.put(ReleaseLevel.UNSET_WORD, ReleaseLevel.UNSET);

        ABBREVIATION_FOR_LEVEL.put(ReleaseLevel.UNSET, ReleaseLevel.UNSET_ABRV);
        LEVEL_FOR_ABBREVIATION.put(ReleaseLevel.UNSET_ABRV, ReleaseLevel.UNSET);

        WORD_FOR_LEVEL.put(
            ReleaseLevel.DEVELOPMENT,
            ReleaseLevel.DEVELOPMENT_WORD);
        LEVEL_FOR_WORD.put(
            ReleaseLevel.DEVELOPMENT_WORD,
            ReleaseLevel.DEVELOPMENT);
        ABBREVIATION_FOR_LEVEL.put(
            ReleaseLevel.DEVELOPMENT,
            ReleaseLevel.DEVELOPMENT_ABRV);
        LEVEL_FOR_ABBREVIATION.put(
            ReleaseLevel.DEVELOPMENT_ABRV,
            ReleaseLevel.DEVELOPMENT);

        WORD_FOR_LEVEL.put(ReleaseLevel.MILESTONE, ReleaseLevel.MILESTONE_WORD);
        LEVEL_FOR_WORD.put(ReleaseLevel.MILESTONE_WORD, ReleaseLevel.MILESTONE);
        ABBREVIATION_FOR_LEVEL.put(
            ReleaseLevel.MILESTONE,
            ReleaseLevel.MILESTONE_ABRV);
        LEVEL_FOR_ABBREVIATION.put(
            ReleaseLevel.MILESTONE_ABRV,
            ReleaseLevel.MILESTONE);

        WORD_FOR_LEVEL.put(ReleaseLevel.ALPHA, ReleaseLevel.ALPHA_WORD);
        LEVEL_FOR_WORD.put(ReleaseLevel.ALPHA_WORD, ReleaseLevel.ALPHA);
        ABBREVIATION_FOR_LEVEL.put(ReleaseLevel.ALPHA, ReleaseLevel.ALPHA_ABRV);
        LEVEL_FOR_ABBREVIATION.put(ReleaseLevel.ALPHA_ABRV, ReleaseLevel.ALPHA);

        WORD_FOR_LEVEL.put(ReleaseLevel.BETA, ReleaseLevel.BETA_WORD);
        LEVEL_FOR_WORD.put(ReleaseLevel.BETA_WORD, ReleaseLevel.BETA);
        ABBREVIATION_FOR_LEVEL.put(ReleaseLevel.BETA, ReleaseLevel.BETA_ABRV);
        LEVEL_FOR_ABBREVIATION.put(ReleaseLevel.BETA_ABRV, ReleaseLevel.BETA);

        WORD_FOR_LEVEL.put(
            ReleaseLevel.EARLY_ACCESS,
            ReleaseLevel.EARLY_ACCESS_WORD);
        LEVEL_FOR_WORD.put(
            ReleaseLevel.EARLY_ACCESS_WORD,
            ReleaseLevel.EARLY_ACCESS);
        ABBREVIATION_FOR_LEVEL.put(
            ReleaseLevel.EARLY_ACCESS,
            ReleaseLevel.EARLY_ACCESS_ABRV);
        LEVEL_FOR_ABBREVIATION.put(
            ReleaseLevel.EARLY_ACCESS_ABRV,
            ReleaseLevel.EARLY_ACCESS);

        WORD_FOR_LEVEL.put(
            ReleaseLevel.RELEASE_CANDIDATE,
            ReleaseLevel.RELEASE_CANDIDATE_WORD);
        LEVEL_FOR_WORD.put(
            ReleaseLevel.RELEASE_CANDIDATE_WORD,
            ReleaseLevel.RELEASE_CANDIDATE);
        ABBREVIATION_FOR_LEVEL.put(
            ReleaseLevel.RELEASE_CANDIDATE,
            ReleaseLevel.RELEASE_CANDIDATE_ABRV);
        LEVEL_FOR_ABBREVIATION.put(
            ReleaseLevel.RELEASE_CANDIDATE_ABRV,
            ReleaseLevel.RELEASE_CANDIDATE);

        WORD_FOR_LEVEL.put(ReleaseLevel.RELEASE, ReleaseLevel.RELEASE_WORD);
        LEVEL_FOR_WORD.put(ReleaseLevel.RELEASE_WORD, ReleaseLevel.RELEASE);
        ABBREVIATION_FOR_LEVEL.put(
            ReleaseLevel.RELEASE,
            ReleaseLevel.RELEASE_ABRV);
        LEVEL_FOR_ABBREVIATION.put(
            ReleaseLevel.RELEASE_ABRV,
            ReleaseLevel.RELEASE);
    }

    protected ReleaseLevel(int level) {
        m_level = level;
    }

    public String getAsString() {
        String releaseLevel = (String) WORD_FOR_LEVEL.get(this);

        if (null == releaseLevel)
            releaseLevel = UNSET_WORD;

        return releaseLevel;
    }
    /**
     * Maps a string to an object
     * 
     * @param level
     * @return ReleaseLevel
     * @throws VersionException -- if unrecognized string
     */
    public static ReleaseLevel getFromString(String level)
        throws VersionException {
        ReleaseLevel releaseLevel = null;

        if ((null == level) || (0 == level.length()))
            releaseLevel = ReleaseLevel.RELEASE;
        else
            releaseLevel = (ReleaseLevel) LEVEL_FOR_WORD.get(level);

        if (null == releaseLevel)
            throw new VersionException(
                "Unrecognized Release Level [" + level + "]");

        return releaseLevel;
    }

    public static ReleaseLevel getFromInt(int level) {
        ReleaseLevel releaseLevel = null;

        switch (level) {
            case LEVEL_UNSET :
                {
                    releaseLevel = ReleaseLevel.UNSET;
                    break;
                }

            case LEVEL_DEVELOPMENT :
                {
                    releaseLevel = ReleaseLevel.DEVELOPMENT;
                    break;
                }

            case LEVEL_MILESTONE :
                {
                    releaseLevel = ReleaseLevel.MILESTONE;
                    break;
                }

            case LEVEL_ALPHA :
                {
                    releaseLevel = ReleaseLevel.ALPHA;
                    break;
                }

            case LEVEL_EARLY_ACCESS :
                {
                    releaseLevel = ReleaseLevel.EARLY_ACCESS;
                    break;
                }

            case LEVEL_BETA :
                {
                    releaseLevel = ReleaseLevel.BETA;
                    break;
                }

            case LEVEL_RELEASE_CANDIDATE :
                {
                    releaseLevel = ReleaseLevel.RELEASE_CANDIDATE;
                    break;
                }

            case LEVEL_RELEASE :
                {
                    releaseLevel = ReleaseLevel.RELEASE;
                    break;
                }

            default :
                {
                    releaseLevel = ReleaseLevel.UNSET;
                    break;
                }

        }

        return releaseLevel;
    }

    public String getName() {
        String releaseLevel = null;
        
        switch (m_level) {
            case LEVEL_UNSET :
                {
                    releaseLevel = "ReleaseLevel.UNSET";
                    break;
                }

            case LEVEL_DEVELOPMENT :
                {
                    releaseLevel = "ReleaseLevel.DEVELOPMENT";
                    break;
                }

            case LEVEL_MILESTONE :
                {
                    releaseLevel = "ReleaseLevel.MILESTONE";
                    break;
                }

            case LEVEL_ALPHA :
                {
                    releaseLevel = "ReleaseLevel.ALPHA";
                    break;
                }

            case LEVEL_EARLY_ACCESS :
                {
                    releaseLevel = "ReleaseLevel.EARLY_ACCESS";
                    break;
                }

            case LEVEL_BETA :
                {
                    releaseLevel = "ReleaseLevel.BETA";
                    break;
                }

            case LEVEL_RELEASE_CANDIDATE :
                {
                    releaseLevel = "ReleaseLevel.RELEASE_CANDIDATE";
                    break;
                }

            case LEVEL_RELEASE :
                {
                    releaseLevel = "ReleaseLevel.RELEASE";
                    break;
                }

            default :
                {
                    releaseLevel = "ReleaseLevel.UNSET";
                    break;
                }

        }

        return releaseLevel;
    }
    /**
     * @see Object#equals(Object)
     */
    public boolean equals(Object other) {
        boolean equal = false;

        if (other instanceof ReleaseLevel) {
            ReleaseLevel otherLevel = (ReleaseLevel) other;

            equal = (otherLevel.m_level == m_level);
        }
        else if (other instanceof String) {
            String otherString = (String) other;

            equal = otherString.equalsIgnoreCase(getAsString());
        }

        return equal;
    }

    public String toString() {
        return getName();
    }

    /**
     * @see Object#hashCode()
     */
    public int hashCode() {
        return m_level;
    }

    /**
     * @see Object#equals(Object)
     */
    public int compareTo(Object other) {
        int comparison = -1;

        if (other instanceof ReleaseLevel) {
            ReleaseLevel otherLevel = (ReleaseLevel) other;

            comparison = (m_level - otherLevel.m_level);
        }
        else
            throw new IllegalArgumentException(
                "Not a ReleaseLevel: "
                    + other.getClass()
                    + " : "
                    + other.toString());

        return comparison;
    }

    /**
     * 
     * Increment this ReleaseLevel to the next stage
     * 
     * @return ReleaseLevel
     */
    public ReleaseLevel nextLevel() {
        ReleaseLevel inc = null;
        int level = m_level + 1;

        if (level <= ReleaseLevel.MAX_RELEASE_LEVEL)
            inc = getFromInt(level);

        return inc;
    }

    /**
     * 
     * Decrement this ReleaseLevel to the next stage
     * 
     * @return ReleaseLevel
     */
    public ReleaseLevel previousLevel() {
        ReleaseLevel inc = null;
        int level = m_level - 1;

        if (level >= ReleaseLevel.MIN_RELEASE_LEVEL)
            inc = getFromInt(level);

        return inc;
    }

    public static void main(String args[]) throws Exception {
    
        String nullTest = null;
        ReleaseLevel nullLevel = ReleaseLevel.getFromString(nullTest);
        System.out.println("[" + nullTest + "] -> Release Level : " + nullLevel);
      
        String emptyTest = "";
        ReleaseLevel emptyLevel = ReleaseLevel.getFromString(emptyTest);
        System.out.println("[" + emptyTest + "] -> Release Level : " + emptyLevel);
      
        for ( int i = 0; i < args.length; ++ i){
            String arg = args[i];
            
            ReleaseLevel level = ReleaseLevel.getFromString(arg);

            System.out.println("[" + arg + "] -> Release Level : " + level);
            
        }
        
        for (Iterator i = RELEASE_LEVELS.iterator(); i.hasNext();) {
            ReleaseLevel level = (ReleaseLevel) i.next();
            ReleaseLevel next = level.nextLevel();
            ReleaseLevel prev = level.previousLevel();

            System.out.println("Release Level : " + level);
            System.out.println("Next          : " + next);
            System.out.println("Prev           : " + prev);
        }
    }

}

--- NEW FILE: VersionDataElementSet.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

3. The end-user documentation included with the redistribution,
   if any, must include the following acknowledgment:
      "This product includes software developed for project
       Krysalis (http://www.krysalis.org/)."
   Alternately, this acknowledgment may appear in the software itself,
   if and wherever such third-party acknowledgments normally appear.

4. The names "Krysalis" and "Nicola Ken Barozzi" and
   "Krysalis Centipede" must not be used to endorse or promote products
   derived from this software without prior written permission. For
   written permission, please contact [email protected].

5. Products derived from this software may not be called "Krysalis",
   "Krysalis Centipede", nor may "Krysalis" appear in their name, without
    prior written permission of Nicola Ken Barozzi.

6. This software may contain voluntary contributions made by many 
   individuals, who decided to donate the code to this project in respect 
   of this licence.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
====================================================================
*/
package org.krysalis.version.impl.data;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/**
 * @author [email protected]
 */
public class VersionDataElementSet extends TreeSet {

    public static final VersionDataElementSet SHORT =
        new VersionDataElementSet(
            VersionDataElement.ELEMENT_MAJOR
                | VersionDataElement.ELEMENT_MINOR);

    public static final VersionDataElementSet LONG =
        new VersionDataElementSet(
            VersionDataElement.ELEMENT_MAJOR
                | VersionDataElement.ELEMENT_MINOR
                | VersionDataElement.ELEMENT_MINOR
                | VersionDataElement.ELEMENT_POINT
                | VersionDataElement.ELEMENT_RELEASE_LEVEL);

    public static final VersionDataElementSet DEFAULT =
        new VersionDataElementSet(
            VersionDataElement.ELEMENT_MAJOR
                | VersionDataElement.ELEMENT_MINOR
                | VersionDataElement.ELEMENT_POINT
                | VersionDataElement.ELEMENT_RELEASE_LEVEL
                | VersionDataElement.ELEMENT_RELEASE_QUALIFIER
                | VersionDataElement.ELEMENT_BUILD_NUMBER);

    public static final VersionDataElementSet FULL =
        new VersionDataElementSet(
            VersionDataElement.ELEMENT_MAJOR
                | VersionDataElement.ELEMENT_MINOR
                | VersionDataElement.ELEMENT_POINT
                | VersionDataElement.ELEMENT_RELEASE_LEVEL
                | VersionDataElement.ELEMENT_RELEASE_QUALIFIER
                | VersionDataElement.ELEMENT_BUILD_NUMBER);

    private int m_elementMask = VersionDataElement.ELEMENT_UNSET;


    public VersionDataElementSet() {
        this(0);
    }

    public VersionDataElementSet(int elementValues) {

        super(new VersionDataElementReverseComparator());

        m_elementMask = elementValues;

        if (VersionDataElement.isMajor(elementValues)) {
            add(VersionDataElement.MAJOR);
        }

        if (VersionDataElement.isMinor(elementValues)) {
            add(VersionDataElement.MINOR);
        }

        if (VersionDataElement.isPoint(elementValues)) {
            add(VersionDataElement.POINT);
        }

        if (VersionDataElement.isReleaseLevel(elementValues)) {
            add(VersionDataElement.RELEASE_LEVEL);
        }

        if (VersionDataElement.isReleaseQualifier(elementValues)) {
            add(VersionDataElement.RELEASE_QUALIFIER);
        }

        if (VersionDataElement.isBuildNumber(elementValues)) {
            add(VersionDataElement.BUILD_NUMBER);
        }
    }

    public VersionDataElementSet intersect(VersionDataElementSet other) {
        int mask1 = getElementMask();
        int mask2 = other.getElementMask();

        return new VersionDataElementSet(mask1 & mask2);
    }

    public VersionDataElementSet union(VersionDataElementSet other) {
        int mask1 = getElementMask();
        int mask2 = other.getElementMask();

        return new VersionDataElementSet(mask1 | mask2);
    }

    /**
     * Returns the elementMask.
     * @return int
     */
    public int getElementMask() {
        return m_elementMask;
    }

    public boolean has(VersionDataElement element) {
        return has(element.getElement());
    }

    public boolean has(int element) {
        return (0 != (m_elementMask & element));
    }

    public void set(VersionDataElement element, boolean on) {

        set(element.getElement(), on);
    }

    public void set(int element, boolean on) {
        if (on) {
            if (!has(element)) {
                m_elementMask |= element;
                add(new VersionDataElement(element));
            }
        }
        else {
            if (has(element)) {
                m_elementMask ^= element;
                remove(new VersionDataElement(element));
            }
        }
    }

    /**
     * Sets the elementMask.
     * @param elementMask The elementMask to set
     */
    public void setElementMask(int elementMask) {
        m_elementMask = elementMask;
    }

    public boolean hasMajor() {
        return VersionDataElement.isMajor(m_elementMask);
    }

    public boolean hasMinor() {
        return VersionDataElement.isMinor(m_elementMask);
    }

    public boolean hasPoint() {
        return VersionDataElement.isPoint(m_elementMask);
    }

    public boolean hasReleaseLevel() {
        return VersionDataElement.isReleaseLevel(m_elementMask);
    }

    public boolean hasReleaseQualifier() {
        return VersionDataElement.isReleaseQualifier(m_elementMask);
    }

    public boolean hasBuildNumber() {
        return VersionDataElement.isBuildNumber(m_elementMask);
    }

    public boolean hasEmpty() {
        return (VersionDataElement.ELEMENT_UNSET == m_elementMask);
    }

    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        for (Iterator i = iterator(); i.hasNext();) {
            VersionDataElement element = (VersionDataElement) i.next();

            buffer.append(element.toString());

            if (i.hasNext())
                buffer.append(",");
        }
        buffer.append("]");
        return buffer.toString();
    }
}

--- NEW FILE: VersionDataElement.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

3. The end-user documentation included with the redistribution,
   if any, must include the following acknowledgment:
      "This product includes software developed for project
       Krysalis (http://www.krysalis.org/)."
   Alternately, this acknowledgment may appear in the software itself,
   if and wherever such third-party acknowledgments normally appear.

4. The names "Krysalis" and "Nicola Ken Barozzi" and
   "Krysalis Centipede" must not be used to endorse or promote products
   derived from this software without prior written permission. For
   written permission, please contact [email protected].

5. Products derived from this software may not be called "Krysalis",
   "Krysalis Centipede", nor may "Krysalis" appear in their name, without
    prior written permission of Nicola Ken Barozzi.

6. This software may contain voluntary contributions made by many 
   individuals, who decided to donate the code to this project in respect 
   of this licence.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
====================================================================
*/
package org.krysalis.version.impl.data;

import java.util.ArrayList;
import java.util.HashMap;

import org.krysalis.version.exception.VersionException;
import org.krysalis.version.impl.data.ReleaseLevel;

/**
 * @author [email protected]
 */
public class VersionDataElement implements Comparable {

    public static final int MAX_MAJOR = 100;
    public static final int MAX_MINOR = 100;
    public static final int MAX_POINT = 1000;
    public static final ReleaseLevel MAX_RELEASE_LEVEL = ReleaseLevel.MAX;
    public static final int MAX_RELEASE_QUALIFIER = 100;
    public static final int MAX_BUILD_NUMBER = 100000000;

    public static final int MIN_MAJOR = 0;
    public static final int MIN_MINOR = 0;
    public static final int MIN_POINT = 0;
    public static final ReleaseLevel MIN_RELEASE_LEVEL = ReleaseLevel.MIN;
    public static final int MIN_RELEASE_QUALIFIER = 0;
    public static final int MIN_BUILD_NUMBER = 0;

    public static final int UNSET_MAJOR = -1;
    public static final int UNSET_MINOR = -1;
    public static final int UNSET_POINT = -1;
    public static final ReleaseLevel UNSET_RELEASE_LEVEL = ReleaseLevel.UNSET;
    public static final int UNSET_RELEASE_QUALIFIER = -1;
    public static final int UNSET_BUILD_NUMBER = -1;

    public static final int DEFAULT_MAJOR = MIN_MAJOR;
    public static final int DEFAULT_MINOR = 1;
    public static final int DEFAULT_POINT = UNSET_POINT;
    public static final ReleaseLevel DEFAULT_RELEASE_LEVEL =
        ReleaseLevel.DEFAULT;
    public static final int DEFAULT_RELEASE_QUALIFIER = UNSET_RELEASE_QUALIFIER;
    public static final int DEFAULT_BUILD_NUMBER = UNSET_BUILD_NUMBER;

    /** Unset */
    public static final int ELEMENT_UNSET = 0;
    public static final String UNSET_WORD = "unset";

    /** Development */
    public static final int ELEMENT_BUILD_NUMBER = 0x01;
    public static final String BUILD_NUMBER_WORD = "buildNumber";

    /** Release Qualifier */
    public static final int ELEMENT_RELEASE_QUALIFIER = 0x02;
    public static final String RELEASE_QUALIFIER_WORD = "releaseQualifier";

    /** Release Level */
    public static final int ELEMENT_RELEASE_LEVEL = 0x04;
    public static final String RELEASE_LEVEL_WORD = "releaseLevel";

    /** Point */
    public static final int ELEMENT_POINT = 0x08;
    public static final String POINT_WORD = "point";

    /** Minor */
    public static final int ELEMENT_MINOR = 0x10;
    public static final String MINOR_WORD = "minor";

    /** Major */
    public static final int ELEMENT_MAJOR = 0x20;
    public static final String MAJOR_WORD = "major";

    /** MIN_ELEMENT */
    public static final int MIN_ELEMENT =
        VersionDataElement.ELEMENT_BUILD_NUMBER;
    /** MAX_ELEMENT */
    public static final int MAX_ELEMENT = VersionDataElement.ELEMENT_MAJOR;

    /** Unset */
    public static final VersionDataElement UNSET =
        new VersionDataElement(ELEMENT_UNSET);

    /** Build Number */
    public static final VersionDataElement BUILD_NUMBER =
        new VersionDataElement(ELEMENT_BUILD_NUMBER);
    /** Release Qualifier */
    public static final VersionDataElement RELEASE_QUALIFIER =
        new VersionDataElement(ELEMENT_RELEASE_QUALIFIER);
    /** Release Level */
    public static final VersionDataElement RELEASE_LEVEL =
        new VersionDataElement(ELEMENT_RELEASE_LEVEL);
    /** Point */
    public static final VersionDataElement POINT =
        new VersionDataElement(ELEMENT_POINT);
    /** Minor */
    public static final VersionDataElement MINOR =
        new VersionDataElement(ELEMENT_MINOR);
    /** Major */
    public static final VersionDataElement MAJOR =
        new VersionDataElement(ELEMENT_MAJOR);

    /** Collections */
    public static final ArrayList ELEMENTS = new ArrayList();

    public static final HashMap WORD_FOR_ELEMENT = new HashMap();
    public static final HashMap ELEMENT_FOR_WORD = new HashMap();

    private int m_element = VersionDataElement.ELEMENT_UNSET;

    static {
        ELEMENTS.add(VersionDataElement.BUILD_NUMBER);
        ELEMENTS.add(VersionDataElement.RELEASE_QUALIFIER);
        ELEMENTS.add(VersionDataElement.RELEASE_LEVEL);
        ELEMENTS.add(VersionDataElement.POINT);
        ELEMENTS.add(VersionDataElement.MINOR);
        ELEMENTS.add(VersionDataElement.MAJOR);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.UNSET,
            VersionDataElement.UNSET_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.UNSET_WORD,
            VersionDataElement.UNSET);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.BUILD_NUMBER,
            VersionDataElement.BUILD_NUMBER_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.BUILD_NUMBER_WORD,
            VersionDataElement.BUILD_NUMBER);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.RELEASE_QUALIFIER,
            VersionDataElement.RELEASE_QUALIFIER_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.RELEASE_QUALIFIER_WORD,
            VersionDataElement.RELEASE_QUALIFIER);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.RELEASE_LEVEL,
            VersionDataElement.RELEASE_LEVEL_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.RELEASE_LEVEL_WORD,
            VersionDataElement.RELEASE_LEVEL);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.POINT,
            VersionDataElement.POINT_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.POINT_WORD,
            VersionDataElement.POINT);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.MINOR,
            VersionDataElement.MINOR_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.MINOR_WORD,
            VersionDataElement.MINOR);

        WORD_FOR_ELEMENT.put(
            VersionDataElement.MAJOR,
            VersionDataElement.MAJOR_WORD);
        ELEMENT_FOR_WORD.put(
            VersionDataElement.MAJOR_WORD,
            VersionDataElement.MAJOR);
    }

    protected VersionDataElement(int element) {
        m_element = element;
    }

    public String getAsString() {
        String element = (String) WORD_FOR_ELEMENT.get(this);

        if (null == element)
            element = UNSET_WORD;

        return element;
    }

    public static VersionDataElement getFromString(String elementStr)
        throws VersionException {
        VersionDataElement element =
            (VersionDataElement) ELEMENT_FOR_WORD.get(elementStr);

        if (null == element)
            throw new VersionException(
                "Unknown element name [" + elementStr + "]");
        return element;
    }

    public static VersionDataElement getFromInt(int elementNo)
        throws VersionException {
        VersionDataElement element = null;
        if (ELEMENT_MAJOR == elementNo)
            element = MAJOR;
        else if (ELEMENT_MINOR == elementNo)
            element = MINOR;
        else if (ELEMENT_POINT == elementNo)
            element = POINT;
        else if (ELEMENT_RELEASE_LEVEL == elementNo)
            element = RELEASE_LEVEL;
        else if (ELEMENT_RELEASE_QUALIFIER == elementNo)
            element = RELEASE_QUALIFIER;
        else if (ELEMENT_BUILD_NUMBER == elementNo)
            element = BUILD_NUMBER;

        if (null == element)
            throw new VersionException("Unknown element [" + elementNo + "]");

        return element;
    }

    /**
     * @see Object#equals(Object)
     */
    public boolean equals(Object other) {
        boolean equal = false;

        if (other instanceof VersionDataElement) {
            VersionDataElement otherElement = (VersionDataElement) other;

            equal = (otherElement.m_element == m_element);
        }

        return equal;
    }

    public String toString() {
        return getAsString();
    }

    /**
     * @see Object#hashCode()
     */
    public int hashCode() {
        return m_element;
    }

    /**
     * @see Object#equals(Object)
     */
    public int compareTo(Object other) {
        int comparison = -1;

        if (other instanceof VersionDataElement) {
            VersionDataElement otherElement = (VersionDataElement) other;

            //
            // :TODO: This work for a mask?
            //
            comparison = (m_element - otherElement.m_element);
        }
        else
            throw new IllegalArgumentException(
                "Not a VersionDataElement: "
                    + other.getClass()
                    + " : "
                    + other.toString());

        return comparison;
    }

    /**
     * Returns the element.
     * @return int
     */
    public int getElement() {
        return m_element;
    }

    public static boolean isMajor(VersionDataElement element) {
        return isMajor(element.getElement());
    }

    public static boolean isMajor(int elementSet) {
        return (0 != (elementSet & ELEMENT_MAJOR));
    }

    public static boolean isMinor(VersionDataElement element) {
        return isMinor(element.getElement());
    }

    public static boolean isMinor(int elementSet) {
        return (0 != (elementSet & ELEMENT_MINOR));
    }
    public static boolean isPoint(VersionDataElement element) {
        return isPoint(element.getElement());
    }

    public static boolean isPoint(int elementSet) {
        return (0 != (elementSet & ELEMENT_POINT));
    }

    public static boolean isReleaseLevel(VersionDataElement element) {
        return isReleaseLevel(element.getElement());
    }

    public static boolean isReleaseLevel(int elementSet) {
        return (0 != (elementSet & ELEMENT_RELEASE_LEVEL));
    }

    public static boolean isReleaseQualifier(VersionDataElement element) {
        return isReleaseQualifier(element.getElement());
    }

    public static boolean isReleaseQualifier(int elementSet) {
        return (0 != (elementSet & ELEMENT_RELEASE_QUALIFIER));
    }

    public static boolean isBuildNumber(VersionDataElement element) {
        return isBuildNumber(element.getElement());
    }

    public static boolean isBuildNumber(int elementSet) {
        return (0 != (elementSet & ELEMENT_BUILD_NUMBER));
    }
}

--- NEW FILE: VersionData.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
[...1019 lines suppressed...]

        if (null != m_annotations) {
            for (Iterator ai = m_annotations.iterator(); ai.hasNext();) {
                Object note = ai.next();
                out.println(" - " + note.toString());
            }
        }

        if (null != m_attributes) {
            for (Iterator ai = m_attributes.keySet().iterator();
                ai.hasNext();
                ) {
                Object key = ai.next();
                Object value = m_attributes.get(key);

                out.println(" - " + key + " -> [" + value.toString() + "]");
            }
        }
    }
}

--- NEW FILE: VersionDataElementReverseComparator.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

3. The end-user documentation included with the redistribution,
   if any, must include the following acknowledgment:
      "This product includes software developed for project
       Krysalis (http://www.krysalis.org/)."
   Alternately, this acknowledgment may appear in the software itself,
   if and wherever such third-party acknowledgments normally appear.

4. The names "Krysalis" and "Nicola Ken Barozzi" and
   "Krysalis Centipede" must not be used to endorse or promote products
   derived from this software without prior written permission. For
   written permission, please contact [email protected].

5. Products derived from this software may not be called "Krysalis",
   "Krysalis Centipede", nor may "Krysalis" appear in their name, without
    prior written permission of Nicola Ken Barozzi.

6. This software may contain voluntary contributions made by many 
   individuals, who decided to donate the code to this project in respect 
   of this licence.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
====================================================================
*/
package org.krysalis.version.impl.data;

import java.util.Comparator;

/**
 *
 * @author $Author: arb_jack $
 * @version $Revision: 1.1 $
 * 
 */
public class VersionDataElementReverseComparator implements Comparator {

    public int compare(Object o1, Object o2) {
        return (
            ((VersionDataElement) o2).getElement()
                - ((VersionDataElement) o1).getElement());
    }
}

--- NEW FILE: VersionDataComparator.java ---
/*
The Krysalis Patchy Software License, Version 1.1_01

Copyright (c) 2002-2003 Nicola Ken Barozzi.  All rights reserved.

This Licence is compatible with the BSD licence as described and 
approved by http://www.opensource.org/, and is based on the
Apache Software Licence Version 1.1.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

3. The end-user documentation included with the redistribution,
   if any, must include the following acknowledgment:
      "This product includes software developed for project 
       Krysalis (http://www.krysalis.org/)."
   Alternately, this acknowledgment may appear in the software itself,
   if and wherever such third-party acknowledgments normally appear.

4. The names "Krysalis" and "Nicola Ken Barozzi" and
   "Krysalis Centipede" must not be used to endorse or promote products
   derived from this software without prior written permission. For
   written permission, please contact [email protected].

5. Products derived from this software may not be called "Krysalis",
   "Krysalis Centipede", nor may "Krysalis" appear in their name, without
    prior written permission of Nicola Ken Barozzi.

6. This software may contain voluntary contributions made by many 
   individuals, who decided to donate the code to this project in respect 
   of this licence.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
====================================================================
*/
package org.krysalis.version.impl.data;

import java.util.Comparator;

// :TODO: Compatibility a class -- a range? 
// :TODO: Types of compatiblity, see commons...

/**
 * @author [email protected]
 */
public class VersionDataComparator implements Comparator {

    /**
     * @see Object#equals(Object)
     * 
     * :TODO: Follow hashCode algortym (i.e. multiple by 'position').
     * :TODO: Attributes?
     */
    public int compare(Object first, Object second) {
        int comparison = -1;

        if (first instanceof VersionData) {
            VersionData firstVersionData = (VersionData) first;

            if (second instanceof VersionData) {
                VersionData secondVersionData = (VersionData) second;

                VersionDataElementSet set1 = firstVersionData.getElements();
                VersionDataElementSet set2 = secondVersionData.getElements();

                VersionDataElementSet overlap = set1.intersect(set2);

                if (!overlap.isEmpty()) {
                    comparison = 0;

                    //    :TODO: Deal with null versions...
                    //    :TODO: Deal with unset values...

                    if (overlap.hasMajor())
                        comparison =
                            (secondVersionData.getMajor()
                                - firstVersionData.getMajor());

                    if ((0 == comparison) && overlap.hasMinor())
                        comparison =
                            (secondVersionData.getMinor()
                                - firstVersionData.getMinor());

                    if ((0 == comparison) && overlap.hasReleaseLevel())
                        comparison =
                            (secondVersionData
                                .getReleaseLevel()
                                .compareTo(firstVersionData.getReleaseLevel()));

                    if ((0 == comparison) && overlap.hasPoint())
                        comparison =
                            (secondVersionData.getPoint()
                                - firstVersionData.getPoint());

                    if ((0 == comparison) && overlap.hasReleaseQualifier())
                        comparison =
                            (secondVersionData.getReleaseQualifier()
                                - firstVersionData.getReleaseQualifier());

                    if ((0 == comparison) && overlap.hasBuildNumber())
                        comparison =
                            (secondVersionData.getBuildNumber()
                                - firstVersionData.getBuildNumber());

                    //          :TODO: Attributes/Annotations/Constraints/second
                }
            }
        }
        //:TODO: throw exceptions?

        return comparison;
    }
}




-------------------------------------------------------
This SF.net email is sponsored by:Crypto Challenge is now open! 
Get cracking and register here for some mind boggling fun and 
the chance of winning an Apple iPod:
http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0031en