KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > runtime > PluginVersionIdentifier


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.runtime;
12
13 import java.util.StringTokenizer JavaDoc;
14 import java.util.Vector JavaDoc;
15 import org.eclipse.core.internal.runtime.CommonMessages;
16 import org.eclipse.core.internal.runtime.IRuntimeConstants;
17 import org.eclipse.osgi.util.NLS;
18 import org.osgi.framework.Version;
19
20 /**
21  * <p>
22  * Version identifier for a plug-in. In its string representation,
23  * it consists of up to 4 tokens separated by a decimal point.
24  * The first 3 tokens are positive integer numbers, the last token
25  * is an uninterpreted string (no whitespace characters allowed).
26  * For example, the following are valid version identifiers
27  * (as strings):
28  * <ul>
29  * <li><code>0.0.0</code></li>
30  * <li><code>1.0.127564</code></li>
31  * <li><code>3.7.2.build-127J</code></li>
32  * <li><code>1.9</code> (interpreted as <code>1.9.0</code>)</li>
33  * <li><code>3</code> (interpreted as <code>3.0.0</code>)</li>
34  * </ul>
35  * </p>
36  * <p>
37  * The version identifier can be decomposed into a major, minor,
38  * service level component and qualifier components. A difference
39  * in the major component is interpreted as an incompatible version
40  * change. A difference in the minor (and not the major) component
41  * is interpreted as a compatible version change. The service
42  * level component is interpreted as a cumulative and compatible
43  * service update of the minor version component. The qualifier is
44  * not interpreted, other than in version comparisons. The
45  * qualifiers are compared using lexicographical string comparison.
46  * </p>
47  * <p>
48  * Version identifiers can be matched as perfectly equal, equivalent,
49  * compatible or greaterOrEqual.
50  * </p><p>
51  * This class can be used without OSGi running.
52  * </p><p>
53  * Clients may instantiate; not intended to be subclassed by clients.
54  * </p>
55  * @see java.lang.String#compareTo(java.lang.String)
56  * @deprecated clients should use {@link org.osgi.framework.Version} instead
57  */

58 public final class PluginVersionIdentifier {
59
60     private Version version;
61     
62     private static final String JavaDoc SEPARATOR = "."; //$NON-NLS-1$
63

64     /**
65      * Creates a plug-in version identifier from its components.
66      *
67      * @param major major component of the version identifier
68      * @param minor minor component of the version identifier
69      * @param service service update component of the version identifier
70      */

71     public PluginVersionIdentifier(int major, int minor, int service) {
72         this(major, minor, service, null);
73     }
74
75     /**
76      * Creates a plug-in version identifier from its components.
77      *
78      * @param major major component of the version identifier
79      * @param minor minor component of the version identifier
80      * @param service service update component of the version identifier
81      * @param qualifier qualifier component of the version identifier.
82      * Qualifier characters that are not a letter or a digit are replaced.
83      */

84     public PluginVersionIdentifier(int major, int minor, int service, String JavaDoc qualifier) {
85         // Do the test outside of the assert so that they 'Policy.bind'
86
// will not be evaluated each time (including cases when we would
87
// have passed by the assert).
88

89         if (major < 0)
90             Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMajor, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
91         if (minor < 0)
92             Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMinor, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
93         if (service < 0)
94             Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveService, major + SEPARATOR + minor + SEPARATOR + service + SEPARATOR + qualifier));
95
96         this.version = new Version(major, minor, service, qualifier);
97     }
98
99     /**
100      * Creates a plug-in version identifier from the given string.
101      * The string representation consists of up to 4 tokens
102      * separated by decimal point.
103      * For example, the following are valid version identifiers
104      * (as strings):
105      * <ul>
106      * <li><code>0.0.0</code></li>
107      * <li><code>1.0.127564</code></li>
108      * <li><code>3.7.2.build-127J</code></li>
109      * <li><code>1.9</code> (interpreted as <code>1.9.0</code>)</li>
110      * <li><code>3</code> (interpreted as <code>3.0.0</code>)</li>
111      * </ul>
112      * </p>
113      *
114      * @param versionId string representation of the version identifier.
115      * Qualifier characters that are not a letter or a digit are replaced.
116      */

