Bug 521490 - Handle RESOURCE_NOT_FOUND error

When the resource is deleted on the file system and out of synch with
the workspace, a ResourceException is raised while trying to load the
contents. For this case no error has to be raised and the method should
return gracefully like in the previous check for existence of the
resource.

Change-Id: Ic37c767ae38d665ecf4a47a1f4da7d5decd1dcd6
Signed-off-by: Karsten Thoms <karsten.thoms@itemis.de>
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java
index 8ffb91a..e8772e9 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/ProjectPreferences.java
@@ -14,6 +14,7 @@
 package org.eclipse.core.internal.resources;
 
 import java.io.*;
+import java.text.MessageFormat;
 import java.util.*;
 import org.eclipse.core.internal.preferences.*;
 import org.eclipse.core.internal.utils.*;
@@ -166,9 +167,14 @@
 			input = new BufferedInputStream(file.getContents(true));
 			result.load(input);
 		} catch (CoreException e) {
-			String message = NLS.bind(Messages.preferences_loadException, file.getFullPath());
-			log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
-			throw new BackingStoreException(message);
+			if (e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) {
+				if (Policy.DEBUG_PREFERENCES)
+					Policy.debug(MessageFormat.format("Preference file {0} does not exist.", file.getFullPath())); //$NON-NLS-1$
+			} else {
+				String message = NLS.bind(Messages.preferences_loadException, file.getFullPath());
+				log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
+				throw new BackingStoreException(message);
+			}
 		} catch (IOException e) {
 			String message = NLS.bind(Messages.preferences_loadException, file.getFullPath());
 			log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
@@ -509,6 +515,11 @@
 			convertFromProperties(this, fromDisk, true);
 			loadedNodes.add(absolutePath());
 		} catch (CoreException e) {
+			if (e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) {
+				if (Policy.DEBUG_PREFERENCES)
+					Policy.debug("Preference file does not exist for node: " + absolutePath()); //$NON-NLS-1$
+				return;
+			}
 			if (reportProblems) {
 				String message = NLS.bind(Messages.preferences_loadException, localFile.getFullPath());
 				log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, e));
diff --git a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/ProjectPreferencesTest.java b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/ProjectPreferencesTest.java
index ca7031e..6caeb56 100644
--- a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/ProjectPreferencesTest.java
+++ b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/ProjectPreferencesTest.java
@@ -16,6 +16,7 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import org.eclipse.core.internal.preferences.EclipsePreferences;
+import org.eclipse.core.internal.resources.ProjectPreferences;
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.content.IContentType;
@@ -1561,4 +1562,32 @@
 		project1.delete(true, getMonitor());
 		project2.delete(true, getMonitor());
 	}
+
+	public void testDeleteOnFilesystemAndLoad() throws CoreException, BackingStoreException {
+		String nodeA = "nodeA";
+		String key = "key";
+		String value = "value";
+
+		IProject project1 = getProject(getUniqueString());
+		project1.create(getMonitor());
+		project1.open(getMonitor());
+
+		Preferences prefs1 = new ProjectScope(project1).getNode(nodeA);
+		prefs1.put(key, value);
+		prefs1.flush();
+
+		IFile prefsFile = project1.getFile(".settings/nodeA.prefs");
+		File settingsFile = new File(prefsFile.getLocationURI());
+		assertTrue(settingsFile.exists());
+
+		ProjectPreferences.updatePreferences(prefsFile);
+
+		settingsFile.delete(); // delete the preference file on file system
+		assertFalse(settingsFile.exists());
+
+		// will cause a FNFE in FileSystemResourceManager#read, see bug 521490
+		// but it should be handled silently
+		ProjectPreferences.updatePreferences(prefsFile);
+	}
+
 }