*** 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; } }