117     public PluginVersionIdentifier(String JavaDoc versionId) {
118         Object JavaDoc[] parts = parseVersion(versionId);
119         version = new Version(((Integer JavaDoc) parts[0]).intValue(), ((Integer JavaDoc) parts[1]).intValue(), ((Integer JavaDoc) parts[2]).intValue(), (String JavaDoc) parts[3]);
120     }
121
122     /**
123      * Validates the given string as a plug-in version identifier.
124      *
125      * @param version the string to validate
126      * @return a status object with code <code>IStatus.OK</code> if
127      * the given string is valid as a plug-in version identifier, otherwise a status
128      * object indicating what is wrong with the string
129      * @since 2.0
130      */

131     public static IStatus validateVersion(String JavaDoc version) {
132         try {
133             parseVersion(version);
134         } catch (RuntimeException JavaDoc e) {
135             return new Status(IStatus.ERROR, IRuntimeConstants.PI_RUNTIME, IStatus.ERROR, e.getMessage(), e);
136         }
137         return Status.OK_STATUS;
138     }
139
140     private static Object JavaDoc[] parseVersion(String JavaDoc versionId) {
141
142         // Do the test outside of the assert so that they 'Policy.bind'
143
// will not be evaluated each time (including cases when we would
144
// have passed by the assert).
145
if (versionId == null)
146             Assert.isNotNull(null, CommonMessages.parse_emptyPluginVersion);
147         String JavaDoc s = versionId.trim();
148         if (s.equals("")) //$NON-NLS-1$
149
Assert.isTrue(false, CommonMessages.parse_emptyPluginVersion);
150         if (s.startsWith(SEPARATOR))
151             Assert.isTrue(false, NLS.bind(CommonMessages.parse_separatorStartVersion, s));
152         if (s.endsWith(SEPARATOR))
153             Assert.isTrue(false, NLS.bind(CommonMessages.parse_separatorEndVersion, s));
154         if (s.indexOf(SEPARATOR + SEPARATOR) != -1)
155             Assert.isTrue(false, NLS.bind(CommonMessages.parse_doubleSeparatorVersion, s));
156
157         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s, SEPARATOR);
158         Vector JavaDoc elements = new Vector JavaDoc(4);
159
160         while (st.hasMoreTokens())
161             elements.addElement(st.nextToken());
162
163         int elementSize = elements.size();
164
165         if (elementSize <= 0)
166             Assert.isTrue(false, NLS.bind(CommonMessages.parse_oneElementPluginVersion, s));
167         if (elementSize > 4)
168             Assert.isTrue(false, NLS.bind(CommonMessages.parse_fourElementPluginVersion, s));
169
170         int[] numbers = new int[3];
171         try {
172             numbers[0] = Integer.parseInt((String JavaDoc) elements.elementAt(0));
173             if (numbers[0] < 0)
174                 Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMajor, s));
175         } catch (NumberFormatException JavaDoc nfe) {
176             Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericMajorComponent, s));
177         }
178
179         try {
180             if (elementSize >= 2) {
181                 numbers[1] = Integer.parseInt((String JavaDoc) elements.elementAt(1));
182                 if (numbers[1] < 0)
183                     Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveMinor, s));
184             } else
185                 numbers[1] = 0;
186         } catch (NumberFormatException JavaDoc nfe) {
187             Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericMinorComponent, s));
188         }
189
190         try {
191             if (elementSize >= 3) {
192                 numbers[2] = Integer.parseInt((String JavaDoc) elements.elementAt(2));
193                 if (numbers[2] < 0)
194                     Assert.isTrue(false, NLS.bind(CommonMessages.parse_postiveService, s));
195             } else
196                 numbers[2] = 0;
197         } catch (NumberFormatException JavaDoc nfe) {
198             Assert.isTrue(false, NLS.bind(CommonMessages.parse_numericServiceComponent, s));
199         }
200
201         // "result" is a 4-element array with the major, minor, service, and qualifier
202
Object JavaDoc[] result = new Object JavaDoc[4];
203         result[0] = new Integer JavaDoc(numbers[0]);
204         result[1] = new Integer JavaDoc(numbers[1]);
205         result[2] = new Integer JavaDoc(numbers[2]);
206         if (elementSize >= 4)
207             result[3] = (String JavaDoc) elements.elementAt(3);
208         else
209             result[3] = ""; //$NON-NLS-1$
210
return result;
211     }
212
213     /**
214      * Compare version identifiers for equality. Identifiers are
215      * equal if all of their components are equal.
216      *
217      * @param object an object to compare
218      * @return whether or not the two objects are equal
219      */

