Fix for Bug 59899 Encoding changes need to notify clients
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java
index 362608e..8dcfe18 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Container.java
@@ -12,8 +12,10 @@
import java.util.*;
import org.eclipse.core.internal.localstore.HistoryStore;
+import org.eclipse.core.internal.utils.Policy;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
public abstract class Container extends Resource implements IContainer {
protected Container(IPath path, Workspace container) {
@@ -239,10 +241,43 @@
/* (non-Javadoc)
* @see IContainer#setDefaultCharset(String)
+ * @deprecated Replaced by {@link #setDefaultCharset(String, IProgressMonitor)} which
+ * is a workspace operation and reports changes in resource deltas.
*/
public void setDefaultCharset(String charset) throws CoreException {
ResourceInfo info = getResourceInfo(false, false);
checkAccessible(getFlags(info));
workspace.getCharsetManager().setCharsetFor(getFullPath(), charset);
}
+
+ /* (non-Javadoc)
+ * @see IContainer#setDefaultCharset(String, IProgressMonitor)
+ */
+ public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
+ monitor = Policy.monitorFor(monitor);
+ try {
+ String message = Policy.bind("resources.settingDefaultCharsetContainer", getFullPath().toString()); //$NON-NLS-1$
+ monitor.beginTask(message, Policy.totalWork);
+ // need to get the project as a scheduling rule because we might be
+ // creating a new folder/file to hold the project settings
+ final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(getProject());
+ try {
+ workspace.prepareOperation(rule, monitor);
+ ResourceInfo info = getResourceInfo(false, false);
+ checkAccessible(getFlags(info));
+ workspace.beginOperation(true);
+ // TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=59899
+ // Changing the encoding needs to notify clients.
+ workspace.getCharsetManager().setCharsetFor(getFullPath(), charset);
+ monitor.worked(Policy.opWork);
+ } catch (OperationCanceledException e) {
+ workspace.getWorkManager().operationCanceled();
+ throw e;
+ } finally {
+ workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.buildWork));
+ }
+ } finally {
+ monitor.done();
+ }
+ }
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
index e4b0152..6d2d804 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java
@@ -373,6 +373,8 @@
/* (non-Javadoc)
* @see IFile#setCharset(String)
+ * @deprecated Replaced by {@link #setCharset(String, IProgressMonitor)} which
+ * is a workspace operation and reports changes in resource deltas.
*/
public void setCharset(String newCharset) throws CoreException {
ResourceInfo info = getResourceInfo(false, false);
@@ -381,6 +383,37 @@
}
/* (non-Javadoc)
+ * @see IFile#setCharset(String, IProgressMonitor)
+ */
+ public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {
+ monitor = Policy.monitorFor(monitor);
+ try {
+ String message = Policy.bind("resources.settingCharset", getFullPath().toString()); //$NON-NLS-1$
+ monitor.beginTask(message, Policy.totalWork);
+ // need to get the project as a scheduling rule because we might be creating a new folder/file to
+ // hold the project settings
+ final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(getProject());
+ try {
+ workspace.prepareOperation(rule, monitor);
+ ResourceInfo info = getResourceInfo(false, false);
+ checkAccessible(getFlags(info));
+ workspace.beginOperation(true);
+ // TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=59899
+ // Changing the encoding needs to notify clients.
+ workspace.getCharsetManager().setCharsetFor(getFullPath(), newCharset);
+ monitor.worked(Policy.opWork);
+ } catch (OperationCanceledException e) {
+ workspace.getWorkManager().operationCanceled();
+ throw e;
+ } finally {
+ workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.buildWork));
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /* (non-Javadoc)
* @see IFile#setContents(InputStream, boolean, boolean, IProgressMonitor)
*/
public void setContents(InputStream content, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceRoot.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceRoot.java
index 2239c57..a3c8d97 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceRoot.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/WorkspaceRoot.java
@@ -12,8 +12,10 @@
import java.util.HashMap;
import org.eclipse.core.internal.utils.Assert;
+import org.eclipse.core.internal.utils.Policy;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
public class WorkspaceRoot extends Container implements IWorkspaceRoot {
/**
@@ -216,6 +218,8 @@
/**
* @see IContainer#setDefaultCharset(String)
+ * @deprecated Replaced by {@link #setDefaultCharset(String, IProgressMonitor)} which
+ * is a workspace operation and reports changes in resource deltas.
*/
public void setDefaultCharset(String charset) throws CoreException {
// directly change the Resource plugin's preference for encoding
@@ -227,6 +231,42 @@
}
/**
+ * @see IContainer#setDefaultCharset(String, IProgressMonitor)
+ */
+ public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
+ monitor = Policy.monitorFor(monitor);
+ try {
+ String message = Policy.bind("resources.settingDefaultCharsetWorkspace"); //$NON-NLS-1$
+ monitor.beginTask(message, Policy.totalWork);
+ final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
+ try {
+ workspace.prepareOperation(rule, monitor);
+ ResourceInfo info = getResourceInfo(false, false);
+ checkAccessible(getFlags(info));
+ workspace.beginOperation(true);
+
+ // TODO: https://bugs.eclipse.org/bugs/show_bug.cgi?id=59899
+ // Changing the encoding needs to notify clients.
+ // directly change the Resource plugin's preference for encoding
+ Preferences resourcesPreferences = ResourcesPlugin.getPlugin().getPluginPreferences();
+ if (charset != null)
+ resourcesPreferences.setValue(ResourcesPlugin.PREF_ENCODING, charset);
+ else
+ resourcesPreferences.setToDefault(ResourcesPlugin.PREF_ENCODING);
+
+ monitor.worked(Policy.opWork);
+ } catch (OperationCanceledException e) {
+ workspace.getWorkManager().operationCanceled();
+ throw e;
+ } finally {
+ workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.buildWork));
+ }
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
* @see IResource#setLocalTimeStamp(long)
*/
public long setLocalTimeStamp(long value) throws CoreException {
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties
index 17a5ea4..867f559 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/messages.properties
@@ -236,6 +236,9 @@
resources.savingEncoding = Could not save encoding settings.
resources.setDesc = Setting project description.
resources.setLocal = Setting resource local flag.
+resources.settingCharset = Setting charset for resource: {0}.
+resources.settingDefaultCharsetContainer = Setting default charset for resource: {0}.
+resources.settingDefaultCharsetWorkspace = Setting the default charset for the workspace.
resources.settingContents = Setting contents: {0}.
resources.shutdown = Workspace was not properly initialized or has already shutdown.
resources.shutdownProblems = Problem on shutdown.
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IContainer.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IContainer.java
index ecc1f50..a932608 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IContainer.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IContainer.java
@@ -389,16 +389,49 @@
public IFile[] findDeletedMembersWithHistory(int depth, IProgressMonitor monitor) throws CoreException;
/**
- * Sets the default charset for this container.
+ * Sets the default charset for this container. Passing a value of <code>null</code>
+ * will remove the default charset setting for this resource.
*
* @param charset a charset string, or <code>null</code>
- * @throws CoreException if this method fails Reasons include:
+ * @exception CoreException if this method fails Reasons include:
* <ul>
* <li> This resource does not exist.</li>
- * <li> An error happened while persisting this setting .</li>
+ * <li> An error happened while persisting this setting.</li>
+ * </ul>
+ * @see IContainer#getDefaultCharset()
+ * @since 3.0
+ * @deprecated Replaced by {@link #setDefaultCharset(String, IProgressMonitor)} which
+ * is a workspace operation and reports changes in resource deltas.
+ */
+ public void setDefaultCharset(String charset) throws CoreException;
+
+ /**
+ * Sets the default charset for this container. Passing a value of <code>null</code>
+ * will remove the default charset setting for this resource.
+ * <p>
+ * This method changes resources; these changes will be reported
+ * in a subsequent resource change event, including an indication
+ * that the encoding of affected resources has been changed.
+ * </p>
+ * <p>
+ * This method is long-running; progress and cancellation are provided
+ * by the given progress monitor.
+ * </p>
+ *
+ * @param charset a charset string, or <code>null</code>
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @exception OperationCanceledException if the operation is canceled.
+ * Cancelation can occur even if no progress monitor is provided.
+ * @exception CoreException if this method fails Reasons include:
+ * <ul>
+ * <li> This resource is not accessible.</li>
+ * <li> An error happened while persisting this setting.</li>
+ * <li> Resource changes are disallowed during certain types of resource change
+ * event notification. See {@link IResourceChangeEvent} for more details.</li>
* </ul>
* @see IContainer#getDefaultCharset()
* @since 3.0
*/
- public void setDefaultCharset(String charset) throws CoreException;
+ public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException;
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
index 826e146..8852b86 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java
@@ -680,18 +680,51 @@
public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException;
/**
- * Sets the charset for this file.
+ * Sets the charset for this file. Passing a value of <code>null</code>
+ * will remove the charset setting for this resource.
*
* @param newCharset a charset name, or <code>null</code>
- * @throws CoreException if this method fails. Reasons include:
+ * @exception CoreException if this method fails. Reasons include:
* <ul>
* <li> This resource does not exist.</li>
- * <li> An error happened while persisting this setting .</li>
+ * <li> An error happened while persisting this setting.</li>
+ * </ul>
+ * @see #getCharset()
+ * @since 3.0
+ * @deprecated Replaced by {@link #setCharset(String, IProgressMonitor)} which
+ * is a workspace operation and reports changes in resource deltas.
+ */
+ public void setCharset(String newCharset) throws CoreException;
+
+ /**
+ * Sets the charset for this file. Passing a value of <code>null</code>
+ * will remove the charset setting for this resource.
+ * <p>
+ * This method changes resources; these changes will be reported
+ * in a subsequent resource change event, including an indication
+ * that this file's encoding has changed.
+ * </p>
+ * <p>
+ * This method is long-running; progress and cancellation are provided
+ * by the given progress monitor.
+ * </p>
+ *
+ * @param newCharset a charset name, or <code>null</code>
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting is not desired
+ * @exception OperationCanceledException if the operation is canceled.
+ * Cancelation can occur even if no progress monitor is provided.
+ * @exception CoreException if this method fails. Reasons include:
+ * <ul>
+ * <li> This resource does not exist.</li>
+ * <li> An error happened while persisting this setting.</li>
+ * <li> Resource changes are disallowed during certain types of resource change
+ * event notification. See {@link IResourceChangeEvent} for more details.</li>
* </ul>
* @see #getCharset()
* @since 3.0
*/
- public void setCharset(String newCharset) throws CoreException;
+ public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException;
/**
* Sets the contents of this file to the bytes in the given input stream.
@@ -704,7 +737,7 @@
* <p>
* This method changes resources; these changes will be reported
* in a subsequent resource change event, including an indication
- * that this file's content have been changed.
+ * that this file's contents have been changed.
* </p>
* <p>
* This method is long-running; progress and cancellation are provided
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceDelta.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceDelta.java
index 7cef864..4745867 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceDelta.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IResourceDelta.java
@@ -166,6 +166,14 @@
public static final int DESCRIPTION = 0x80000;
/**
+ * Change constant (bit mask) indicating that the encoding of the resource has changed.
+ *
+ * @see IResourceDelta#getFlags()
+ * @since 3.0
+ */
+ public static final int ENCODING = 0x100000;
+
+ /**
* Accepts the given visitor.
* The only kinds of resource deltas visited
* are <code>ADDED</code>, <code>REMOVED</code>,
@@ -360,6 +368,7 @@
* <li><code>CONTENT</code> - The bytes contained by the resource have
* been altered, or <code>IResource.touch</code> has been called on
* the resource.</li>
+ * <li><code>ENCODING</code> - The encoding of the resource has been altered.</li>
* <li><code>DESCRIPTION</code> - The description of the project has been altered,
* or <code>IResource.touch</code> has been called on the project.
* This flag is only valid for project resources.</li>
@@ -410,6 +419,7 @@
* @return the flags
* @see IResourceDelta#CONTENT
* @see IResourceDelta#DESCRIPTION
+ * @see IResourceDelta#ENCODING
* @see IResourceDelta#OPEN
* @see IResourceDelta#MOVED_TO
* @see IResourceDelta#MOVED_FROM
diff --git a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/CharsetTest.java b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/CharsetTest.java
index da94034..a2d1c25 100644
--- a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/CharsetTest.java
+++ b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/CharsetTest.java
@@ -246,6 +246,34 @@
}
}
+ public void testBug59899() {
+ IWorkspace workspace = getWorkspace();
+ IProject project = workspace.getRoot().getProject(getUniqueString());
+ IFile file = project.getFile("file.txt");
+ IFolder folder = project.getFolder("folder");
+ ensureExistsInWorkspace(new IResource[] {file, folder}, true);
+ try {
+ file.setCharset("FOO", getMonitor());
+ } catch (CoreException e) {
+ fail("1.0", e);
+ }
+ try {
+ folder.setDefaultCharset("BAR", getMonitor());
+ } catch (CoreException e) {
+ fail("2.0", e);
+ }
+ try {
+ project.setDefaultCharset("PROJECT_CHARSET", getMonitor());
+ } catch (CoreException e) {
+ fail("3.0", e);
+ }
+ try {
+ getWorkspace().getRoot().setDefaultCharset("ROOT_CHARSET", getMonitor());
+ } catch (CoreException e) {
+ fail("4.0", e);
+ }
+ }
+
public void testFileCreation() throws CoreException {
IWorkspace workspace = getWorkspace();
IProject project = workspace.getRoot().getProject("MyProject");
@@ -368,13 +396,14 @@
ensureDoesNotExistInWorkspace(project);
}
}
+
public void testBug64503() throws CoreException {
IWorkspace workspace = getWorkspace();
IProject project = workspace.getRoot().getProject("MyProject");
try {
IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
- IContentType text = contentTypeManager.getContentType("org.eclipse.core.runtime.text");
- IFile file = project.getFile("file.txt");
+ IContentType text = contentTypeManager.getContentType("org.eclipse.core.runtime.text");
+ IFile file = project.getFile("file.txt");
ensureExistsInWorkspace(file, true);
IContentDescription description = file.getContentDescription();
assertNotNull("1.0", description);
@@ -388,7 +417,7 @@
}
} finally {
ensureDoesNotExistInWorkspace(project);
- }
- }
-
+ }
+ }
+
}
\ No newline at end of file