Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentType.java41
-rw-r--r--bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentTypeManager.java32
-rw-r--r--bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/FileSpec.java8
-rw-r--r--tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/IContentTypeManagerTest.java87
4 files changed, 148 insertions, 20 deletions
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentType.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentType.java
index 403b2ddd9..c140b4fdf 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentType.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentType.java
@@ -170,12 +170,16 @@ public final class ContentType implements IContentType {
if (type != FILE_EXTENSION_SPEC && type != FILE_NAME_SPEC)
throw new IllegalArgumentException("Unknown type: " + type); //$NON-NLS-1$
if (!internalAddFileSpec(fileSpec, type | SPEC_USER_DEFINED))
+ // the entry was already there, nothing to do...
return;
- // persist using preferences
+ // notify listeners
+ manager.fireContentTypeChangeEvent(this);
+ // update preferences
String key = getPreferenceKey(type);
Preferences contentTypeNode = manager.getPreferences().node(getId());
final String[] userSet = internalGetFileSpecs(type | IGNORE_PRE_DEFINED);
contentTypeNode.put(key, toListString(userSet));
+ // persist preferences
try {
contentTypeNode.flush();
} catch (BackingStoreException bse) {
@@ -472,20 +476,19 @@ public final class ContentType implements IContentType {
return false;
}
- void internalRemoveFileSpec(String fileSpec, int typeMask) {
- if (aliasTarget != null) {
- aliasTarget.internalRemoveFileSpec(fileSpec, typeMask);
- return;
- }
+ boolean internalRemoveFileSpec(String fileSpec, int typeMask) {
+ if (aliasTarget != null)
+ return aliasTarget.internalRemoveFileSpec(fileSpec, typeMask);
if (fileSpecs == null)
- return;
+ return false;
for (Iterator i = fileSpecs.iterator(); i.hasNext();) {
FileSpec spec = (FileSpec) i.next();
if ((spec.getType() == typeMask) && fileSpec.equals(spec.getText())) {
i.remove();
- return;
+ return true;
}
}
+ return false;
}
private IContentDescriber invalidateDescriber(Throwable reason) {
@@ -533,8 +536,12 @@ public final class ContentType implements IContentType {
}
if (type != FILE_EXTENSION_SPEC && type != FILE_NAME_SPEC)
throw new IllegalArgumentException("Unknown type: " + type); //$NON-NLS-1$
- internalRemoveFileSpec(fileSpec, type | SPEC_USER_DEFINED);
- // persist using preferences
+ if (!internalRemoveFileSpec(fileSpec, type | SPEC_USER_DEFINED))
+ // the entry was not there... nothing to do
+ return;
+ // notify listeners
+ manager.fireContentTypeChangeEvent(this);
+ // update preferences
String key = getPreferenceKey(type);
Preferences contentTypeNode = manager.getPreferences().node(getId());
final String[] userSet = internalGetFileSpecs(type | IGNORE_PRE_DEFINED);
@@ -542,6 +549,7 @@ public final class ContentType implements IContentType {
contentTypeNode.remove(key);
else
contentTypeNode.put(key, toListString(userSet));
+ // persist using preferences
try {
contentTypeNode.flush();
} catch (BackingStoreException bse) {
@@ -567,13 +575,22 @@ public final class ContentType implements IContentType {
* (non-Javadoc)
* @see org.eclipse.core.runtime.content.IContentType#setDefaultCharset(java.lang.String)
*/
- public void setDefaultCharset(String userCharset) throws CoreException {
- this.userCharset = userCharset;
+ public void setDefaultCharset(String newCharset) throws CoreException {
+ if (userCharset == null) {
+ if (newCharset == null)
+ return;
+ } else if (userCharset.equals(newCharset))
+ return;
+ userCharset = newCharset;
+ // notify listeners
+ manager.fireContentTypeChangeEvent(this);
+ // update preferences
Preferences contentTypeNode = manager.getPreferences().node(getId());
if (userCharset == null)
contentTypeNode.remove(PREF_DEFAULT_CHARSET);
else
contentTypeNode.put(PREF_DEFAULT_CHARSET, userCharset);
+ // persist preferences
try {
contentTypeNode.flush();
} catch (BackingStoreException bse) {
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentTypeManager.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentTypeManager.java
index 8f00c3010..0b4f95a9c 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentTypeManager.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/ContentTypeManager.java
@@ -13,6 +13,7 @@ package org.eclipse.core.internal.content;
import java.io.*;
import java.util.*;
import org.eclipse.core.internal.runtime.InternalPlatform;
+import org.eclipse.core.internal.runtime.ListenerList;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.*;
import org.eclipse.core.runtime.preferences.InstanceScope;
@@ -28,6 +29,13 @@ public class ContentTypeManager implements IContentTypeManager {
private ContentTypeBuilder builder;
private Map catalog = new HashMap();
+ /**
+ * List of registered listeners (element type:
+ * <code>IContentTypeChangeListener</code>).
+ * These listeners are to be informed when
+ * something in a content type changes.
+ */
+ protected ListenerList contentTypeListeners = new ListenerList();
// a comparator used when resolving conflicts (two types associated to the same spec)
private Comparator conflictComparator = new Comparator() {
@@ -375,15 +383,31 @@ public class ContentTypeManager implements IContentTypeManager {
* @see IContentTypeManager#addContentTypeChangeListener(IContentTypeChangeListener)
*/
public void addContentTypeChangeListener(IContentTypeChangeListener listener) {
- // TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=67884
- // Content type change events not reported
+ contentTypeListeners.add(listener);
}
/* (non-Javadoc)
* @see IContentTypeManager#removeContentTypeChangeListener(IContentTypeChangeListener)
*/
public void removeContentTypeChangeListener(IContentTypeChangeListener listener) {
- // TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=67884
- // Content type change events not reported
+ contentTypeListeners.remove(listener);
+ }
+
+ public void fireContentTypeChangeEvent(ContentType type) {
+ Object[] listeners = this.contentTypeListeners.getListeners();
+ for (int i = 0; i < listeners.length; i++) {
+ final ContentTypeChangeEvent event = new ContentTypeChangeEvent(type);
+ final IContentTypeChangeListener listener = (IContentTypeChangeListener) listeners[i];
+ ISafeRunnable job = new ISafeRunnable() {
+ public void handleException(Throwable exception) {
+ // already logged in Platform#run()
+ }
+
+ public void run() throws Exception {
+ listener.contentTypeChanged(event);
+ }
+ };
+ Platform.run(job);
+ }
}
} \ No newline at end of file
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/FileSpec.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/FileSpec.java
index c689b5c31..c0a0d4ff4 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/FileSpec.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/content/FileSpec.java
@@ -34,7 +34,7 @@ class FileSpec {
return type;
}
- public int getBasicType() {
+ public static int getBasicType(int type) {
return BASIC_TYPE & type;
}
@@ -42,11 +42,11 @@ class FileSpec {
if (!(other instanceof FileSpec))
return false;
FileSpec otherFileSpec = (FileSpec) other;
- return getBasicType() == otherFileSpec.getBasicType() && text.equalsIgnoreCase(otherFileSpec.text);
+ return equals(text, otherFileSpec.getType());
}
- public boolean equals(String text, int basicType) {
- return getBasicType() == basicType && this.text.equalsIgnoreCase(text);
+ public boolean equals(String text, int otherType) {
+ return getBasicType(type) == getBasicType(otherType) && this.text.equalsIgnoreCase(text);
}
public int hashCode() {
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/IContentTypeManagerTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/IContentTypeManagerTest.java
index 9edd15ab9..21a34e3d7 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/IContentTypeManagerTest.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/content/IContentTypeManagerTest.java
@@ -11,11 +11,13 @@
package org.eclipse.core.tests.runtime.content;
import java.io.*;
+import java.util.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.content.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.*;
+import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.core.tests.harness.BundleTestingHelper;
import org.eclipse.core.tests.harness.EclipseWorkspaceTest;
@@ -651,4 +653,89 @@ public class IContentTypeManagerTest extends EclipseWorkspaceTest {
text.removeFileSpec("foo.bar", IContentType.FILE_NAME_SPEC);
}
}
+
+ class ContentTypeChangeTracer implements IContentTypeManager.IContentTypeChangeListener {
+ private Set changed = new HashSet();
+
+ public void contentTypeChanged(ContentTypeChangeEvent event) {
+ changed.add(event.getContentType());
+ }
+
+ public Collection getChanges() {
+ return changed;
+ }
+
+ public void reset() {
+ changed.clear();
+ }
+
+ public boolean isOnlyChange(IContentType myType) {
+ return changed.size() == 1 && changed.contains(myType);
+ }
+ }
+
+ public void testEvents() {
+ IContentTypeManager contentTypeManager = Platform.getContentTypeManager();
+ IContentType myType = contentTypeManager.getContentType(RuntimeTestsPlugin.PI_RUNTIME_TESTS + ".myContent");
+ assertNotNull("0.9", myType);
+
+ ContentTypeChangeTracer tracer;
+
+ tracer = new ContentTypeChangeTracer();
+ contentTypeManager.addContentTypeChangeListener(tracer);
+
+ // add a file spec and check event
+ try {
+ myType.addFileSpec("another.file.name", IContentType.FILE_NAME_SPEC);
+ } catch (CoreException e) {
+ fail("1.0", e);
+ }
+ assertTrue("1.1", tracer.isOnlyChange(myType));
+
+ // remove a non-existing file spec - should not cause an event to be fired
+ tracer.reset();
+ try {
+ myType.removeFileSpec("another.file.name", IContentType.FILE_EXTENSION_SPEC);
+ } catch (CoreException e) {
+ fail("2.0", e);
+ }
+ assertTrue("2.1", !tracer.isOnlyChange(myType));
+
+ // add a file spec again and check no event is generated
+ tracer.reset();
+ try {
+ myType.addFileSpec("another.file.name", IContentType.FILE_NAME_SPEC);
+ } catch (CoreException e) {
+ fail("3.0", e);
+ }
+ assertTrue("3.1", !tracer.isOnlyChange(myType));
+
+ // remove a file spec and check event
+ tracer.reset();
+ try {
+ myType.removeFileSpec("another.file.name", IContentType.FILE_NAME_SPEC);
+ } catch (CoreException e) {
+ fail("4.0", e);
+ }
+ assertTrue("4.1", tracer.isOnlyChange(myType));
+
+ // change the default charset and check event
+ tracer.reset();
+ try {
+ myType.setDefaultCharset("FOO");
+ } catch (CoreException e) {
+ fail("5.0", e);
+ }
+ assertTrue("5.1", tracer.isOnlyChange(myType));
+
+ // set the default charset to the same - no event should be generated
+ tracer.reset();
+ try {
+ myType.setDefaultCharset("FOO");
+ } catch (CoreException e) {
+ fail("6.0", e);
+ }
+ assertTrue("6.1", !tracer.isOnlyChange(myType));
+
+ }
} \ No newline at end of file

Back to the top