220     public boolean equals(Object JavaDoc object) {
221         if (!(object instanceof PluginVersionIdentifier))
222             return false;
223         PluginVersionIdentifier v = (PluginVersionIdentifier) object;
224         return version.equals(v.version);
225     }
226
227     /**
228      * Returns a hash code value for the object.
229      *
230      * @return an integer which is a hash code value for this object.
231      */

232     public int hashCode() {
233         return version.hashCode();
234     }
235
236     /**
237      * Returns the major (incompatible) component of this
238      * version identifier.
239      *
240      * @return the major version
241      */

242     public int getMajorComponent() {
243         return version.getMajor();
244     }
245
246     /**
247      * Returns the minor (compatible) component of this
248      * version identifier.
249      *
250      * @return the minor version
251      */

252     public int getMinorComponent() {
253         return version.getMinor();
254     }
255
256     /**
257      * Returns the service level component of this
258      * version identifier.
259      *
260      * @return the service level
261      */

262     public int getServiceComponent() {
263         return version.getMicro();
264     }
265
266     /**
267      * Returns the qualifier component of this
268      * version identifier.
269      *
270      * @return the qualifier
271      */

272     public String JavaDoc getQualifierComponent() {
273         return version.getQualifier();
274     }
275
276     /**
277      * Compares two version identifiers to see if this one is
278      * greater than or equal to the argument.
279      * <p>
280      * A version identifier is considered to be greater than or equal
281      * if its major component is greater than the argument major
282      * component, or the major components are equal and its minor component
283      * is greater than the argument minor component, or the
284      * major and minor components are equal and its service component is
285      * greater than the argument service component, or the major, minor and
286      * service components are equal and the qualifier component is
287      * greater than the argument qualifier component (using lexicographic
288      * string comparison), or all components are equal.
289      * </p>
290      *
291      * @param id the other version identifier
292      * @return <code>true</code> is this version identifier
293      * is compatible with the given version identifier, and
294      * <code>false</code> otherwise
295      * @since 2.0
296      */

297     public boolean isGreaterOrEqualTo(PluginVersionIdentifier id) {
298         if (id == null)
299             return false;
300         if (getMajorComponent() > id.getMajorComponent())
301             return true;
302         if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() > id.getMinorComponent()))
303             return true;
304         if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() == id.getMinorComponent()) && (getServiceComponent() > id.getServiceComponent()))
305             return true;
306         if ((getMajorComponent() == id.getMajorComponent()) && (getMinorComponent() == id.getMinorComponent()) && (getServiceComponent() == id.getServiceComponent()) && (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0))
307             return true;
308         else
309             return false;
310     }
311
312     /**
313      * Compares two version identifiers for compatibility.
314      * <p>
315      * A version identifier is considered to be compatible if its major
316      * component equals to the argument major component, and its minor component
317      * is greater than or equal to the argument minor component.
318      * If the minor components are equal, than the service level of the
319      * version identifier must be greater than or equal to the service level
320      * of the argument identifier. If the service levels are equal, the two
321      * version identifiers are considered to be equivalent if this qualifier is
322      * greater or equal to the qualifier of the argument (using lexicographic
323      * string comparison).
324      * </p>
325      *
326      * @param id the other version identifier
327      * @return <code>true</code> is this version identifier
328      * is compatible with the given version identifier, and
329      * <code>false</code> otherwise
330      */

