/* * Copyright 2010 Research Studios Austria Forschungsgesellschaft mBH * * This file is part of easyrec. * * easyrec is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * easyrec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with easyrec. If not, see <http://www.gnu.org/licenses/>. */ package org.easyrec.plugin.model; import javax.xml.bind.annotation.adapters.XmlAdapter; /** * This class is a model class (dataholder) for the database <code>Version</code>. <p/> <p><b>Company: </b> SAT, * Research Studios Austria</p> <p/> <p><b>Copyright: </b> (c) 2010</p> <p/> <p><b>last modified:</b><br/> * $Author: pmarschik $<br/> $Date: 2011-03-24 15:21:34 +0100 (Do, 24 Mär 2011) $<br/> $Revision: 18036 $</p> * * @author Roman Cerny */ public class Version implements Comparable<Version> { public static class StringAdapter extends XmlAdapter<String, Version> { @Override public Version unmarshal(String v) throws Exception { return Version.parseVersion(v); } @Override public String marshal(Version v) throws Exception { return v.toString(); } } // ------------------------------ FIELDS ------------------------------ private static final String PATTERN_ERROR_MESSAGE = "Wrong format, 'version' has to fit the pattern 'major.minor[.misc]'\n\n" + " where:\n" + " major = any number >= 0 (leading zeros allowed)\n" + " minor = any number >= 0 (leading zeros allowed)\n" + " misc = any number >= 0 (leading zeros allowed)\n" + " any of major, minor, or misc has to be > 0, at least major and minor need to be specified\n\n"; private int major; private int minor; private Integer misc; // -------------------------- STATIC METHODS -------------------------- public static Version parseVersion(String version) { return new Version(version); } public static Version valueOf(String version) { return new Version(version); } // --------------------------- CONSTRUCTORS --------------------------- /** * Creates a new <code>Version</code> object. * <p/> * In order to be valid the String representation of a <code>Version</code> must follow this pattern: * <p/> * major.minor.misc * <p/> * Where: major = any number >= 0 (leading zeros allowed) minor = any number >= 0 (leading zeros allowed) misc = any * number >= 0 (leading zeros allowed) any of major, minor, or misc has to be > 0 * <p/> * Some valid versions: 0.1 1.0 1.0.10 1.7.21 20.1.0 * <p/> * Some illegal versions: 1 0.0 0.0.0 -1.0.0 0.-1.0 0.0.-1 1.0.0.0 * * @param version as String representation * @throws IllegalArgumentException when the given version, does not fit the version pattern */ public Version(String version) { if (version == null) throw new IllegalArgumentException("'version' must not be 'null'"); String[] splitVersion = version.split("\\."); if (splitVersion.length < 2) throw new IllegalArgumentException(PATTERN_ERROR_MESSAGE + "missing '.'"); else if (splitVersion.length > 3) throw new IllegalArgumentException(PATTERN_ERROR_MESSAGE + "too many '.'"); try { major = Integer.parseInt(splitVersion[0]); } catch (NumberFormatException e) { throw new IllegalArgumentException("'major' has to be a number", e); } try { minor = Integer.parseInt(splitVersion[1]); } catch (NumberFormatException e) { throw new IllegalArgumentException("'minor' has to be a number", e); } if (splitVersion.length > 2) { try { misc = Integer.parseInt(splitVersion[2]); } catch (NumberFormatException e) { throw new IllegalArgumentException("'misc' has to be a number", e); } } else { misc = null; } testValidity(); } private void testValidity() { if (major < 0) throw new IllegalArgumentException("'major' has to be a number > 0"); if (minor < 0) throw new IllegalArgumentException("'minor' has to be a number > 0"); if (isMiscAvailable()) { if (misc < 0) throw new IllegalArgumentException("'misc' has to be a number > 0"); if (major == 0 && minor == 0 && misc == 0) throw new IllegalArgumentException("any of 'major', 'minor', or 'misc' has to be > 0"); } else { if (major == 0 && minor == 0) throw new IllegalArgumentException("any of 'major' or 'minor' has to be > 0"); } } public Version(final int major, final int minor) { this.major = major; this.minor = minor; this.misc = null; testValidity(); } public Version(final int major, final int minor, final int misc) { this.major = major; this.minor = minor; this.misc = misc; testValidity(); } // --------------------- GETTER / SETTER METHODS --------------------- public int getMajor() { return major; } public int getMinor() { return minor; } public Integer getMisc() { return misc; } // ------------------------ CANONICAL METHODS ------------------------ @Override public boolean equals(final Object o) { if (this == o) return true; if (!(o instanceof Version)) return false; final Version version = (Version) o; return major == version.major && minor == version.minor && !(misc != null ? !misc.equals(version.misc) : version.misc != null); } @Override public int hashCode() { int result = major; result = 31 * result + minor; result = 31 * result + (misc != null ? misc.hashCode() : 0); return result; } @Override public String toString() { StringBuilder result = new StringBuilder().append(major).append('.').append(minor); if (isMiscAvailable()) result.append('.').append(misc); return result.toString(); } public boolean isMiscAvailable() { return misc != null; } // ------------------------ INTERFACE METHODS ------------------------ // --------------------- Interface Comparable --------------------- public int compareTo(Version that) { final int BEFORE = -1; final int EQUAL = 0; final int AFTER = BEFORE * -1; if (this == that) { return EQUAL; } if (this.major > that.major) return AFTER; if (this.major < that.major) return BEFORE; if (this.minor > that.minor) return AFTER; if (this.minor < that.minor) return BEFORE; if (this.misc != null && that.misc != null) { if (this.misc > that.misc) return AFTER; if (this.misc < that.misc) return BEFORE; } else if (this.misc == null && that.misc != null) { return BEFORE; } else if (this.misc != null && that.misc == null) { return AFTER; } assert this.equals(that) : "compareTo(...) inconsistent with equals(...)"; return EQUAL; } }