*** empty log message ***
diff --git a/bundles/org.eclipse.core.runtime/.options b/bundles/org.eclipse.core.runtime/.options
index 2418841..649b2a0 100644
--- a/bundles/org.eclipse.core.runtime/.options
+++ b/bundles/org.eclipse.core.runtime/.options
@@ -8,10 +8,10 @@
org.eclipse.core.runtime/debug/context=false
# Prints time taken by Plugin constructors and startup() methods.
-org.eclipse.core.runtime/timing/startup=false
+org.eclipse.core.runtime/debug/startup=false
# Prints time taken by Plugin.shutdown() methods.
-org.eclipse.core.runtime/timing/shutdown=false
+org.eclipse.core.runtime/debug/shutdown=false
# Turn on debugging for the registry.
org.eclipse.core.runtime/registry/debug=false
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/PluginRegistry.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/PluginRegistry.java
index 54fb8df..971db47 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/PluginRegistry.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/PluginRegistry.java
@@ -191,9 +191,11 @@
}
public void saveRegistry() throws IOException {
IPath path = InternalPlatform.getMetaArea().getRegistryPath();
+ IPath tempPath = InternalPlatform.getMetaArea().getBackupFilePathFor(path);
+
DataOutputStream output = null;
try {
- output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path.toFile())));
+ output = new DataOutputStream(new BufferedOutputStream(new SafeFileOutputStream(path.toOSString(),tempPath.toOSString())));
} catch (IOException ioe) {
String message = Policy.bind("meta.unableToCreateCache");
IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, Platform.PLUGIN_ERROR, message, ioe);
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/RegistryLoader.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/RegistryLoader.java
index b5f9a02..827645a 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/RegistryLoader.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/plugins/RegistryLoader.java
@@ -8,6 +8,7 @@
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Properties;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.internal.runtime.Policy;
@@ -124,6 +125,7 @@
PluginModel entry = processManifestFile(location);
if (entry == null)
return false;
+ entry.setVersion(getQualifiedVersion(entry, location)); // check for version qualifier
if (entry instanceof PluginDescriptorModel) {
if (entry.getId() == null || entry.getVersion() == null) {
return parseProblem(Policy.bind("parse.nullPluginIdentifier", location.toString()));
@@ -150,4 +152,33 @@
InternalPlatform.addLastModifiedTime(location.getFile(), new File(location.getFile()).lastModified());
return true;
}
+private String getQualifiedVersion(PluginModel entry, URL base) {
+ if (entry == null || entry.getVersion() == null || entry.getId() == null)
+ return null;
+
+ InputStream is = null;
+ try {
+ // check to see if we have buildmanifest.properties for this plugin
+ URL manifest = null;
+ manifest = new URL(base, "buildmanifest.properties");
+ Properties props = new Properties();
+ is = manifest.openStream();
+ props.load(is);
+
+ // lookup qualifier for this plugin and "morph" the identifier if needed
+ String key = "plugin@"+entry.getId();
+ String qualifier = props.getProperty(key);
+ if (qualifier == null)
+ return entry.getVersion();
+ PluginVersionIdentifier v = new PluginVersionIdentifier(entry.getVersion());
+ if (!v.getQualifierComponent().equals(""))
+ return entry.getVersion();
+ else
+ return (new PluginVersionIdentifier(v.getMajorComponent(), v.getMinorComponent(), v.getServiceComponent(), qualifier)).toString();
+ } catch(Exception e) {
+ return entry.getVersion();
+ } finally {
+ if (is != null) try { is.close(); } catch(IOException e) {}
+ }
+}
}
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
index 9874ddc..9b68aa0 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/runtime/InternalPlatform.java
@@ -62,8 +62,8 @@
// execution options
private static final String OPTION_DEBUG = Platform.PI_RUNTIME + "/debug";
private static final String OPTION_DEBUG_SYSTEM_CONTEXT = Platform.PI_RUNTIME + "/debug/context";
- private static final String OPTION_DEBUG_STARTUP = Platform.PI_RUNTIME + "/timing/startup";
- private static final String OPTION_DEBUG_SHUTDOWN = Platform.PI_RUNTIME + "/timing/shutdown";
+ private static final String OPTION_DEBUG_STARTUP = Platform.PI_RUNTIME + "/debug/startup";
+ private static final String OPTION_DEBUG_SHUTDOWN = Platform.PI_RUNTIME + "/debug/shutdown";
private static final String OPTION_DEBUG_PLUGINS = Platform.PI_RUNTIME + "/registry/debug";
private static final String OPTION_DEBUG_PLUGINS_DUMP = Platform.PI_RUNTIME + "/registry/debug/dump";
@@ -645,6 +645,7 @@
InternalFactory factory = new InternalFactory(problems);
IPath path = getMetaArea().getRegistryPath();
+ IPath tempPath = getMetaArea().getBackupFilePathFor(path);
DataInputStream input = null;
registry = null;
// augment the plugin path with any additional platform entries
@@ -652,7 +653,7 @@
URL[] augmentedPluginPath = getAugmentedPluginPath(pluginPath);
if (path.toFile().exists() && cacheRegistry) {
try {
- input = new DataInputStream(new BufferedInputStream(new FileInputStream(path.toFile())));
+ input = new DataInputStream(new BufferedInputStream(new SafeFileInputStream(path.toOSString(), tempPath.toOSString())));
try {
long start = System.currentTimeMillis();
RegistryCacheReader cacheReader = new RegistryCacheReader(factory);
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Plugin.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Plugin.java
index d207fdf..25c3d71 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Plugin.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/Plugin.java
@@ -13,6 +13,7 @@
import org.eclipse.core.internal.boot.PlatformURLHandler;
import java.util.StringTokenizer;
import java.util.Vector;
+import java.util.Map;
import java.net.*;
import java.io.*;
@@ -199,6 +200,22 @@
* @return a URL for the given path or <code>null</code>
*/
public final URL find(IPath path) {
+ return find(path, null);
+}
+/**
+ * Returns a URL for the given path. Returns <code>null</code> if the URL
+ * could not be computed or created.
+ *
+ * @param path file path relative to plug-in installation location
+ * @param override map of override substitution arguments to be used for
+ * any $arg$ path elements. The map keys correspond to the substitution
+ * arguments (without the $ characters, eg. "nl" or "os"). The resulting
+ * values must be of type java.lang.String. If the map is <code>null</code>,
+ * or does not contain the required substitution argument, the default
+ * is used.
+ * @return a URL for the given path or <code>null</code>
+ */
+public final URL find(IPath path, Map override) {
URL install = getDescriptor().getInstallURL();
String first = path.segment(0);
if (first.charAt(0) != '$') {
@@ -209,34 +226,57 @@
}
IPath rest = path.removeFirstSegments(1);
if (first.equalsIgnoreCase("$nl$"))
- return findNL(install, rest);
+ return findNL(install, rest, override);
if (first.equalsIgnoreCase("$os$"))
- return findOS(install, rest);
+ return findOS(install, rest, override);
if (first.equalsIgnoreCase("$ws$"))
- return findWS(install, rest);
+ return findWS(install, rest, override);
if (first.equalsIgnoreCase("$files$"))
return null;
return null;
}
-private URL findOS(URL install, IPath path) {
- String filePath = "os/" + BootLoader.getOS() + "/" + path.toString();
+private URL findOS(URL install, IPath path, Map override) {
+ String os = null;
+ if (override != null)
+ try { // check for override
+ os = (String) override.get("os");
+ } catch (ClassCastException e) {
+ }
+ if (os == null)
+ os = BootLoader.getOS(); // use default
+ String filePath = "os/" + os + "/" + path.toString();
URL result = findInPlugin(install, filePath);
if (result != null)
return result;
return findInFragments(filePath);
}
-private URL findWS(URL install, IPath path) {
- String filePath = "ws/" + BootLoader.getWS() + "/" + path.toString();
+private URL findWS(URL install, IPath path, Map override) {
+ String ws = null;
+ if (override != null)
+ try { // check for override
+ ws = (String) override.get("ws");
+ } catch (ClassCastException e) {
+ }
+ if (ws == null)
+ ws = BootLoader.getWS(); // use default
+ String filePath = "ws/" + ws + "/" + path.toString();
URL result = findInPlugin(install, filePath);
if (result != null)
return result;
return findInFragments(filePath);
}
-private URL findNL(URL install, IPath path) {
- String nl = BootLoader.getNL();
+private URL findNL(URL install, IPath path, Map override) {
+ String nl = null;
+ if (override != null)
+ try { // check for override
+ nl = (String) override.get("nl");
+ } catch (ClassCastException e) {
+ }
+ if (nl == null)
+ nl = BootLoader.getNL(); // use default
URL result = null;
boolean done = false;
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/PluginVersionIdentifier.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/PluginVersionIdentifier.java
index 2244a93..3a3d2c3 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/PluginVersionIdentifier.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/runtime/PluginVersionIdentifier.java
@@ -12,25 +12,29 @@
/**
* <p>
* Version identifier for a plug-in. In its string representation,
- * it consists of up to 3 positive integer numbers separated by decimal point.
+ * 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):
* <ul>
* <li><code>0.0.0</code></li>
* <li><code>1.0.127564</code></li>
- * <li><code>3.7.2</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>
* <p>
- * The version identifier can be decomposed into a major, minor
- * and service level component. 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 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,
@@ -40,12 +44,14 @@
* Clients may instantiate; not intended to be subclassed by clients.
* </p>
* @see IPluginDescriptor#getVersionIdentifier
+ * @see java.lang.String#compareTo
*/
public final class PluginVersionIdentifier {
- private int major = 0;
+ private int major = 0;
private int minor = 0;
private int service = 0;
+ private String qualifier = "";
private static final String SEPARATOR = ".";
/**
@@ -56,31 +62,46 @@
* @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.
+ *
+ * @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) {
Assert.isTrue(major>=0);
Assert.isTrue(minor>=0);
Assert.isTrue(service>=0);
+ if (qualifier == null) qualifier = "";
this.major = major;
this.minor = minor;
this.service = service;
+ this.qualifier = verifyQualifier(qualifier);
}
/**
* Creates a plug-in version identifier from the given string.
- * The string represenation consists of up to 3 integer
- * numbers separated by decimal point.
+ * The string represenation 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</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>
*
- * @param versionId string representation of the version identifier
+ * @param versionId string representation of the version identifier.
+ * Qualifier characters that are not a letter or a digit are replaced.
*/
public PluginVersionIdentifier(String versionId) {
@@ -92,22 +113,23 @@
Assert.isTrue(s.indexOf(SEPARATOR+SEPARATOR)==-1);
StringTokenizer st = new StringTokenizer(s, SEPARATOR);
- Integer token;
- Vector elements = new Vector(3);
+ Vector elements = new Vector(4);
while(st.hasMoreTokens()) {
- token = new Integer((String)st.nextToken());
- Assert.isTrue(token.intValue() >= 0);
- elements.addElement(token);
+ elements.addElement(st.nextToken());
}
Assert.isTrue(elements.size()>0);
- Assert.isTrue(elements.size()<=3);
+ Assert.isTrue(elements.size()<=4);
- if (elements.size()>=1) this.major = ((Integer)elements.elementAt(0)).intValue();
- if (elements.size()>=2) this.minor = ((Integer)elements.elementAt(1)).intValue();
- if (elements.size()>=3) this.service = ((Integer)elements.elementAt(2)).intValue();
-
+ if (elements.size()>=1) this.major = (new Integer((String)elements.elementAt(0))).intValue();
+ if (elements.size()>=2) this.minor = (new Integer((String)elements.elementAt(1))).intValue();
+ if (elements.size()>=3) this.service = (new Integer((String)elements.elementAt(2))).intValue();
+ if (elements.size()>=4) this.qualifier = verifyQualifier((String)elements.elementAt(3));
+
+ Assert.isTrue(this.major >= 0);
+ Assert.isTrue(this.minor >= 0);
+ Assert.isTrue(this.service >= 0);
}
/**
* Compare version identifiers for equality. Identifiers are
@@ -120,7 +142,7 @@
if (!(object instanceof PluginVersionIdentifier))
return false;
PluginVersionIdentifier v = (PluginVersionIdentifier) object;
- return v.getMajorComponent() == major && v.getMinorComponent() == minor && v.getServiceComponent() == service;
+ return v.getMajorComponent() == major && v.getMinorComponent() == minor && v.getServiceComponent() == service && v.getQualifierComponent().equals(qualifier);
}
/**
* Returns a hash code value for the object.
@@ -128,7 +150,11 @@
* @return an integer which is a hash code value for this object.
*/
public int hashCode() {
- return major + minor + service;
+ int code = major + minor + service; // R1.0 result
+ if (qualifier.equals(""))
+ return code;
+ else
+ return code + qualifier.hashCode();
}
/**
* Returns the major (incompatible) component of this
@@ -158,16 +184,27 @@
return service;
}
/**
+ * Returns the qualifier component of this
+ * version identifier.
+ *
+ * @return the qualifier
+ */
+public String getQualifierComponent() {
+ return qualifier;
+}
+/**
* 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 or equal to the argument minor component, or the
+ * 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 all components are
- * equal.
+ * greater than the argument service component, or the major, minor and
+ * service components are equal and the qualifier component is
+ * greated than the argument qualifier component (using lexicographic
+ * string comparison), or all components are equal.
* </p>
*
* @param versionId the other version identifier
@@ -186,7 +223,12 @@
return true;
if ((major == id.getMajorComponent()) &&
(minor == id.getMinorComponent()) &&
- (service >= id.getServiceComponent()))
+ (service > id.getServiceComponent()))
+ return true;
+ if ((major == id.getMajorComponent()) &&
+ (minor == id.getMinorComponent()) &&
+ (service == id.getServiceComponent()) &&
+ (qualifier.compareTo(id.getQualifierComponent())>=0))
return true;
else
return false;
@@ -199,7 +241,10 @@
* 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.
+ * of the argument identifier. If the service levels are equal, the two
+ * version identifiers are considered to be equivalent if this qualifier is
+ * greated or equal to the qualifier of the argument (using lexicographic
+ * string comparison).
* </p>
*
* @param versionId the other version identifier
@@ -216,7 +261,11 @@
return true;
if (minor < id.getMinorComponent())
return false;
- if (service >= id.getServiceComponent())
+ if (service > id.getServiceComponent())
+ return true;
+ if (service < id.getServiceComponent())
+ return false;
+ if (qualifier.compareTo(id.getQualifierComponent())>=0)
return true;
else
return false;
@@ -226,7 +275,11 @@
* <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.
+ * as the argument. If the service levels are equal, the two version
+ * identifiers are considered to be equivalent if this qualifier is
+ * greated or equal to the qualifier of the argument (using lexicographic
+ * string comparison).
+ *
* </p>
*
* @param versionId the other version identifier
@@ -241,7 +294,11 @@
return false;
if (minor != id.getMinorComponent())
return false;
- if (service >= id.getServiceComponent())
+ if (service > id.getServiceComponent())
+ return true;
+ if (service < id.getServiceComponent())
+ return false;
+ if (qualifier.compareTo(id.getQualifierComponent())>=0)
return true;
else
return false;
@@ -250,7 +307,7 @@
* Compares two version identifiers for perfect equality.
* <p>
* Two version identifiers are considered to be perfectly equal if their
- * major, minor and service components are equal
+ * major, minor, service and qualifier components are equal
* </p>
*
* @param versionId the other version identifier
@@ -264,7 +321,8 @@
return false;
if ( (major != id.getMajorComponent()) ||
(minor != id.getMinorComponent()) ||
- (service != id.getServiceComponent()) )
+ (service != id.getServiceComponent()) ||
+ (!qualifier.equals(id.getQualifierComponent())) )
return false;
else
return true;
@@ -281,7 +339,7 @@
public boolean isGreaterThan(PluginVersionIdentifier id) {
if (id == null) {
- if (major==0 && minor==0 && service==0) return false;
+ if (major==0 && minor==0 && service==0 && qualifier.equals("")) return false;
else return true;
}
@@ -289,7 +347,9 @@
if (major < id.getMajorComponent()) return false;
if (minor > id.getMinorComponent()) return true;
if (minor < id.getMinorComponent()) return false;
- if (service > id.getServiceComponent()) return true;
+ if (service > id.getServiceComponent()) return true;
+ if (service < id.getServiceComponent()) return false;
+ if (qualifier.compareTo(id.getQualifierComponent())>0) return true;
else return false;
}
@@ -301,6 +361,22 @@
* @return the string representation of this plug-in version identifier
*/
public String toString() {
- return major+SEPARATOR+minor+SEPARATOR+service;
+ String base = major+SEPARATOR+minor+SEPARATOR+service; // R1.0 result
+ if (qualifier.equals(""))
+ return base;
+ else
+ return base + SEPARATOR + qualifier;
+}
+
+private String verifyQualifier(String s) {
+ char[] chars = s.trim().toCharArray();
+ boolean whitespace = false;
+ for(int i=0; i<chars.length; i++) {
+ if (!Character.isLetterOrDigit(chars[i])) {
+ chars[i] = '-';
+ whitespace = true;
+ }
+ }
+ return whitespace ? new String(chars) : s;
}
}