001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM - Initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.build.site;
011:
012: import org.eclipse.osgi.service.resolver.VersionRange;
013: import org.eclipse.pde.internal.build.IBuildPropertiesConstants;
014: import org.eclipse.pde.internal.build.IPDEBuildConstants;
015: import org.eclipse.update.core.*;
016: import org.osgi.framework.Version;
017:
018: public class ReachablePlugin implements Comparable {
019: private static final Version GENERIC_VERSION = new Version(
020: IPDEBuildConstants.GENERIC_VERSION_NUMBER);
021: private static final Version MAX_VERSION = new Version(
022: Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
023: public static final VersionRange WIDEST_RANGE = new VersionRange(
024: new Version(0, 0, 0), true, MAX_VERSION, true);
025:
026: private String id;
027: private VersionRange range;
028:
029: public ReachablePlugin(String id, VersionRange range) {
030: this .id = id;
031: this .range = range;
032: }
033:
034: public ReachablePlugin(IPluginEntry entry) {
035: id = entry.getVersionedIdentifier().getIdentifier();
036: Version version = new Version(entry.getVersionedIdentifier()
037: .getVersion().toString());
038: if (version.equals(GENERIC_VERSION)) {
039: range = WIDEST_RANGE;
040: } else if (version.getQualifier().endsWith(
041: IBuildPropertiesConstants.PROPERTY_QUALIFIER)) {
042: if (version.getMicro() == 0) {
043: range = new VersionRange(new Version(
044: version.getMajor(), version.getMinor(), 0),
045: true, new Version(version.getMajor(), version
046: .getMinor() + 1, 0), false);
047: } else {
048: range = new VersionRange(new Version(
049: version.getMajor(), version.getMinor(), version
050: .getMicro()), true, new Version(version
051: .getMajor(), version.getMinor(), version
052: .getMicro() + 1), false);
053: }
054: } else {
055: range = new VersionRange(version, true, version, true);
056: }
057: }
058:
059: public ReachablePlugin(IImport existingImport) {
060: id = existingImport.getVersionedIdentifier().getIdentifier();
061: range = constructRange(new Version(existingImport
062: .getVersionedIdentifier().toString()), existingImport
063: .getRule());
064: }
065:
066: private VersionRange constructRange(Version initialValue,
067: int ruleCode) {
068: switch (ruleCode) {
069: case IUpdateConstants.RULE_NONE:
070: case IUpdateConstants.RULE_EQUIVALENT: //[1.0.0, 1.1.0)
071: return new VersionRange(initialValue, true, new Version(
072: initialValue.getMajor(),
073: initialValue.getMinor() + 1, 0), false);
074:
075: case IUpdateConstants.RULE_PERFECT: //[1.0.0, 1.0.0]
076: return new VersionRange(initialValue, true, initialValue,
077: true);
078:
079: case IUpdateConstants.RULE_COMPATIBLE: //[1.1.0, 2.0.0)
080: return new VersionRange(initialValue, true, new Version(
081: initialValue.getMajor() + 1, 0, 0), false);
082:
083: case IUpdateConstants.RULE_GREATER_OR_EQUAL://[1.0.0, 999.999.999)
084: return new VersionRange(initialValue, true, new Version(
085: Integer.MAX_VALUE, Integer.MAX_VALUE,
086: Integer.MAX_VALUE), true);
087: default:
088: return null;
089: }
090:
091: }
092:
093: public String getId() {
094: return id;
095: }
096:
097: public VersionRange getRange() {
098: return range;
099: }
100:
101: public int compareTo(Object o) {
102: if (o instanceof ReachablePlugin) {
103: ReachablePlugin toCompare = (ReachablePlugin) o;
104: int result = id.compareTo(toCompare.id);
105: if (result != 0)
106: return result;
107: //We want the object with the widest version range to sort first
108: result = substract(toCompare.range.getMaximum(),
109: toCompare.range.getMinimum()).compareTo(
110: substract(range.getMaximum(), range.getMinimum()));
111: if (result != 0)
112: return result;
113: if (this .equals(o))
114: return 0;
115: result = range.getMinimum().compareTo(
116: toCompare.range.getMaximum());
117: if (result != 0)
118: return result;
119: //Give up
120: return -1;
121: }
122: return -1;
123: }
124:
125: private Version substract(Version v1, Version v2) { //v1 - v2 where v1 is always greater or equals to v2
126: int major, minor, micro = 0;
127: int carry = 0;
128: if (v1.getMicro() < v2.getMicro()) {
129: micro = Integer.MAX_VALUE - v2.getMicro() + v1.getMicro();
130: carry = 1;
131: } else {
132: micro = v1.getMicro() - v2.getMicro();
133: carry = 0;
134: }
135: if (v1.getMinor() < v2.getMinor() + carry) {
136: minor = Integer.MAX_VALUE - (v2.getMinor() + carry)
137: + v1.getMinor();
138: carry = 1;
139: } else {
140: minor = v1.getMinor() - (v2.getMinor() + carry);
141: carry = 0;
142: }
143: if (v1.getMajor() < v2.getMajor() + carry) {
144: major = Integer.MAX_VALUE - (v2.getMajor() + carry)
145: + v1.getMajor();
146: carry = 1;
147: } else {
148: major = v1.getMajor() - (v2.getMajor() + carry);
149: carry = 0;
150: }
151: return new Version(major, minor, micro);
152: }
153:
154: public boolean equals(Object obj) {
155: if (obj instanceof ReachablePlugin) {
156: ReachablePlugin toCompare = (ReachablePlugin) obj;
157: if (!id.equals(toCompare.id))
158: return false;
159: if (range.getIncludeMinimum() != toCompare.range
160: .getIncludeMinimum())
161: return false;
162: if (range.getIncludeMaximum() != toCompare.range
163: .getIncludeMaximum())
164: return false;
165: return range.getMinimum().equals(
166: toCompare.range.getMinimum())
167: && range.getMaximum().equals(
168: toCompare.range.getMaximum());
169: }
170: return false;
171: }
172:
173: public int hashCode() {
174: return id.hashCode() + range.hashCode() * 17;
175: }
176:
177: public String toString() {
178: return id + ' ' + range.toString();
179: }
180: }
|