From 1c91522f2df6bbfc6cee2bf8b98af137b038afe2 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Tue, 8 Mar 2011 13:31:45 +0000 Subject: [PATCH] Bug 203240 - Permission of .cproject file seems not to be considered anywhere on writing data --- .../CProjectDescriptionStorageTests.java | 50 ++++++++++++------- .../CProjectDescriptionStorageManager.java | 42 +++++++++++----- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CProjectDescriptionStorageTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CProjectDescriptionStorageTests.java index 73953d76ae9..5ebb1d31739 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CProjectDescriptionStorageTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/CProjectDescriptionStorageTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Broadcom Corporation and others. + * Copyright (c) 2008, 2011 Broadcom Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -41,6 +41,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.InstanceScope; /** * Testsuite for the project description storage. This @@ -242,27 +243,32 @@ public class CProjectDescriptionStorageTests extends BaseTestCase { * @throws Exception */ public void testReadOnlyProjectDescription() throws Exception { - makeDescriptionReadOnly(); - IProject project = cProj.getProject(); - ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(project, true); - projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", true); - CoreModel.getDefault().setProjectDescription(project, projDesc); + enableSetWritableWhenHeadless(true); + try { + makeDescriptionReadOnly(); + IProject project = cProj.getProject(); + ICProjectDescription projDesc = CoreModel.getDefault().getProjectDescription(project, true); + projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", true); + CoreModel.getDefault().setProjectDescription(project, projDesc); - project.close(null); - project.open(null); + project.close(null); + project.open(null); - projDesc = CoreModel.getDefault().getProjectDescription(project, false); - assertNotNull(projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", false)); - projDesc = CoreModel.getDefault().getProjectDescription(project, true); - makeDescriptionReadOnly(); - projDesc.getDefaultSettingConfiguration().removeStorage("Temp_testing_storage"); - CoreModel.getDefault().setProjectDescription(project, projDesc); + projDesc = CoreModel.getDefault().getProjectDescription(project, false); + assertNotNull(projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", false)); + projDesc = CoreModel.getDefault().getProjectDescription(project, true); + makeDescriptionReadOnly(); + projDesc.getDefaultSettingConfiguration().removeStorage("Temp_testing_storage"); + CoreModel.getDefault().setProjectDescription(project, projDesc); - project.close(null); - project.open(null); + project.close(null); + project.open(null); - projDesc = CoreModel.getDefault().getProjectDescription(project, false); - assertNull(projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", false)); + projDesc = CoreModel.getDefault().getProjectDescription(project, false); + assertNull(projDesc.getDefaultSettingConfiguration().getStorage("Temp_testing_storage", false)); + } finally { + enableSetWritableWhenHeadless(false); + } } /* @@ -271,6 +277,14 @@ public class CProjectDescriptionStorageTests extends BaseTestCase { * */ + /** + * Enables/disables team UI preference whether validateEdit should + * set files writable if no UI context has been provided. + */ + private void enableSetWritableWhenHeadless(boolean enable) { + InstanceScope.INSTANCE.getNode("org.eclipse.team.ui").putBoolean("org.eclipse.team.ui.validate_edit_with_no_context", enable); + } + /** * makes the project description (as stored by the XmlProjectDescriptionStorage & * XmlProjectDescriptionStorage2) read-only. Does this using java.io.File deliberately. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java index e4cd4e875dd..aef28d0b209 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Broadcom Corporation and others. + * Copyright (c) 2008, 2011 Broadcom Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -16,6 +16,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -44,16 +45,17 @@ import org.eclipse.cdt.internal.core.settings.model.xml2.XmlProjectDescriptionSt import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Version; @@ -373,7 +375,7 @@ public class CProjectDescriptionStorageManager { * Helper method to ensure that a resource is writable. This means:
* - If the resource doesn't exist, it can be created (its parent is made writable)
* - If the resource exists and its a file, it's made writable
- * - If the resource exists and its a directory, it and its children + * - If the resource exists and its a directory, it and its (direct) children * are made writable * @param resource * @throws CoreException on failure @@ -390,16 +392,32 @@ public class CProjectDescriptionStorageManager { } } else { // If resource exists, ensure it and children are writable - resource.accept(new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - ResourceAttributes resAttr = resource.getResourceAttributes(); - if (resAttr.isReadOnly()) { - resAttr.setReadOnly(false); - resource.setResourceAttributes(resAttr); - } - return true; + if (resource instanceof IFile) { + if (resource.getResourceAttributes().isReadOnly()) { + IStatus result = resource.getWorkspace().validateEdit(new IFile[] { (IFile) resource }, null); + if (!result.isOK()) + throw new CoreException(result); } - }); + } else if (resource instanceof IContainer) { + ResourceAttributes resAttr = resource.getResourceAttributes(); + if (resAttr.isReadOnly()) { + resAttr.setReadOnly(false); + resource.setResourceAttributes(resAttr); + } + IResource[] members = ((IContainer) resource).members(); + List files = new ArrayList(members.length); + for (IResource member : members) { + if (member instanceof IFile && member.getResourceAttributes().isReadOnly()) { + files.add((IFile) member); + } + } + if (files.size() > 0) { + IFile[] filesToValidate = files.toArray(new IFile[files.size()]); + IStatus result = resource.getWorkspace().validateEdit(filesToValidate, null); + if (!result.isOK()) + throw new CoreException(result); + } + } } }