331     public boolean isCompatibleWith(PluginVersionIdentifier id) {
332         if (id == null)
333             return false;
334         if (getMajorComponent() != id.getMajorComponent())
335             return false;
336         if (getMinorComponent() > id.getMinorComponent())
337             return true;
338         if (getMinorComponent() < id.getMinorComponent())
339             return false;
340         if (getServiceComponent() > id.getServiceComponent())
341             return true;
342         if (getServiceComponent() < id.getServiceComponent())
343             return false;
344         if (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0)
345             return true;
346         else
347             return false;
348     }
349
350     /**
351      * Compares two version identifiers for equivalency.
352      * <p>
353      * Two version identifiers are considered to be equivalent if their major
354      * and minor component equal and are at least at the same service level
355      * as the argument. If the service levels are equal, the two version
356      * identifiers are considered to be equivalent if this qualifier is
357      * greater or equal to the qualifier of the argument (using lexicographic
358      * string comparison).
359      *
360      * </p>
361      *
362      * @param id the other version identifier
363      * @return <code>true</code> is this version identifier
364      * is equivalent to the given version identifier, and
365      * <code>false</code> otherwise
366      */

367     public boolean isEquivalentTo(PluginVersionIdentifier id) {
368         if (id == null)
369             return false;
370         if (getMajorComponent() != id.getMajorComponent())
371             return false;
372         if (getMinorComponent() != id.getMinorComponent())
373             return false;
374         if (getServiceComponent() > id.getServiceComponent())
375             return true;
376         if (getServiceComponent() < id.getServiceComponent())
377             return false;
378         if (getQualifierComponent().compareTo(id.getQualifierComponent()) >= 0)
379             return true;
380         else
381             return false;
382     }
383
384     /**
385      * Compares two version identifiers for perfect equality.
386      * <p>
387      * Two version identifiers are considered to be perfectly equal if their
388      * major, minor, service and qualifier components are equal
389      * </p>
390      *
391      * @param id the other version identifier
392      * @return <code>true</code> is this version identifier
393      * is perfectly equal to the given version identifier, and
394      * <code>false</code> otherwise
395      * @since 2.0
396      */

397     public boolean isPerfect(PluginVersionIdentifier id) {
398         if (id == null)
399             return false;
400         if ((getMajorComponent() != id.getMajorComponent()) || (getMinorComponent() != id.getMinorComponent()) || (getServiceComponent() != id.getServiceComponent()) || (!getQualifierComponent().equals(id.getQualifierComponent())))
401             return false;
402         else
403             return true;
404     }
405
406     /**
407      * Compares two version identifiers for order using multi-decimal
408      * comparison.
409      *
410      * @param id the other version identifier
411      * @return <code>true</code> is this version identifier
412      * is greater than the given version identifier, and
413      * <code>false</code> otherwise
414      */

415     public boolean isGreaterThan(PluginVersionIdentifier id) {
416
417         if (id == null) {
418             if (getMajorComponent() == 0 && getMinorComponent() == 0 && getServiceComponent() == 0 && getQualifierComponent().equals("")) //$NON-NLS-1$
419
return false;
420             else
421                 return true;
422         }
423
424         if (getMajorComponent() > id.getMajorComponent())
425             return true;
426         if (getMajorComponent() < id.getMajorComponent())
427             return false;
428         if (getMinorComponent() > id.getMinorComponent())
429             return true;
430         if (getMinorComponent() < id.getMinorComponent())
431             return false;
432         if (getServiceComponent() > id.getServiceComponent())
433             return true;
434         if (getServiceComponent() < id.getServiceComponent())
435             return false;
436         if (getQualifierComponent().compareTo(id.getQualifierComponent()) > 0)
437             return true;
438         else
439             return false;
440
441     }
442
443     /**
444      * Returns the string representation of this version identifier.
445      * The result satisfies
446      * <code>vi.equals(new PluginVersionIdentifier(vi.toString()))</code>.
447      *
448      * @return the string representation of this plug-in version identifier
449      */

450     public String JavaDoc toString() {
451         return version.toString();
452     }
453
454 }
455
Popular Tags