Copyright (c) 2000, 2015 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
Sergey Prigogin (Google) - use parameterized types (bug 442021)
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google) - use parameterized types (bug 442021)
*******************************************************************************/
package org.eclipse.core.runtime;
import java.util.StringTokenizer;
import java.util.Vector;
import org.eclipse.core.internal.runtime.CommonMessages;
import org.eclipse.core.internal.runtime.IRuntimeConstants;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Version;
Version identifier for a plug-in. In its string representation,
it consists of up to 4 tokens separated by a decimal point.
The first 3 tokens are positive integer numbers, the last token
is an uninterpreted string (no whitespace characters allowed).
For example, the following are valid version identifiers
(as strings):
0.0.0
1.0.127564
3.7.2.build-127J
1.9
(interpreted as 1.9.0
)
3
(interpreted as 3.0.0
)
The version identifier can be decomposed into a major, minor,
service level component and qualifier components. A difference
in the major component is interpreted as an incompatible version
change. A difference in the minor (and not the major) component
is interpreted as a compatible version change. The service
level component is interpreted as a cumulative and compatible
service update of the minor version component. The qualifier is
not interpreted, other than in version comparisons. The
qualifiers are compared using lexicographical string comparison.
Version identifiers can be matched as perfectly equal, equivalent,
compatible or greaterOrEqual.
This class can be used without OSGi running.
Clients may instantiate; not intended to be subclassed by clients.
See Also: - compareTo.compareTo(String)
Deprecated: clients should use Version
instead
/**
* <p>
* Version identifier for a plug-in. In its string representation,
* it consists of up to 4 tokens separated by a decimal point.
* The first 3 tokens are positive integer numbers, the last token
* is an uninterpreted string (no whitespace characters allowed).
* For example, the following are valid version identifiers
* (as strings):
* </p>
* <ul>
* <li><code>0.0.0</code></li>
* <li><code>1.0.127564</code></li>
* <li><code>3.7.2.build-127J</code></li>
* <li><code>1.9</code> (interpreted as <code>1.9.0</code>)</li>
* <li><code>3</code> (interpreted as <code>3.0.0</code>)</li>
* </ul>
* <p>
* The version identifier can be decomposed into a major, minor,
* service level component and qualifier components. A difference
* in the major component is interpreted as an incompatible version
* change. A difference in the minor (and not the major) component
* is interpreted as a compatible version change. The service
* level component is interpreted as a cumulative and compatible
* service update of the minor version component. The qualifier is
* not interpreted, other than in version comparisons. The
* qualifiers are compared using lexicographical string comparison.
* </p>
* <p>
* Version identifiers can be matched as perfectly equal, equivalent,
* compatible or greaterOrEqual.
* </p><p>
* This class can be used without OSGi running.
* </p><p>
* Clients may instantiate; not intended to be subclassed by clients.
* </p>
* @see java.lang.String#compareTo(java.lang.String)
* @deprecated clients should use {@link org.osgi.framework.Version} instead
*/
@Deprecated
public final class PluginVersionIdentifier {
private Version version;
private static final String SEPARATOR = "."; //$NON-NLS-1$
Creates a plug-in version identifier from its components.
Params: - major – major component of the version identifier
- minor – minor component of the version identifier
- service – service update component of the version identifier
/**
* Creates a plug-in version identifier from its components.
*
* @param major major component of the version identifier
* @param minor minor component of the version identifier
* @param service service update component of the version identifier
*/
public PluginVersionIdentifier(int major, int minor, int service) {
this(major, minor, service, null);
}
Creates a plug-in version identifier from its components.
Params: - major – major component of the version identifier
- minor – minor component of the version identifier
- service – service update component of the version identifier
- qualifier – qualifier component of the version identifier.
Qualifier characters that are not a letter or a digit are replaced.
/**
* Creates a plug-in version identifier from its components.
*
* @param major major component of the version identifier
* @param minor minor component of the version identifier
* @param service service update component of the version identifier
* @param qualifier qualifier component of the version identifier.
* Qualifier characters that are not a letter or a digit are replaced.
*/
public PluginVersionIdentifier(int major, int minor, int service, String qualifier) {
// Do the test outside of the assert so that they 'Policy.bind'
// will not be evaluated each time (including cases when we would
// have passed by the assert).
if (major < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMajor, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
if (minor < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMinor, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
if (service < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveService, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
this.version = new Version(major, minor, service, qualifier);
}
Creates a plug-in version identifier from the given string.
The string representation consists of up to 4 tokens
separated by decimal point.
For example, the following are valid version identifiers
(as strings):
0.0.0
1.0.127564
3.7.2.build-127J
1.9
(interpreted as 1.9.0
)
3
(interpreted as 3.0.0
)
Params: - versionId – string representation of the version identifier.
Qualifier characters that are not a letter or a digit are replaced.
/**
* Creates a plug-in version identifier from the given string.
* The string representation consists of up to 4 tokens
* separated by decimal point.
* For example, the following are valid version identifiers
* (as strings):
* <ul>
* <li><code>0.0.0</code></li>
* <li><code>1.0.127564</code></li>
* <li><code>3.7.2.build-127J</code></li>
* <li><code>1.9</code> (interpreted as <code>1.9.0</code>)</li>
* <li><code>3</code> (interpreted as <code>3.0.0</code>)</li>
* </ul>
*
* @param versionId string representation of the version identifier.
* Qualifier characters that are not a letter or a digit are replaced.
*/
public PluginVersionIdentifier(String versionId) {
Object[] parts = parseVersion(versionId);
version = new Version(((Integer) parts[0]).intValue(), ((Integer) parts[1]).intValue(), ((Integer) parts[2]).intValue(), (String) parts[3]);
}
Validates the given string as a plug-in version identifier.
Params: - version – the string to validate
Returns: a status object with code IStatus.OK
if
the given string is valid as a plug-in version identifier, otherwise a status
object indicating what is wrong with the string Since: 2.0
/**
* Validates the given string as a plug-in version identifier.
*
* @param version the string to validate
* @return a status object with code <code>IStatus.OK</code> if
* the given string is valid as a plug-in version identifier, otherwise a status
* object indicating what is wrong with the string
* @since 2.0
*/
public static IStatus validateVersion(String version) {
try {
parseVersion(version);
} catch (RuntimeException e) {
return new Status(IStatus.ERROR, IRuntimeConstants.PI_RUNTIME, IStatus.ERROR, e.getMessage(), e);
}
return Status.OK_STATUS;
}
private static Object[] parseVersion(String versionId) {
// Do the test outside of the assert so that they 'Policy.bind'
// will not be evaluated each time (including cases when we would
// have passed by the assert).
if (versionId == null)
Assert.isNotNull(null, CommonMessages.parse_emptyPluginVersion);
String s = versionId.trim();
if (s.equals("")) //$NON-NLS-1$
Assert.isTrue(false, CommonMessages.parse_emptyPluginVersion);
if (s.startsWith(SEPARATOR))
Assert.isTrue(false, NLS.bind(CommonMessages.parse_separatorStartVersion, s));
if (s.endsWith(SEPARATOR))
Assert.isTrue(false, NLS.bind(CommonMessages.parse_separatorEndVersion, s));
if (s.contains(SEPARATOR + SEPARATOR))
Assert.isTrue(false, NLS.bind(CommonMessages.parse_doubleSeparatorVersion, s));
StringTokenizer st = new StringTokenizer(s, SEPARATOR);
Vector<String> elements = new Vector<>(4);
while (st.hasMoreTokens())
elements.addElement(st.nextToken());
int elementSize = elements.size();
if (elementSize <= 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_oneElementPluginVersion, s));
if (elementSize > 4)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_fourElementPluginVersion, s));
int[] numbers = new int[3];
try {
numbers[0] = Integer.parseInt(elements.elementAt(0));
if (numbers[0] < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMajor, s));
} catch (NumberFormatException nfe) {
Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericMajorComponent, s));
}
try {
if (elementSize >= 2) {
numbers[1] = Integer.parseInt(elements.elementAt(1));
if (numbers[1] < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMinor, s));
} else
numbers[1] = 0;
} catch (NumberFormatException nfe) {
Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericMinorComponent, s));
}
try {
if (elementSize >= 3) {
numbers[2] = Integer.parseInt(elements.elementAt(2));
if (numbers[2] < 0)
Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveService, s));
} else
numbers[2] = 0;
} catch (NumberFormatException nfe) {
Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericServiceComponent, s));
}
// "result" is a 4-element array with the major, minor, service, and qualifier
Object[] result = new Object[4];
result[0] = Integer.valueOf(numbers[0]);
result[1] = Integer.valueOf(numbers[1]);
result[2] = Integer.valueOf(numbers[2]);
if (elementSize >= 4)
result[3] = elements.elementAt(3);
else
result[3] = ""; //$NON-NLS-1$
return result;
}
Compare version identifiers for equality. Identifiers are
equal if all of their components are equal.
Params: - object – an object to compare
Returns: whether or not the two objects are equal
/**
* Compare version identifiers for equality. Identifiers are
* equal if all of their components are equal.
*
* @param object an object to compare
* @return whether or not the two objects are equal
*/
@Override
public boolean equals(Object object) {
if (!(object instanceof PluginVersionIdentifier))
return false;
PluginVersionIdentifier v = (PluginVersionIdentifier) object;
return version.equals(v.version);
}
Returns a hash code value for the object.
Returns: an integer which is a hash code value for this object.
/**
* Returns a hash code value for the object.
*
* @return an integer which is a hash code value for this object.
*/
@Override
public int hashCode() {
return version.hashCode();
}
Returns the major (incompatible) component of this
version identifier.
Returns: the major version
/**
* Returns the major (incompatible) component of this
* version identifier.
*
* @return the major version
*/
public int getMajorComponent() {
return version.getMajor();
}
Returns the minor (compatible) component of this
version identifier.
Returns: the minor version
/**
* Returns the minor (compatible) component of this
* version identifier.
*
* @return the minor version
*/
public int getMinorComponent() {
return version.getMinor();
}
Returns the service level component of this
version identifier.
Returns: the service level
/**
* Returns the service level component of this
* version identifier.
*
* @return the service level
*/
public int getServiceComponent() {
return version.getMicro();
}
Returns the qualifier component of this
version identifier.
Returns: the qualifier
/**
* Returns the qualifier component of this
* version identifier.
*
* @return the qualifier
*/
public String getQualifierComponent() {
return version.getQualifier();
}
Compares two version identifiers to see if this one is
greater than or equal to the argument.
A version identifier is considered to be greater than or equal
if its major component is greater than the argument major
component, or the major components are equal and its minor component
is greater than the argument minor component, or the
major and minor components are equal and its service component is
greater than the argument service component, or the major, minor and
service components are equal and the qualifier component is
greater than the argument qualifier component (using lexicographic
string comparison), or all components are equal.
Params: - id – the other version identifier
Returns: true
is this version identifier
is compatible with the given version identifier, and
false
otherwiseSince: 2.0
/**
* Compares two version identifiers to see if this one is
* greater than or equal to the argument.
* <p>
* A version identifier is considered to be greater than or equal
* if its major component is greater than the argument major
* component, or the major components are equal and its minor component
* is greater than the argument minor component, or the
* major and minor components are equal and its service component is
* greater than the argument service component, or the major, minor and
* service components are equal and the qualifier component is
* greater than the argument qualifier component (using lexicographic
* string comparison), or all components are equal.
* </p>
*
* @param id the other version identifier
* @return <code>true</code> is this version identifier
* is compatible with the given version identifier, and
* <code>false</code> otherwise
* @since 2.0
*/
public boolean isGreaterOrEqualTo(PluginVersionIdentifier id) {
if (id == null)
return false;
if (getMajorComponent() > id.getMajorComponent())
return true;
if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() > id.getMinorComponent()))
return true;
if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() == id.getMinorComponent()) && (getServiceComponent() > id.getServiceComponent()))
return true;
if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() == id.getMinorComponent()) && (getServiceComponent() == id.getServiceComponent()) && (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0))
return true;
return false;
}
Compares two version identifiers for compatibility.
A version identifier is considered to be compatible if its major
component equals to the argument major component, and its minor component
is greater than or equal to the argument minor component.
If the minor components are equal, than the service level of the
version identifier must be greater than or equal to the service level
of the argument identifier. If the service levels are equal, the two
version identifiers are considered to be equivalent if this qualifier is
greater or equal to the qualifier of the argument (using lexicographic
string comparison).
Params: - id – the other version identifier
Returns: true
is this version identifier
is compatible with the given version identifier, and
false
otherwise
/**
* Compares two version identifiers for compatibility.
* <p>
* A version identifier is considered to be compatible if its major
* component equals to the argument major component, and its minor component
* is greater than or equal to the argument minor component.
* If the minor components are equal, than the service level of the
* version identifier must be greater than or equal to the service level
* of the argument identifier. If the service levels are equal, the two
* version identifiers are considered to be equivalent if this qualifier is
* greater or equal to the qualifier of the argument (using lexicographic
* string comparison).
* </p>
*
* @param id the other version identifier
* @return <code>true</code> is this version identifier
* is compatible with the given version identifier, and
* <code>false</code> otherwise
*/
public boolean isCompatibleWith(PluginVersionIdentifier id) {
if (id == null)
return false;
if (getMajorComponent() != id.getMajorComponent())
return false;
if (getMinorComponent() > id.getMinorComponent())
return true;
if (getMinorComponent() < id.getMinorComponent())
return false;
if (getServiceComponent() > id.getServiceComponent())
return true;
if (getServiceComponent() < id.getServiceComponent())
return false;
if (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0)
return true;
return false;
}
Compares two version identifiers for equivalency.
Two version identifiers are considered to be equivalent if their major
and minor component equal and are at least at the same service level
as the argument. If the service levels are equal, the two version
identifiers are considered to be equivalent if this qualifier is
greater or equal to the qualifier of the argument (using lexicographic
string comparison).
Params: - id – the other version identifier
Returns: true
is this version identifier
is equivalent to the given version identifier, and
false
otherwise
/**
* Compares two version identifiers for equivalency.
* <p>
* Two version identifiers are considered to be equivalent if their major
* and minor component equal and are at least at the same service level
* as the argument. If the service levels are equal, the two version
* identifiers are considered to be equivalent if this qualifier is
* greater or equal to the qualifier of the argument (using lexicographic
* string comparison).
*
* </p>
*
* @param id the other version identifier
* @return <code>true</code> is this version identifier
* is equivalent to the given version identifier, and
* <code>false</code> otherwise
*/
public boolean isEquivalentTo(PluginVersionIdentifier id) {
if (id == null)
return false;
if (getMajorComponent() != id.getMajorComponent())
return false;
if (getMinorComponent() != id.getMinorComponent())
return false;
if (getServiceComponent() > id.getServiceComponent())
return true;
if (getServiceComponent() < id.getServiceComponent())
return false;
if (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0)
return true;
return false;
}
Compares two version identifiers for perfect equality.
Two version identifiers are considered to be perfectly equal if their
major, minor, service and qualifier components are equal
Params: - id – the other version identifier
Returns: true
is this version identifier
is perfectly equal to the given version identifier, and
false
otherwiseSince: 2.0
/**
* Compares two version identifiers for perfect equality.
* <p>
* Two version identifiers are considered to be perfectly equal if their
* major, minor, service and qualifier components are equal
* </p>
*
* @param id the other version identifier
* @return <code>true</code> is this version identifier
* is perfectly equal to the given version identifier, and
* <code>false</code> otherwise
* @since 2.0
*/
public boolean isPerfect(PluginVersionIdentifier id) {
if (id == null)
return false;
if ((getMajorComponent() != id.getMajorComponent()) || (getMinorComponent() != id.getMinorComponent()) || (getServiceComponent() != id.getServiceComponent()) || (!getQualifierComponent().equals(id.getQualifierComponent())))
return false;
return true;
}
Compares two version identifiers for order using multi-decimal
comparison.
Params: - id – the other version identifier
Returns: true
is this version identifier
is greater than the given version identifier, and
false
otherwise
/**
* Compares two version identifiers for order using multi-decimal
* comparison.
*
* @param id the other version identifier
* @return <code>true</code> is this version identifier
* is greater than the given version identifier, and
* <code>false</code> otherwise
*/
public boolean isGreaterThan(PluginVersionIdentifier id) {
if (id == null) {
if (getMajorComponent() == 0 && getMinorComponent() == 0 && getServiceComponent() == 0 && getQualifierComponent().equals("")) //$NON-NLS-1$
return false;
return true;
}
if (getMajorComponent() > id.getMajorComponent())
return true;
if (getMajorComponent() < id.getMajorComponent())
return false;
if (getMinorComponent() > id.getMinorComponent())
return true;
if (getMinorComponent() < id.getMinorComponent())
return false;
if (getServiceComponent() > id.getServiceComponent())
return true;
if (getServiceComponent() < id.getServiceComponent())
return false;
if (getQualifierComponent().compareTo(id.getQualifierComponent()) > 0)
return true;
return false;
}
Returns the string representation of this version identifier.
The result satisfies
vi.equals(new PluginVersionIdentifier(vi.toString()))
.
Returns: the string representation of this plug-in version identifier
/**
* Returns the string representation of this version identifier.
* The result satisfies
* <code>vi.equals(new PluginVersionIdentifier(vi.toString()))</code>.
*
* @return the string representation of this plug-in version identifier
*/
@Override
public String toString() {
return version.toString();
}
}