diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index ecd0eef8dbf..bdd14109afa 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,7 @@ +2004-06-09 Alain Magloire + + Patch from Sam Rob to resolve 64022 + 2004-05-19 Alain Magloire New test provided by Sam Rob added for the resolver. diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/filetype/tests/ResolverTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/filetype/tests/ResolverTests.java index ecd0fea655c..4ed0698bbc2 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/filetype/tests/ResolverTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/filetype/tests/ResolverTests.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -22,9 +22,13 @@ import org.eclipse.cdt.core.filetype.ICFileTypeAssociation; import org.eclipse.cdt.core.filetype.ICFileTypeConstants; import org.eclipse.cdt.core.filetype.ICFileTypeResolver; import org.eclipse.cdt.core.filetype.ICLanguage; +import org.eclipse.cdt.core.filetype.IResolverChangeListener; import org.eclipse.cdt.core.filetype.IResolverModel; +import org.eclipse.cdt.core.filetype.ResolverChangeEvent; +import org.eclipse.cdt.core.filetype.ResolverDelta; import org.eclipse.cdt.core.internal.filetype.CFileType; import org.eclipse.cdt.core.internal.filetype.CFileTypeAssociation; +import org.eclipse.cdt.core.internal.filetype.CFileTypeResolver; import org.eclipse.cdt.core.internal.filetype.CLanguage; import org.eclipse.cdt.core.internal.filetype.ResolverModel; import org.eclipse.cdt.testplugin.CTestPlugin; @@ -59,6 +63,7 @@ public class ResolverTests extends TestCase { suite.addTest(new ResolverTests("testGetFileTypeAssociations")); suite.addTest(new ResolverTests("testAdd")); suite.addTest(new ResolverTests("testRemove")); + suite.addTest(new ResolverTests("testChangeNotifications")); TestSetup wrapper = new TestSetup(suite) { protected void setUp() throws Exception { @@ -137,6 +142,10 @@ public class ResolverTests extends TestCase { super(name); } + private ICFileTypeResolver createResolver() { + return new CFileTypeResolver(); + } + public final void testInternalCtors() { ICLanguage lang = null; ICFileType type = null; @@ -366,11 +375,11 @@ public class ResolverTests extends TestCase { // Set up a new resolver just for the tests // This one will only recognize '*.c', '*.h', and '*.sam' - ICFileTypeResolver resolver = model.createResolver(); + ICFileTypeResolver resolver = createResolver(); - resolver.addAssociation("*.sam", model.getFileTypeById(ICFileTypeConstants.FT_C_SOURCE)); - resolver.addAssociation("*.shari", model.getFileTypeById(ICFileTypeConstants.FT_C_HEADER)); - resolver.addAssociation("*.delainey", model.getFileTypeById(ICFileTypeConstants.FT_ASM_SOURCE)); + resolver.addAssociation(model.createAssocation("*.sam", model.getFileTypeById(ICFileTypeConstants.FT_C_SOURCE))); + resolver.addAssociation(model.createAssocation("*.shari", model.getFileTypeById(ICFileTypeConstants.FT_C_HEADER))); + resolver.addAssociation(model.createAssocation("*.delainey", model.getFileTypeById(ICFileTypeConstants.FT_ASM_SOURCE))); // Set the workspace to use the new resolver model.setResolver(resolver); @@ -426,11 +435,11 @@ public class ResolverTests extends TestCase { // Set up a new resolver just for the tests // This one will only recognize '*.c', '*.h', and '*.sam' - ICFileTypeResolver resolver = model.createResolver(); + ICFileTypeResolver resolver = createResolver(); - resolver.addAssociation("*.sam", model.getFileTypeById(ICFileTypeConstants.FT_C_SOURCE)); - resolver.addAssociation("*.shari", model.getFileTypeById(ICFileTypeConstants.FT_C_HEADER)); - resolver.addAssociation("*.delainey", model.getFileTypeById(ICFileTypeConstants.FT_ASM_SOURCE)); + resolver.addAssociation(model.createAssocation("*.sam", model.getFileTypeById(ICFileTypeConstants.FT_C_SOURCE))); + resolver.addAssociation(model.createAssocation("*.shari", model.getFileTypeById(ICFileTypeConstants.FT_C_HEADER))); + resolver.addAssociation(model.createAssocation("*.delainey", model.getFileTypeById(ICFileTypeConstants.FT_ASM_SOURCE))); // Set the workspace to use the new resolver model.setResolver(project, resolver); @@ -602,7 +611,7 @@ public class ResolverTests extends TestCase { result = workspaceResolver.removeAssociation(tha); assertFalse(result); - result = workspaceResolver.addAssociation(tha.getPattern(), tha.getType()); + result = workspaceResolver.addAssociation(tha); assertTrue(result); ICFileType thaOut = workspaceResolver.getFileType("file.aest"); @@ -614,7 +623,7 @@ public class ResolverTests extends TestCase { result = workspaceResolver.removeAssociation(tsa); assertFalse(result); - result = workspaceResolver.addAssociation(tsa.getPattern(), tsa.getType()); + result = workspaceResolver.addAssociation(tsa); assertTrue(result); ICFileType tsaOut = workspaceResolver.getFileType("file.test"); @@ -627,7 +636,7 @@ public class ResolverTests extends TestCase { result = workspaceResolver.removeAssociation(tua); assertFalse(result); - result = workspaceResolver.addAssociation(tua.getPattern(), tua.getType()); + result = workspaceResolver.addAssociation(tua); assertTrue(result); ICFileType tuaOut = workspaceResolver.getFileType("file.zest"); @@ -688,4 +697,302 @@ public class ResolverTests extends TestCase { } + class TestModelListener implements IResolverChangeListener { + private ResolverChangeEvent fEvent; + public TestModelListener() { + model.addResolverChangeListener(this); + } + public void resolverChanged(ResolverChangeEvent event) { + fEvent = event; + model.removeResolverChangeListener(this); + this.notifyAll(); + } + public ResolverChangeEvent getEvent() { + return fEvent; + } + } + + public final void testChangeNotifications() { + ResolverModel rawModel = ((ResolverModel) model); + ResolverChangeEvent event = null; + ICLanguage lang = new CLanguage(LANG_TEST, "Test Language"); + ICFileType type = new CFileType("?", model.getLanguageById("?"), "?", ICFileType.TYPE_UNKNOWN); + TestModelListener listener = null; + ResolverDelta[] deltas = null; + + // Add language + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertTrue(rawModel.addLanguage(lang)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNull(event.getResolver()); + assertEquals(1, deltas.length); + assertEquals(ResolverDelta.ELEMENT_LANGUAGE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_ADD, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNotNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Repeated addition should not result in a change event + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertFalse(rawModel.addLanguage(lang)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNull(listener.getEvent()); + + // Remove language + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertTrue(rawModel.removeLanguage(lang)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNull(event.getResolver()); + assertEquals(1, deltas.length); + assertEquals(ResolverDelta.ELEMENT_LANGUAGE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_REMOVE, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNotNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Repeated removal should not result in a change event + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertFalse(rawModel.removeLanguage(lang)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNull(listener.getEvent()); + + // Add file type + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertTrue(rawModel.addFileType(type)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNull(event.getResolver()); + assertEquals(1, deltas.length); + assertEquals(ResolverDelta.ELEMENT_FILETYPE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_ADD, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNotNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Repeated addition should not result in a change event + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertFalse(rawModel.addFileType(type)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNull(listener.getEvent()); + + // Remove file type + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertTrue(rawModel.removeFileType(type)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNull(event.getResolver()); + assertEquals(1, deltas.length); + assertEquals(ResolverDelta.ELEMENT_FILETYPE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_REMOVE, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNotNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Repeated removal should not result in a change event + + try { + listener = new TestModelListener(); + synchronized (listener) { + assertFalse(rawModel.removeFileType(type)); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNull(listener.getEvent()); + + // Test setting workspace resolver + + ICFileTypeResolver testResolver = createResolver(); + + try { + listener = new TestModelListener(); + synchronized (listener) { + model.setResolver(testResolver); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNotNull(event.getResolver()); + assertTrue(deltas.length > 1); + assertEquals(ResolverDelta.ELEMENT_WORKSPACE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_SET, deltas[0].getEventType()); + assertNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Test resetting workspace resolver + + try { + listener = new TestModelListener(); + synchronized (listener) { + model.setResolver(null); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNotNull(event.getResolver()); + assertTrue(deltas.length > 1); + assertEquals(ResolverDelta.ELEMENT_WORKSPACE, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_SET, deltas[0].getEventType()); + assertNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNull(deltas[0].getProject()); + + // Test setting project resolver + + try { + listener = new TestModelListener(); + synchronized (listener) { + model.setResolver(project, testResolver); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNotNull(event.getResolver()); + assertTrue(deltas.length > 1); + assertEquals(ResolverDelta.ELEMENT_PROJECT, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_SET, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNotNull(deltas[0].getProject()); + + // Test resetting project resolver + + try { + listener = new TestModelListener(); + synchronized (listener) { + model.setResolver(project, null); + listener.wait(3); + } + } catch (InterruptedException e) { + assertTrue(e.getMessage(), false); + } + + assertNotNull(listener.getEvent()); + + event = listener.getEvent(); + deltas = event.getDeltas(); + + assertNotNull(event.getResolver()); + assertTrue(deltas.length > 1); + assertEquals(ResolverDelta.ELEMENT_PROJECT, deltas[0].getElementType()); + assertEquals(ResolverDelta.EVENT_SET, deltas[0].getEventType()); + assertNotNull(deltas[0].getElement()); + assertNull(deltas[0].getAssociation()); + assertNull(deltas[0].getLanguage()); + assertNull(deltas[0].getFileType()); + assertNotNull(deltas[0].getProject()); + } + } diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 378a1707a0c..ed06bfdca67 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,7 @@ +2004-06-09 Alain Magloire + + Patch from Sam Rob to resolve 64022 + 2004-06-09 Alain Magloire Make sure to run the PathEntryContainerInitializer.initialize() diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileType.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileType.java index 774dd724a6f..afe4aa4fbe3 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileType.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileType.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeAssociation.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeAssociation.java index fd537d51b25..0d2551059e6 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeAssociation.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeAssociation.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -10,11 +10,21 @@ ***********************************************************************/ package org.eclipse.cdt.core.filetype; +import java.util.Comparator; + /** * Corresponds to an org.eclipse.cdt.core.CFileTypeAssociation entry. */ public interface ICFileTypeAssociation { + public static Comparator Comparator = new Comparator() { + public int compare(Object arg0, Object arg1) { + ICFileTypeAssociation lhs = (ICFileTypeAssociation) arg0; + ICFileTypeAssociation rhs = (ICFileTypeAssociation) arg1; + return (lhs.getPattern().compareTo(rhs.getPattern())); + } + }; + /** * @return the file name pattern used for this file association */ diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeConstants.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeConstants.java index 0d2f688da94..f36e99b8092 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeConstants.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeConstants.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeResolver.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeResolver.java index 7716f604903..06448dc109d 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeResolver.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICFileTypeResolver.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -10,7 +10,6 @@ ***********************************************************************/ package org.eclipse.cdt.core.filetype; - /** * Class responsible for resolving a file name into the * associated file type. @@ -35,14 +34,21 @@ public interface ICFileTypeResolver { /** * Add a new file type association to the resolver's list. + * @param assoc file name pattern to add. * - * @param pattern file name pattern to add. - * @param type file type associated with pattern. - * * @return true if the file type association was added. */ - public boolean addAssociation(String pattern, ICFileType type); + public boolean addAssociation(ICFileTypeAssociation assoc); + /** + * Add multiple file type associations to the resolver's list. + * + * @param assocs array of file type associations to add; may be null. + * + * @return true if at least one file type association was added. + */ + public boolean addAssociations(ICFileTypeAssociation[] assocs); + /** * Remove a file type association from the resolver's list. * @@ -51,4 +57,35 @@ public interface ICFileTypeResolver { * @return true if the file type association was removed. */ public boolean removeAssociation(ICFileTypeAssociation assoc); + + /** + * Remove multiple file type associations from the resolver's list. + * + * @param assoc array of file type association to remove; may be null + * + * @return true if at least one file type association was removed. + */ + public boolean removeAssociations(ICFileTypeAssociation[] assocs); + + /** + * Add and/or remove associations from the resolver in a + * batch operation. Either (or both) of the parameters + * may be null. + * + * @param add associations to add to the resolver; may be null + * @param rem associations to remove from the resolver; may be null + * + * @return true if at least one file type association was added or removed + */ + public boolean adjustAssociations(ICFileTypeAssociation[] add, ICFileTypeAssociation[] remove); + + /** + * Create a working copy of this file type resolver. + * + * The copy contains the current set of associations that + * make up the resolver. + * + * @return working copy of this file type resolver + */ + public ICFileTypeResolver createWorkingCopy(); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICLanguage.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICLanguage.java index 26977017a5a..4ff131364f6 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICLanguage.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ICLanguage.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverChangeListener.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverChangeListener.java new file mode 100644 index 00000000000..2a8b7ca0cf4 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverChangeListener.java @@ -0,0 +1,19 @@ +/********************************************************************** + * Copyright (c) 2004 TimeSys Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.filetype; + +/** + * Listener interface for clients interested in changes to an + * individual resolver. + */ +public interface IResolverChangeListener { + public void resolverChanged(ResolverChangeEvent event); +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverModel.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverModel.java index 58079a2ff4a..8c317bb0bd1 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverModel.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverModel.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -93,17 +93,9 @@ public interface IResolverModel { */ public ICFileTypeResolver getResolver(IProject project); - /** - * Create a new file type resolver. The newly created - * resolver will contain no file type associations. - * - * @return newly created file type resolver - */ - public ICFileTypeResolver createResolver(); - /** * Create a new file type assocation. The association - * must be added to a type resolver. + * may be added to a type resolver. * * @param pattern filename pattern for the association. * @param type association file type. @@ -111,4 +103,20 @@ public interface IResolverModel { * @return newly created file type association */ public ICFileTypeAssociation createAssocation(String pattern, ICFileType type); + + /** + * Adds the given listener for model change events to the model. + * Has no effect if an identical listener is already registered. + * + * @param listener listener to add + */ + public void addResolverChangeListener(IResolverChangeListener listener); + + /** + * Removes the given change listener from the model. + * Has no effect if an identical listener is not registered. + * + * @param listener listener to remove + */ + public void removeResolverChangeListener(IResolverChangeListener listener); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverChangeEvent.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverChangeEvent.java new file mode 100644 index 00000000000..922d1cf8281 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverChangeEvent.java @@ -0,0 +1,78 @@ +/********************************************************************** + * Copyright (c) 2004 TimeSys Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.filetype; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ResolverChangeEvent { + private ICFileTypeResolver fResolver; + private List fDeltas = new ArrayList(); + + /** + * Create a new resolver change event. The event is empty + * of any change deltas, and references the provided file + * type resolver. + * + * @param resolver file type resolver this event applies to + */ + public ResolverChangeEvent(ICFileTypeResolver resolver) { + fResolver = resolver; + } + + /** + * @return resolver affected by this change + */ + public ICFileTypeResolver getResolver() { + return fResolver; + } + + /** + * @return number of resolver deltas involved in this change + */ + public int getDeltaCount() { + return fDeltas.size(); + } + + /** + * @return ResolverDelta[] for this change + */ + public ResolverDelta[] getDeltas() { + return (ResolverDelta[]) fDeltas.toArray(new ResolverDelta[fDeltas.size()]); + } + + /** + * Add a new delta to the list of deltas. + * + * @param delta instance of ResolverDelta to add to the list. + */ + public void addDelta(ResolverDelta delta) { + fDeltas.add(delta); + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + + buf.append("ResolverChangeEvent ["); + buf.append(fDeltas.size()); + buf.append(" delta(s)]"); + + for (Iterator iter = fDeltas.iterator(); iter.hasNext();) { + ResolverDelta element = (ResolverDelta) iter.next(); + buf.append("\n "); + buf.append(element.toString()); + } + + return buf.toString(); + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverDelta.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverDelta.java new file mode 100644 index 00000000000..aa0038741ff --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/ResolverDelta.java @@ -0,0 +1,124 @@ +/********************************************************************** + * Copyright (c) 2004 TimeSys Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.filetype; + +import org.eclipse.core.resources.IProject; + +public class ResolverDelta { + public static final int EVENT_ADD = 0x10; + public static final int EVENT_REMOVE = 0x20; + public static final int EVENT_SET = 0x40; + public static final int EVENT_MASK = 0xF0; + + public static final int ELEMENT_LANGUAGE = 0x01; + public static final int ELEMENT_FILETYPE = 0x02; + public static final int ELEMENT_ASSOCIATION = 0x04; + public static final int ELEMENT_PROJECT = 0x08; + public static final int ELEMENT_WORKSPACE = 0x0F; + public static final int ELEMENT_MASK = 0x0F; + + private Object fElement; + private int fEvent; + + public ResolverDelta(int event, int source, Object element) { + fElement = element; + fEvent = event | source; + } + + public ResolverDelta(ICLanguage lang, int event) { + this(event, ELEMENT_LANGUAGE, lang); + } + + public ResolverDelta(ICFileType type, int event) { + this(event, ELEMENT_FILETYPE, type); + } + + public ResolverDelta(ICFileTypeAssociation assoc, int event) { + this(event, ELEMENT_ASSOCIATION, assoc); + } + + public Object getElement() { + return fElement; + } + + public int getElementType() { + return fEvent & ELEMENT_MASK; + } + + public int getEventType() { + return fEvent & EVENT_MASK; + } + + public ICLanguage getLanguage() { + return ((fElement instanceof ICLanguage) ? ((ICLanguage) fElement) : null); + } + + public ICFileType getFileType() { + return ((fElement instanceof ICFileType) ? ((ICFileType) fElement) : null); + } + + public ICFileTypeAssociation getAssociation() { + return ((fElement instanceof ICFileTypeAssociation) ? ((ICFileTypeAssociation) fElement) : null); + } + + public IProject getProject() { + return ((fElement instanceof IProject) ? ((IProject) fElement) : null); + } + + public int getEvent() { + return fEvent; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + switch (getEventType()) { + case EVENT_ADD: + buf.append("add"); + break; + case EVENT_REMOVE: + buf.append("remove"); + break; + case EVENT_SET: + buf.append("set"); + break; + default: + buf.append("?unknown event?"); + break; + } + buf.append(" "); + switch (getElementType()) { + case ELEMENT_LANGUAGE: + buf.append("language "); + buf.append(null != getLanguage() ? getLanguage().getName() : "?"); + break; + case ELEMENT_FILETYPE: + buf.append("filetype "); + buf.append(null != getFileType() ? getFileType().getName() : "?"); + break; + case ELEMENT_ASSOCIATION: + buf.append("assoc "); + buf.append(null != getAssociation() ? getAssociation().getPattern() : "?"); + break; + case ELEMENT_PROJECT: + buf.append("resolver for project "); + buf.append(null != getProject() ? getProject().getName() : "?"); + break; + case ELEMENT_WORKSPACE: + buf.append("resolver for workspace"); + break; + default: + buf.append("?unknown source?"); + break; + } + + return buf.toString(); + } +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/Argument.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/Argument.java index defb9fce0f4..cc96c970684 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/Argument.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/Argument.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileType.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileType.java index b2635653695..9cb3149fe0c 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileType.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileType.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeAssociation.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeAssociation.java index 75c1642d903..16b8749ed67 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeAssociation.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeAssociation.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java index b25ae553ab9..e8a86a613d8 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CFileTypeResolver.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.internal.filetype; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -19,33 +20,16 @@ import org.eclipse.cdt.core.filetype.ICFileTypeAssociation; import org.eclipse.cdt.core.filetype.ICFileTypeResolver; public class CFileTypeResolver implements ICFileTypeResolver { - /** - * The association list holds a list of known file associations. - */ + // The association list holds a list of known file associations. protected List fAssocList = new ArrayList(); - /** - * Create a new resolver. - */ public CFileTypeResolver() { } - /** - * @return the file type associations known to this resolver - */ public ICFileTypeAssociation[] getFileTypeAssociations() { return (ICFileTypeAssociation[]) fAssocList.toArray(new ICFileTypeAssociation[fAssocList.size()]); } - /** - * Get the file type assocated with the specified file name. - * Returns ResolverModel.DEFAULT_FILE_TYPE if the file name - * could not be resolved to a particular file type. - * - * @param fileName name of the file to resolve - * - * @return associated file type, or ResolverModel.DEFAULT_FILE_TYPE - */ public ICFileType getFileType(String fileName) { for (Iterator iter = fAssocList.iterator(); iter.hasNext();) { ICFileTypeAssociation element = (ICFileTypeAssociation) iter.next(); @@ -56,28 +40,75 @@ public class CFileTypeResolver implements ICFileTypeResolver { return ResolverModel.DEFAULT_FILE_TYPE; } - /** - * Add an instance of a file type association to the associations - * known to the resolver. - * - * Returns true if the instance is added; returns false if the - * instance is not added, or if it is already present in the list. - * - * @param assoc association to add - * - * @return true if the association is added, false otherwise - */ - public boolean addAssociation(String pattern, ICFileType type) { + //TODO: the add/remove methods do not generate change notifications... + // They really should be part of an IFileTypeResolverWorkingCopy interface + // For now, just be careful with them... + + public boolean addAssociation(ICFileTypeAssociation assoc) { + return addAssociations(new ICFileTypeAssociation[] { assoc } ); + } + + public boolean addAssociations(ICFileTypeAssociation[] assocs) { + return doAddAssociations(assocs); + } + + public boolean removeAssociation(ICFileTypeAssociation assoc) { + return removeAssociations(new ICFileTypeAssociation[] { assoc } ); + } + + public boolean removeAssociations(ICFileTypeAssociation[] assocs) { + return doRemoveAssociations(assocs); + } + + public boolean adjustAssociations(ICFileTypeAssociation[] add, ICFileTypeAssociation[] remove) { + boolean added = doAddAssociations(add); + boolean removed = doRemoveAssociations(remove); + return (added || removed); + } + + public ICFileTypeResolver createWorkingCopy() { + CFileTypeResolver copy = new CFileTypeResolver(); + copy.fAssocList.addAll(fAssocList); + return copy; + } + + protected boolean doAddAssociations(ICFileTypeAssociation[] assocs) { boolean added = false; - ICFileTypeAssociation assoc = new CFileTypeAssociation(pattern, type); - if (!fAssocList.contains(assoc)) { - added = fAssocList.add(assoc); + if (null != assocs) { + for (int i = 0; i < assocs.length; i++) { + if (!fAssocList.contains(assocs[i])) { + if (fAssocList.add(assocs[i])) { + added = true; + } + } + } + } + if (added) { + Collections.sort(fAssocList, ICFileTypeAssociation.Comparator); } return added; } - - public boolean removeAssociation(ICFileTypeAssociation assoc) { - return fAssocList.remove(assoc); + + public boolean doRemoveAssociations(ICFileTypeAssociation[] assocs) { + boolean removed = false; + if (null != assocs) { + for (int i = 0; i < assocs.length; i++) { + if (fAssocList.remove(assocs[i])) { + removed = true; + } + } + } + if (removed) { + Collections.sort(fAssocList, ICFileTypeAssociation.Comparator); + } + return removed; } + private static boolean isDebugging() { + return ResolverModel.VERBOSE; + } + + private static void debugLog(String message) { + System.out.println("CDT Resolver: " + message); + } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CLanguage.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CLanguage.java index fbc8ebdf8d0..ddfde8b3ac6 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CLanguage.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/CLanguage.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java index 73bfab1389e..ccb50e061e8 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -19,11 +19,15 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Vector; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ICDescriptor; @@ -32,15 +36,24 @@ import org.eclipse.cdt.core.filetype.ICFileTypeAssociation; import org.eclipse.cdt.core.filetype.ICFileTypeConstants; import org.eclipse.cdt.core.filetype.ICFileTypeResolver; import org.eclipse.cdt.core.filetype.ICLanguage; +import org.eclipse.cdt.core.filetype.IResolverChangeListener; import org.eclipse.cdt.core.filetype.IResolverModel; +import org.eclipse.cdt.core.filetype.ResolverChangeEvent; +import org.eclipse.cdt.core.filetype.ResolverDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionDelta; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IRegistryChangeEvent; +import org.eclipse.core.runtime.IRegistryChangeListener; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.Status; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -73,6 +86,9 @@ public class ResolverModel implements IResolverModel { // The type map holds a map of file type IDs to file types. private Map fTypeMap = new HashMap(); + // Default resolver + private ICFileTypeResolver fDefaultResolver = null; + // Workspace resolver private ICFileTypeResolver fWkspResolver = null; @@ -102,13 +118,25 @@ public class ResolverModel implements IResolverModel { private static ResolverModel fInstance = null; // Qualified names used to identify project session properties - public static final String RESOLVER_MODEL_ID = CCorePlugin.PLUGIN_ID + ".resolver"; //$NON-NLS-1$ - public static final QualifiedName QN_CUSTOM_RESOLVER = new QualifiedName(RESOLVER_MODEL_ID, TAG_CUSTOM); + private static final String RESOLVER_MODEL_ID = CCorePlugin.PLUGIN_ID + ".resolver"; //$NON-NLS-1$ + private static final QualifiedName QN_CUSTOM_RESOLVER = new QualifiedName(RESOLVER_MODEL_ID, TAG_CUSTOM); + + // List of listeners on the model + private List fListeners = Collections.synchronizedList(new Vector()); // Private ctor to preserve singleton status private ResolverModel() { - loadDeclaredLanguages(); - loadDeclaredTypes(); + try { + loadDeclaredLanguages(); + loadDeclaredTypes(); + + fDefaultResolver = loadDefaultResolver(); + fWkspResolver = loadWorkspaceResolver(); + + initRegistryChangeListener(); + } catch (Exception e) { + CCorePlugin.log(e); + } } /** @@ -141,62 +169,52 @@ public class ResolverModel implements IResolverModel { return ((null != type) ? type : DEFAULT_FILE_TYPE); } - synchronized public void setResolver(ICFileTypeResolver resolver) { - fWkspResolver = resolver; - saveWorkspaceResolver(resolver); + public void setResolver(ICFileTypeResolver newResolver) { + ICFileTypeResolver oldResolver = getResolver(); + fWkspResolver = newResolver; + saveWorkspaceResolver(newResolver); + fireResolverChangeEvent(null, oldResolver); } - synchronized public ICFileTypeResolver getResolver() { - if (null == fWkspResolver) { - fWkspResolver = internalGetWorkspaceResolver(); - } - return fWkspResolver; + public ICFileTypeResolver getResolver() { + return ((null != fWkspResolver) ? fWkspResolver : fDefaultResolver) ; } - public void setResolver(IProject project, ICFileTypeResolver resolver) { - setResolverForSession(project, resolver); - saveProjectResolver(project, resolver); + public void setResolver(IProject project, ICFileTypeResolver newResolver) { + ICFileTypeResolver oldResolver = getResolver(project); + try { + project.setSessionProperty(QN_CUSTOM_RESOLVER, newResolver); + } catch (CoreException e) { + } + saveProjectResolver(project, newResolver); + fireResolverChangeEvent(project, oldResolver); } public ICFileTypeResolver getResolver(IProject project) { ICFileTypeResolver resolver = null; - - if (null == project) { - resolver = getResolver(); - } else { - resolver = getResolverForSession(project); + + if (null != project) { + try { + Object obj = project.getSessionProperty(QN_CUSTOM_RESOLVER); + if (obj instanceof ICFileTypeResolver) { + resolver = (ICFileTypeResolver) obj; + } + } catch (CoreException e) { + } if (null == resolver) { - resolver = internalGetProjectResolver(project); + if (customProjectResolverExists(project)) { + resolver = loadProjectResolver(project); + } } } + if (null == resolver) { + resolver = getResolver(); + } + return resolver; } - private ICFileTypeResolver internalGetWorkspaceResolver() { - ICFileTypeResolver resolver = null; - if (customWorkspaceResolverExists()) { - resolver = loadWorkspaceResolver(); - } else { - resolver = loadResolverDefaults(); - } - return resolver; - } - - private ICFileTypeResolver internalGetProjectResolver(IProject project) { - ICFileTypeResolver resolver = null; - if (customProjectResolverExists(project)) { - resolver = loadProjectResolver(project); - } else { - resolver = internalGetWorkspaceResolver(); - } - return resolver; - } - - public ICFileTypeResolver createResolver() { - return new CFileTypeResolver(); - } - public ICFileTypeAssociation createAssocation(String pattern, ICFileType type) { return new CFileTypeAssociation(pattern, type); } @@ -213,17 +231,14 @@ public class ResolverModel implements IResolverModel { * @return true if the language is added, false otherwise */ public boolean addLanguage(ICLanguage lang) { - if (isDebugging()) { - debugLog("+ language " + lang.getId() + " as " + lang.getName()); + ResolverChangeEvent event = new ResolverChangeEvent(null); + boolean result = addLanguage(lang, event); + if (true == result) { + fireEvent(event); } - boolean added = false; - if (!fLangMap.containsValue(lang)) { - fLangMap.put(lang.getId(), lang); - added = true; - } - return added; + return result; } - + /** * Add an instance of a file type to the file types known to the * resolver. @@ -236,15 +251,12 @@ public class ResolverModel implements IResolverModel { * @return true if the file type is added, false otherwise */ public boolean addFileType(ICFileType type) { - if (isDebugging()) { - debugLog("+ type " + type.getId() + " as " + type.getName()); + ResolverChangeEvent event = new ResolverChangeEvent(null); + boolean result = addFileType(type, event); + if (true == result) { + fireEvent(event); } - boolean added = false; - if (!fTypeMap.containsValue(type)) { - fTypeMap.put(type.getId(), type); - added = true; - } - return added; + return result; } /** @@ -255,26 +267,14 @@ public class ResolverModel implements IResolverModel { * @return true if the language is removed, false otherwise */ public boolean removeLanguage(ICLanguage lang) { - if (isDebugging()) { - debugLog("- language " + lang.getId() + " as " + lang.getName()); + ResolverChangeEvent event = new ResolverChangeEvent(null); + boolean result = removeLanguage(lang, event); + if (true == result) { + fireEvent(event); } - boolean removed = (null != fLangMap.remove(lang.getId())); - - if (removed) { - ArrayList removeList = new ArrayList(); - for (Iterator iter = fTypeMap.values().iterator(); iter.hasNext();) { - ICFileType type = (ICFileType) iter.next(); - if (lang.equals(type.getLanguage())) { - removeList.add(type); - } - } - for (Iterator iter = removeList.iterator(); iter.hasNext();) { - removeFileType((ICFileType) iter.next()); - } - } - return removed; + return result; } - + /** * Remove a file type from the list of type known to the resolver. * @@ -283,61 +283,266 @@ public class ResolverModel implements IResolverModel { * @return true if the file type is removed, false otherwise */ public boolean removeFileType(ICFileType type) { - if (isDebugging()) { - debugLog("- type " + type.getId() + " as " + type.getName()); + ResolverChangeEvent event = new ResolverChangeEvent(null); + boolean result = removeFileType(type, event); + if (true == result) { + fireEvent(event); } - // TODO: must remove any associations based on this file type as well - // Unforuntately, at this point, that means iterating over the contents - // of the default, workspace, and project resolvers. Ugh. - return (null != fTypeMap.remove(type.getId())); + return result; + } + + public void addResolverChangeListener(IResolverChangeListener listener) { + fListeners.add(listener); + } + + public void removeResolverChangeListener(IResolverChangeListener listener) { + fListeners.remove(listener); + } + + //---------------------------------------------------------------------- + // Misc. internal + //---------------------------------------------------------------------- + + private IExtensionPoint getExtensionPoint(String extensionPointId) { + return Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, extensionPointId); + } + + private static boolean isDebugging() { + return VERBOSE; } - /** - * Load languages declared through the CLanguage extension point. - */ - private void loadDeclaredLanguages() { - IExtensionPoint point = getExtensionPoint(EXTENSION_LANG); - IExtension[] extensions = point.getExtensions(); - IConfigurationElement[] elements = null; + private static void debugLog(String message) { + System.out.println("CDT Resolver: " + message); + } - for (int i = 0; i < extensions.length; i++) { - elements = extensions[i].getConfigurationElements(); - for (int j = 0; j < elements.length; j++) { - String id = elements[j].getAttribute(ATTR_ID); - String name = elements[j].getAttribute(ATTR_NAME); - - try { - addLanguage(new CLanguage(id, name)); - } catch (IllegalArgumentException e) { - CCorePlugin.log(e); + //---------------------------------------------------------------------- + // Registry change event handling + //---------------------------------------------------------------------- + + private boolean addLanguage(ICLanguage lang, ResolverChangeEvent event) { + boolean added = false; + if (!fLangMap.containsValue(lang)) { + fLangMap.put(lang.getId(), lang); + if (null != event) { + event.addDelta(new ResolverDelta(lang, ResolverDelta.EVENT_ADD)); + } + added = true; + } + return added; + } + + private boolean addFileType(ICFileType type, ResolverChangeEvent event) { + boolean added = false; + if (!fTypeMap.containsValue(type)) { + fTypeMap.put(type.getId(), type); + if (null != event) { + event.addDelta(new ResolverDelta(type, ResolverDelta.EVENT_ADD)); + } + added = true; + } + return added; + } + + private boolean removeLanguage(ICLanguage lang, ResolverChangeEvent event) { + boolean removed = (null != fLangMap.remove(lang.getId())); + + if (removed) { + if (null != event) { + event.addDelta(new ResolverDelta(lang, ResolverDelta.EVENT_REMOVE)); + } + ArrayList removeList = new ArrayList(); + for (Iterator iter = fTypeMap.values().iterator(); iter.hasNext();) { + ICFileType type = (ICFileType) iter.next(); + if (lang.equals(type.getLanguage())) { + removeList.add(type); + } + } + for (Iterator iter = removeList.iterator(); iter.hasNext();) { + removeFileType((ICFileType) iter.next(), event); + } + } + return removed; + } + + private boolean removeFileType(ICFileType type, ResolverChangeEvent event) { + boolean removed = (null != fTypeMap.remove(type.getId())); + if (removed) { + if (null != event) { + event.addDelta(new ResolverDelta(type, ResolverDelta.EVENT_REMOVE)); + } + // TODO: must remove any associations based on this file type as well + // Unforuntately, at this point, that means iterating over the contents + // of the default, workspace, and project resolvers. Ugh. + } + return removed; + } + + private void fireEvent(final ResolverChangeEvent event) { + final IResolverChangeListener[] listeners; + + synchronized (fListeners) { + if (isDebugging()) { + debugLog(event.toString()); + } + if (fListeners.isEmpty()) { + return; + } + listeners = (IResolverChangeListener[]) fListeners.toArray(new IResolverChangeListener[fListeners.size()]); + } + + for (int i = 0; i < listeners.length; i++) { + final int index = i; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, + CCorePlugin.getResourceString("ResolverModel.exception.listenerError"), exception); //$NON-NLS-1$ + CCorePlugin.log(status); + } + public void run() throws Exception { + listeners[index].resolverChanged(event); + } + }); + } + } + + private void fireResolverChangeEvent(IProject project, ICFileTypeResolver oldResolver) { + ICFileTypeResolver newResolver = getResolver(project); + ResolverChangeEvent event = new ResolverChangeEvent(newResolver); + int element = ResolverDelta.ELEMENT_WORKSPACE; + + if (null != project) { + element = ResolverDelta.ELEMENT_PROJECT; + } + + event.addDelta(new ResolverDelta(ResolverDelta.EVENT_SET, element, project)); + + if ((null != oldResolver) && (null != newResolver)) { + ICFileTypeAssociation[] oldAssoc = oldResolver.getFileTypeAssociations(); + ICFileTypeAssociation[] newAssoc = newResolver.getFileTypeAssociations(); + + for (int i = 0; i < oldAssoc.length; i++) { + if (Arrays.binarySearch(newAssoc, oldAssoc[i], ICFileTypeAssociation.Comparator) < 0) { + event.addDelta(new ResolverDelta(oldAssoc[i], ResolverDelta.EVENT_REMOVE)); + } + } + + for (int i = 0; i < newAssoc.length; i++) { + if (Arrays.binarySearch(oldAssoc, newAssoc[i], ICFileTypeAssociation.Comparator) < 0) { + event.addDelta(new ResolverDelta(newAssoc[i], ResolverDelta.EVENT_ADD)); } } } + fireEvent(event); + } + + private void initRegistryChangeListener() { + Platform.getExtensionRegistry().addRegistryChangeListener(new IRegistryChangeListener() { + public void registryChanged(IRegistryChangeEvent event) { + handleRegistryChanged(event); + } + }, CCorePlugin.PLUGIN_ID); + } + + private void handleRegistryChanged(IRegistryChangeEvent event) { + IExtensionDelta[] deltas = null; + ResolverChangeEvent modelEvent = new ResolverChangeEvent(null); + + deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_LANG); + for (int i = 0; i < deltas.length; i++) { + processLanguageExtension(modelEvent, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind()); + } + + deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_TYPE); + for (int i = 0; i < deltas.length; i++) { + processTypeExtension(modelEvent, deltas[i].getExtension(), IExtensionDelta.ADDED == deltas[i].getKind()); + } + + deltas = event.getExtensionDeltas(CCorePlugin.PLUGIN_ID, EXTENSION_ASSOC); + if (deltas.length != 0) { + fDefaultResolver = loadDefaultResolver(); + fWkspResolver = loadWorkspaceResolver(); + } + + fireEvent(modelEvent); + } + + //---------------------------------------------------------------------- + // Extension point handling + //---------------------------------------------------------------------- + + /** + * Load languages declared through the CLanguage extension point. + */ + private void loadDeclaredLanguages() { + IExtensionPoint point = getExtensionPoint(EXTENSION_LANG); + IExtension[] extensions = point.getExtensions(); + ResolverChangeEvent event = new ResolverChangeEvent(null); + + for (int i = 0; i < extensions.length; i++) { + processLanguageExtension(event, extensions[i], true); + } + + // Shouldn't have anything listening here, but generating + // the events helps maintain internal consistency w/logging + + fireEvent(event); } /** * Load file type declared through the CFileType extension point. */ private void loadDeclaredTypes() { - IExtensionPoint point = getExtensionPoint(EXTENSION_TYPE); - IExtension[] extensions = point.getExtensions(); - IConfigurationElement[] elements = null; - + IExtensionPoint point = getExtensionPoint(EXTENSION_TYPE); + IExtension[] extensions = point.getExtensions(); + ResolverChangeEvent event = new ResolverChangeEvent(null); + for (int i = 0; i < extensions.length; i++) { - elements = extensions[i].getConfigurationElements(); - for (int j = 0; j < elements.length; j++) { - String id = elements[j].getAttribute(ATTR_ID); - String lang = elements[j].getAttribute(ATTR_LANGUAGE); - String name = elements[j].getAttribute(ATTR_NAME); - String type = elements[j].getAttribute(ATTR_TYPE); - - try { - addFileType(new CFileType(id, getLanguageById(lang), name, parseType(type))); - } catch (IllegalArgumentException e) { - CCorePlugin.log(e); + processTypeExtension(event, extensions[i], true); + } + + // Shouldn't have anything listening here, but generating + // the events helps maintain internal consistency w/logging + + fireEvent(event); + } + + private void processLanguageExtension(ResolverChangeEvent event, IExtension extension, boolean add) { + IConfigurationElement[] elements = extension.getConfigurationElements(); + for (int i = 0; i < elements.length; i++) { + String id = elements[i].getAttribute(ATTR_ID); + String name = elements[i].getAttribute(ATTR_NAME); + + try { + ICLanguage element = new CLanguage(id, name); + if (add) { + addLanguage(element, event); + } else { + removeLanguage(element, event); } + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } + } + } + + private void processTypeExtension(ResolverChangeEvent event, IExtension extension, boolean add) { + IConfigurationElement[] elements = extension.getConfigurationElements(); + for (int i = 0; i < elements.length; i++) { + String id = elements[i].getAttribute(ATTR_ID); + String lang = elements[i].getAttribute(ATTR_LANGUAGE); + String name = elements[i].getAttribute(ATTR_NAME); + String type = elements[i].getAttribute(ATTR_TYPE); + try { + ICFileType element = new CFileType(id, getLanguageById(lang), name, parseType(type)); + if (add) { + addFileType(element, event); + } else { + removeFileType(element, event); + } + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); } } } @@ -360,56 +565,7 @@ public class ResolverModel implements IResolverModel { return type; } - - /** - * Get the resolver cached in the project session properties, - * if available. - * - * @param project project to query - * - * @return cached file type resolver, or null - */ - private ICFileTypeResolver getResolverForSession(IProject project) { - ICFileTypeResolver resolver = null; - - try { - Object obj = project.getSessionProperty(QN_CUSTOM_RESOLVER); - if (obj instanceof ICFileTypeResolver) { - resolver = (ICFileTypeResolver) obj; - } - } catch (CoreException e) { - } - - return resolver; - } - /** - * Store the currently active resolver in the project session - * properties. - * - * @param project project to set resolver for - * @param resolver file type resolver to cache - */ - private void setResolverForSession(IProject project, ICFileTypeResolver resolver) { - if (null != project) { - try { - project.setSessionProperty(QN_CUSTOM_RESOLVER, resolver); - } catch (CoreException e) { - } - } - } - - private static boolean isDebugging() { - return VERBOSE; - } - - private void debugLog(String message) { - System.out.println("CDT Resolver: " + message); - } - - private IExtensionPoint getExtensionPoint(String extensionPointId) { - return Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, extensionPointId); - } //---------------------------------------------------------------------- // Default resolver @@ -419,23 +575,25 @@ public class ResolverModel implements IResolverModel { * Initialize the default resolver by loading data from * declared extension points. */ - private ICFileTypeResolver loadResolverDefaults() { + private ICFileTypeResolver loadDefaultResolver() { + List assoc = new ArrayList(); ICFileTypeResolver resolver = new CFileTypeResolver(); IExtensionPoint point = getExtensionPoint(EXTENSION_ASSOC); IExtension[] extensions = point.getExtensions(); IConfigurationElement[] elements = null; - ResolverModel model = ResolverModel.getDefault(); for (int i = 0; i < extensions.length; i++) { elements = extensions[i].getConfigurationElements(); for (int j = 0; j < elements.length; j++) { - ICFileType typeRef = model.getFileTypeById(elements[j].getAttribute(ATTR_TYPE)); + ICFileType typeRef = getFileTypeById(elements[j].getAttribute(ATTR_TYPE)); if (null != typeRef) { - addAssocFromPattern(resolver, typeRef, elements[j]); - addAssocFromFile(resolver, typeRef, elements[j]); + assoc.addAll(getAssocFromPattern(typeRef, elements[j])); + assoc.addAll(getAssocFromFile(typeRef, elements[j])); } } } + + resolver.addAssociations((ICFileTypeAssociation[]) assoc.toArray(new ICFileTypeAssociation[assoc.size()])); return resolver; } @@ -447,18 +605,20 @@ public class ResolverModel implements IResolverModel { * * @param element configuration element to get file extensions from */ - private void addAssocFromPattern(ICFileTypeResolver resolver, ICFileType typeRef, IConfigurationElement element) { + private List getAssocFromPattern(ICFileType typeRef, IConfigurationElement element) { + List assocs = new ArrayList(); String attr = element.getAttribute(ATTR_PATTERN); if (null != attr) { String[] item = attr.split(","); for (int i = 0; i < item.length; i++) { try { - resolver.addAssociation(item[i].trim(), typeRef); + assocs.add(createAssocation(item[i].trim(), typeRef)); } catch (IllegalArgumentException e) { CCorePlugin.log(e); } } } + return assocs; } /** @@ -472,7 +632,8 @@ public class ResolverModel implements IResolverModel { * * @param element configuration element to get file extensions from */ - private void addAssocFromFile(ICFileTypeResolver resolver, ICFileType typeRef, IConfigurationElement element) { + private List getAssocFromFile(ICFileType typeRef, IConfigurationElement element) { + List assocs = new ArrayList(); String attr = element.getAttribute(ATTR_FILE); if (null != attr) { @@ -488,7 +649,7 @@ public class ResolverModel implements IResolverModel { line = in.readLine(); while (null != line) { try { - resolver.addAssociation(line, typeRef); + assocs.add(createAssocation(line.trim(), typeRef)); } catch (IllegalArgumentException e) { CCorePlugin.log(e); } @@ -499,27 +660,28 @@ public class ResolverModel implements IResolverModel { CCorePlugin.log(e); } } + return assocs; } //---------------------------------------------------------------------- // Workspace resolver //---------------------------------------------------------------------- - public boolean customWorkspaceResolverExists() { + private boolean customWorkspaceResolverExists() { return getWorkspaceResolverStateFilePath().toFile().exists(); } private IPath getWorkspaceResolverStateFilePath() { return CCorePlugin.getDefault().getStateLocation().append(WKSP_STATE_FILE); } - + private ICFileTypeResolver loadWorkspaceResolver() { + List assocs = new ArrayList(); ICFileTypeResolver resolver = null; File file = getWorkspaceResolverStateFilePath().toFile(); if (file.exists()) { Properties props = new Properties(); - ResolverModel model = ResolverModel.getDefault(); FileInputStream in = null; resolver = new CFileTypeResolver(); @@ -531,8 +693,12 @@ public class ResolverModel implements IResolverModel { for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) { Map.Entry element = (Map.Entry) iter.next(); - ICFileType type = model.getFileTypeById(element.getValue().toString()); - resolver.addAssociation(element.getKey().toString(), type); + ICFileType type = getFileTypeById(element.getValue().toString()); + try { + assocs.add(createAssocation(element.getKey().toString(), type)); + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } } in.close(); @@ -543,12 +709,14 @@ public class ResolverModel implements IResolverModel { if (null != in) { in = null; } + + resolver.addAssociations((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()])); } - + return resolver; } - public void saveWorkspaceResolver(ICFileTypeResolver resolver) { + private void saveWorkspaceResolver(ICFileTypeResolver resolver) { File file = getWorkspaceResolverStateFilePath().toFile(); BufferedWriter out = null; @@ -579,7 +747,7 @@ public class ResolverModel implements IResolverModel { // Project resolver //---------------------------------------------------------------------- - public boolean customProjectResolverExists(IProject project) { + private boolean customProjectResolverExists(IProject project) { Element data = getProjectData(project); Node child = ((null != data) ? data.getFirstChild() : null); Boolean custom = new Boolean(false); @@ -609,9 +777,9 @@ public class ResolverModel implements IResolverModel { return data; } - public ICFileTypeResolver loadProjectResolver(IProject project) { + private ICFileTypeResolver loadProjectResolver(IProject project) { + List assocs = new ArrayList(); ICFileTypeResolver resolver = new CFileTypeResolver(); - ResolverModel model = ResolverModel.getDefault(); Element data = getProjectData(project); Node child = ((null != data) ? data.getFirstChild() : null); @@ -623,7 +791,11 @@ public class ResolverModel implements IResolverModel { Element element = (Element) assoc; String pattern = element.getAttribute(ATTR_PATTERN); String typeId = element.getAttribute(ATTR_TYPE); - resolver.addAssociation(pattern, model.getFileTypeById(typeId)); + try { + assocs.add(createAssocation(pattern, getFileTypeById(typeId))); + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } } assoc = assoc.getNextSibling(); } @@ -631,11 +803,12 @@ public class ResolverModel implements IResolverModel { child = child.getNextSibling(); } + resolver.addAssociations((ICFileTypeAssociation[]) assocs.toArray(new ICFileTypeAssociation[assocs.size()])); + return resolver; } - public void saveProjectResolver(IProject project, ICFileTypeResolver resolver) { - //ResolverModel model = ResolverModel.getDefault(); + private void saveProjectResolver(IProject project, ICFileTypeResolver resolver) { Element root = getProjectData(project); Document doc = root.getOwnerDocument(); Node child = root.getFirstChild(); @@ -672,6 +845,4 @@ public class ResolverModel implements IResolverModel { CCorePlugin.log(e); } } - - } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties index 739cd300cde..fb8fd6a0d2c 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties @@ -40,6 +40,8 @@ CDescriptor.exception.missingElement=Missing cdtproject element CDescriptor.exception.providerNotFound=Extension not found. CDescriptor.extension.internalError=Internal Error +ResolverModel.exception.listenerError=An exception occurred during resolver model change notification + Util.exception.invalidArchive=Not a valid archive file. Util.exception.arrayToSmall=Array to small Util.exception.notPE=Not a PE format diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index f92f0cc36b1..85b4c8bbdad 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,7 @@ +2004-06-09 Alain Magloire + + Patch from Sam Rob to resolve 64022 + 2004-06-09 Tanya Wolff Externalized strings from Work In Progress Part of PR 66016 diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypeDialog.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypeDialog.java index a73258ebb15..cc5eda212db 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypeDialog.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypeDialog.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferenceBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferenceBlock.java index 2272d7a7a5e..c2277bffd9f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferenceBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferenceBlock.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -58,7 +58,8 @@ public class CFileTypesPreferenceBlock { private ICFileTypeResolver fResolver; private ArrayList fAddAssoc; private ArrayList fRemoveAssoc; - + private boolean fDirty = false; + private TableViewer fAssocViewer; private Button fBtnNew; private Button fBtnRemove; @@ -152,9 +153,10 @@ public class CFileTypesPreferenceBlock { } public CFileTypesPreferenceBlock(ICFileTypeResolver input) { - fResolver = input; fAddAssoc = new ArrayList(); fRemoveAssoc = new ArrayList(); + setResolver(input); + setDirty(false); } public Control createControl(Composite parent) { @@ -277,32 +279,47 @@ public class CFileTypesPreferenceBlock { fAssocViewer.getTable().setEnabled(enabled); fBtnNew.setEnabled(enabled); fBtnRemove.setEnabled(enabled); + setDirty(enabled); } public void setResolver(ICFileTypeResolver resolver) { fAddAssoc.clear(); fRemoveAssoc.clear(); - fResolver = resolver; - fAssocViewer.setInput(fResolver.getFileTypeAssociations()); + fResolver = resolver.createWorkingCopy(); + if (null != fAssocViewer) { + fAssocViewer.setInput(fResolver.getFileTypeAssociations()); + } + setDirty(true); } public ICFileTypeResolver getResolver() { return fResolver; } - public void performApply() { - for (Iterator iter = fAddAssoc.iterator(); iter.hasNext();) { - ICFileTypeAssociation assoc = (ICFileTypeAssociation) iter.next(); - fResolver.addAssociation(assoc.getPattern(), assoc.getType()); - } + public void setDirty(boolean dirty) { + fDirty = dirty; + } + + public boolean isDirty() { + return fDirty; + } - for (Iterator iter = fRemoveAssoc.iterator(); iter.hasNext();) { - ICFileTypeAssociation assoc = (ICFileTypeAssociation) iter.next(); - fResolver.removeAssociation(assoc); - } + public boolean performOk() { + boolean changed = fDirty; + + if (fDirty) { + ICFileTypeAssociation[] add = (ICFileTypeAssociation[]) fAddAssoc.toArray(new ICFileTypeAssociation[fAddAssoc.size()]); + ICFileTypeAssociation[] rem = (ICFileTypeAssociation[]) fRemoveAssoc.toArray(new ICFileTypeAssociation[fRemoveAssoc.size()]); + + fResolver.adjustAssociations(add, rem); + + fAddAssoc.clear(); + fRemoveAssoc.clear(); - fAddAssoc.clear(); - fRemoveAssoc.clear(); + setDirty(false); + } + + return changed; } private void handleSelectionChanged() { @@ -325,6 +342,7 @@ public class CFileTypesPreferenceBlock { fAssocViewer.add(assoc); fAddAssoc.add(assoc); fRemoveAssoc.remove(assoc); + setDirty(true); } } } @@ -337,6 +355,7 @@ public class CFileTypesPreferenceBlock { fAssocViewer.remove(assoc); fAddAssoc.remove(assoc); fRemoveAssoc.add(assoc); + setDirty(true); } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferencePage.java index 13ed2b6ea72..c4415dadf8b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferencePage.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -76,9 +76,10 @@ public class CFileTypesPreferencePage extends PreferencePage implements IWorkben public boolean performOk() { IResolverModel model = getResolverModel(); - fPrefsBlock.performApply(); - model.setResolver(fPrefsBlock.getResolver()); - + if (fPrefsBlock.performOk()) { + model.setResolver(fPrefsBlock.getResolver()); + } + return super.performOk(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java index 185eb1714c1..b1366cbaea7 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java @@ -1,7 +1,7 @@ /********************************************************************** * Copyright (c) 2004 TimeSys Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * @@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.ui.preferences; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.filetype.ICFileTypeResolver; import org.eclipse.cdt.core.filetype.IResolverModel; -import org.eclipse.cdt.core.internal.filetype.ResolverModel; import org.eclipse.core.resources.IProject; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; @@ -72,12 +71,11 @@ public class CFileTypesPropertyPage extends PropertyPage { }); // Resolver block - // TODO: get rid of ResolverModel cast IProject project = getProject(); ICFileTypeResolver resolver = CCorePlugin.getDefault().getFileTypeResolver(project); IResolverModel model = CCorePlugin.getDefault().getResolverModel(); - boolean custom = ((ResolverModel) model).customProjectResolverExists(project); + boolean custom = model.getResolver() != model.getResolver(project); Composite blockPane = new Composite(topPane, SWT.NONE); @@ -101,9 +99,7 @@ public class CFileTypesPropertyPage extends PropertyPage { protected void performDefaults() { fUseWorkspace.setSelection(true); fUseProject.setSelection(false); - fPrefsBlock.setEnabled(false); - super.performDefaults(); } @@ -113,11 +109,10 @@ public class CFileTypesPropertyPage extends PropertyPage { public boolean performOk() { IResolverModel model = getResolverModel(); - fPrefsBlock.performApply(); - if (fUseProject.getSelection()) { - model.setResolver(getProject(), null); - model.setResolver(getProject(), fPrefsBlock.getResolver()); + if (fPrefsBlock.performOk()) { + model.setResolver(getProject(), fPrefsBlock.getResolver()); + } } else { model.setResolver(getProject(), null); }