/********************************************************************** * Copyright (c) 2005-2009 ant4eclipse project team. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich **********************************************************************/ package org.ant4eclipse.lib.core.data; import org.ant4eclipse.lib.core.Assure; import org.ant4eclipse.lib.core.CoreExceptionCode; import org.ant4eclipse.lib.core.exception.Ant4EclipseException; import org.ant4eclipse.lib.core.nls.NLS; import org.ant4eclipse.lib.core.nls.NLSMessage; import java.util.NoSuchElementException; import java.util.StringTokenizer; /** * <p> * Implements a {@link Version}. * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) * @author Daniel Kasmeroglu (Daniel.Kasmeroglu@Kasisoft.net) */ public class Version { @NLSMessage("The given version '%s' is invalid. Must match: <major> [ '.' <minor> [ '.' <micro> [ '_' <qualifier> ] ] ]") public static String MSG_FORMATERROR; /** the major version */ private Integer _major; /** the minor version */ private Integer _minor; /** the micro version */ private Integer _micro; /** the qualifier version */ private String _qualifier; private String _str; static { NLS.initialize(Version.class); } /** * Sets up this version information from the supplied formatted string. The format is as followed:<br/> * * <major>['.'<minor>['.'<micro>['_'<qualifier>]]] * * The meaning of the qualifier depends on the context where the version information is used. * * @param version * A formatted version string. Neither <code>null</code> nor empty. */ public static final Version newBundleVersion(String version) { Assure.nonEmpty("version", version); return new Version(version, true); } /** * Sets up this version information from the supplied formatted string. The format is as followed:<br/> * * <major>['.'<minor>['.'<micro>[<qualifier>]]] * * The meaning of the qualifier depends on the context where the version information is used. * * @param version * A formatted version string. Neither <code>null</code> nor empty. */ public static final Version newStandardVersion(String version) { Assure.nonEmpty("version", version); return new Version(version, false); } /** * Sets up this version information from the supplied formatted string. The format is as followed:<br/> * * <major>['.'<minor>['.'<micro>['_'<qualifier>]]] * * The meaning of the qualifier depends on the context where the version information is used. * * @param version * A formatted version string. Neither <code>null</code> nor empty. * @param bundleversion * <code>true</code> <=> The format of the version denotes a bundle version. */ private Version(String version, boolean bundleversion) { Assure.nonEmpty("version", version); this._major = Integer.valueOf(0); this._minor = Integer.valueOf(0); this._micro = Integer.valueOf(0); this._qualifier = null; try { StringTokenizer st = new StringTokenizer(version, ".", false); this._major = Integer.valueOf(st.nextToken()); if (st.hasMoreTokens()) { this._minor = Integer.valueOf(st.nextToken()); if (st.hasMoreTokens()) { String microWithQualifier = st.nextToken(); int firstpos = indexOf(microWithQualifier, bundleversion ? '_' : '_', '-'); if (firstpos == -1) { // no delimiter this._micro = Integer.valueOf(microWithQualifier); } else { // with delimiter separating the qualifier this._micro = Integer.valueOf(microWithQualifier.substring(0, firstpos)); if (firstpos < microWithQualifier.length() - 1) { this._qualifier = microWithQualifier.substring(firstpos + 1); } } if (st.hasMoreTokens()) { throw new Ant4EclipseException(CoreExceptionCode.ILLEGAL_FORMAT, String.format(MSG_FORMATERROR, version)); } } } } catch (NumberFormatException ex) { throw new Ant4EclipseException(CoreExceptionCode.ILLEGAL_FORMAT, String.format(MSG_FORMATERROR, version)); } catch (NoSuchElementException e) { throw new Ant4EclipseException(CoreExceptionCode.ILLEGAL_FORMAT, String.format(MSG_FORMATERROR, version)); } // create a textual representation StringBuffer buffer = new StringBuffer(); buffer.append(this._major); buffer.append("."); buffer.append(this._minor); buffer.append("."); buffer.append(this._micro); if (this._qualifier != null) { buffer.append("_"); buffer.append(this._qualifier); } this._str = buffer.toString(); } /** * Determines the leftmost character position of a list of candidates. * * @param str * The String where to look for. Not <code>null</code>. * @param candidates * The characters to look for. * * @return The position of the leftmost found character or -1. */ private int indexOf(String str, char... candidates) { int result = Integer.MAX_VALUE; for (char ch : candidates) { int pos = str.indexOf(ch); if (pos != -1) { result = Math.min(result, pos); } } if (result == Integer.MAX_VALUE) { result = -1; } return result; } /** * Returns the major version. * * @return The major version. */ public int getMajor() { return this._major.intValue(); } /** * Returns the minor version. * * @return The minor version. */ public int getMinor() { return this._minor.intValue(); } /** * Returns the micro version. * * @return The micro version. */ public int getMicro() { return this._micro.intValue(); } /** * Returns the qualifier for this version. * * @return The qualifier for this version. Maybe <code>null</code>. */ public String getQualifier() { return this._qualifier; } /** * {@inheritDoc} */ @Override public int hashCode() { return this._str.hashCode(); } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Version other = (Version) obj; return this._str.equals(other._str); } /** * {@inheritDoc} */ @Override public String toString() { return this._str; } } /* ENDCLASS */