diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java index e888a2fb0f3..eff1d04a8f0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java @@ -286,11 +286,12 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto /** * Method to check whether the description has been modified externally. * If so the current read-only descriptor is nullified. + * It updates the cached modification stamp * @return boolean indicating whether reload is needed */ protected synchronized boolean checkExternalModification() { // If loaded, and we have cached the modification stamp, reload - long currentModificationStamp = project.getFile(ICProjectDescriptionStorageType.STORAGE_FILE_NAME).getModificationStamp(); + long currentModificationStamp = getModificationStamp(project.getFile(ICProjectDescriptionStorageType.STORAGE_FILE_NAME)); if (projectModificaitonStamp != currentModificationStamp) { setCurrentDescription(null, true); projectModificaitonStamp = currentModificationStamp; @@ -299,6 +300,22 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto return false; } + /** + * Gets the modification stamp for the resource. + * If the returned value has changed since last call to + * {@link #getModificationStamp(IResource)}, then the resource has changed. + * @param resource IResource to fetch modification stamp for + * @return long modification stamp + */ + protected long getModificationStamp(IResource resource) { + // The modification stamp is based on the ResourceInfo modStamp and file store modification time. Note that + // because of bug 160728 subsequent generations of resources may have the same modStamp. Until this is fixed + // the suggested solution is to use modStamp + modTime + // + // Both values are cached in resourceInfo, so this is fast. + return resource.getModificationStamp() + resource.getLocalTimeStamp(); + } + /** * Create a writable version of the description * @@ -462,7 +479,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto InternalXmlStorageElement storage = createStorage(project, ICProjectDescriptionStorageType.STORAGE_FILE_NAME, true, false, false); try { // Update the modification stamp - projectModificaitonStamp = project.getFile(ICProjectDescriptionStorageType.STORAGE_FILE_NAME).getModificationStamp(); + projectModificaitonStamp = getModificationStamp(project.getFile(ICProjectDescriptionStorageType.STORAGE_FILE_NAME)); CProjectDescription des = new CProjectDescription(project, new XmlStorage(storage), storage, true, false); try { setThreadLocalProjectDesc(des); @@ -571,7 +588,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto } else { projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ } - return projectFile.getModificationStamp(); + return getModificationStamp(projectFile); } finally { Job.getJobManager().endRule(rule); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml2/XmlProjectDescriptionStorage2.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml2/XmlProjectDescriptionStorage2.java index 8a7493a7120..09c487c4439 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml2/XmlProjectDescriptionStorage2.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml2/XmlProjectDescriptionStorage2.java @@ -90,13 +90,15 @@ public class XmlProjectDescriptionStorage2 extends XmlProjectDescriptionStorage try { project.getFolder(STORAGE_FOLDER_NAME).accept(new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) throws CoreException { - if (modificationMap.containsKey(proxy.getName())) - if (modificationMap.get(proxy.getName()) != proxy.getModificationStamp()) { + if (modificationMap.containsKey(proxy.getName())) { + long modStamp = getModificationStamp(proxy.requestResource()); + if (modificationMap.get(proxy.getName()) != modStamp) { // There may be old storages in here, ensure we don't infinite reload... - modificationMap.put(proxy.getName(), proxy.getModificationStamp()); + modificationMap.put(proxy.getName(), modStamp); setCurrentDescription(null, true); needReload[0] = true; } + } return true; } }, IResource.NONE); @@ -134,7 +136,8 @@ public class XmlProjectDescriptionStorage2 extends XmlProjectDescriptionStorage currEl.getAttribute(EXTERNAL_CELEMENT_KEY), reCreate, createEmptyIfNotFound, readOnly); // Update the modification stamp - modificationMap.put(currEl.getAttribute(EXTERNAL_CELEMENT_KEY), project.getFolder(STORAGE_FOLDER_NAME).getFile(currEl.getAttribute(EXTERNAL_CELEMENT_KEY)).getModificationStamp()); + modificationMap.put(currEl.getAttribute(EXTERNAL_CELEMENT_KEY), + getModificationStamp(project.getFolder(STORAGE_FOLDER_NAME).getFile(currEl.getAttribute(EXTERNAL_CELEMENT_KEY)))); ICStorageElement currParent = currEl.getParent(); // Get the storageModule element in the new Document