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 c6db37cb52c..ecd0fea655c 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 @@ -10,23 +10,38 @@ ***********************************************************************/ package org.eclipse.cdt.core.filetype.tests; +import junit.extensions.TestSetup; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.filetype.ICFileType; 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.IResolverModel; import org.eclipse.cdt.core.internal.filetype.CFileType; import org.eclipse.cdt.core.internal.filetype.CFileTypeAssociation; import org.eclipse.cdt.core.internal.filetype.CLanguage; +import org.eclipse.cdt.core.internal.filetype.ResolverModel; +import org.eclipse.cdt.testplugin.CTestPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; public class ResolverTests extends TestCase { - private ICFileTypeResolver resolver; + private ICFileTypeResolver workspaceResolver; + private ICFileTypeResolver projectResolver; + private IResolverModel model; + private static IProject project; + private static final String PLUGIN_ID = "org.eclipse.cdt.core.filetype.tests"; private static final String LANG_TEST = PLUGIN_ID + ".test"; private static final String FT_TEST_HEADER = LANG_TEST + ".header"; @@ -36,20 +51,70 @@ public class ResolverTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(ResolverTests.class.getName()); suite.addTest(new ResolverTests("testInternalCtors")); - suite.addTest(new ResolverTests("testFileTypeResolution")); + suite.addTest(new ResolverTests("testDefaultFileTypeResolution")); + suite.addTest(new ResolverTests("testWorkspaceFileTypeResolution")); + suite.addTest(new ResolverTests("testProjectFileTypeResolution")); suite.addTest(new ResolverTests("testGetLanguages")); suite.addTest(new ResolverTests("testGetTypes")); suite.addTest(new ResolverTests("testGetFileTypeAssociations")); suite.addTest(new ResolverTests("testAdd")); suite.addTest(new ResolverTests("testRemove")); - return suite; + + TestSetup wrapper = new TestSetup(suite) { + protected void setUp() throws Exception { + oneTimeSetUp(); + } + protected void tearDown() throws Exception { + oneTimeTearDown(); + } + }; + + return wrapper; + } + + private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException { + IProjectDescription description = proj.getDescription(); + String[] prevNatures = description.getNatureIds(); + String[] newNatures = new String[prevNatures.length + 1]; + System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); + newNatures[prevNatures.length] = natureId; + description.setNatureIds(newNatures); + proj.setDescription(description, monitor); + } + + static void oneTimeSetUp() throws Exception { + IWorkspaceRoot root = CTestPlugin.getWorkspace().getRoot(); + IProject project = root.getProject("testResolverProject"); + if (!project.exists()) { + project.create(null); + } else { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } + if (!project.isOpen()) { + project.open(null); + } + if (!project.hasNature(CProjectNature.C_NATURE_ID)) { + addNatureToProject(project, CProjectNature.C_NATURE_ID, null); + } + ResolverTests.project = project; + } + + static void oneTimeTearDown() throws Exception { + project.delete(true, true, null); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { - resolver = CCorePlugin.getDefault().getFileTypeResolver(); + model = CCorePlugin.getDefault().getResolverModel(); + + model.setResolver(null); + model.setResolver(project, null); + + workspaceResolver = model.getResolver(); + projectResolver = model.getResolver(project); + super.setUp(); } @@ -57,7 +122,10 @@ public class ResolverTests extends TestCase { * @see TestCase#tearDown() */ protected void tearDown() throws Exception { - resolver = null; + workspaceResolver = null; + workspaceResolver = null; + projectResolver = null; + model = null; super.tearDown(); } @@ -176,137 +244,254 @@ public class ResolverTests extends TestCase { assertNotNull(assoc); } - private void doTestFileTypeResolution(String fileName, String expectedTypeId) { + private void doTestFileTypeResolution(ICFileTypeResolver resolver, String fileName, String expectedTypeId) { ICFileType typeByName = resolver.getFileType(fileName); assertNotNull(typeByName); assertEquals(expectedTypeId, typeByName.getId()); - ICFileType typeById = resolver.getFileTypeById(typeByName.getId()); + ICFileType typeById = model.getFileTypeById(typeByName.getId()); assertNotNull(typeById); assertEquals(typeByName, typeById); - ICLanguage languageById = resolver.getLanguageById(typeByName.getLanguage().getId()); + ICLanguage languageById = model.getLanguageById(typeByName.getLanguage().getId()); assertNotNull(languageById); assertEquals(typeByName.getLanguage().getId(), languageById.getId()); } - public final void testFileTypeResolution() { + public final void testDefaultFileTypeResolution() { // - Null string, Empty string, Strings w/spaces - doTestFileTypeResolution(null, ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution(" ", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, null, ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, " ", ICFileTypeConstants.FT_UNKNOWN); // Odd filenames - doTestFileTypeResolution(".", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution(".c.", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution(".cpp.", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("file.c.", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("file.cpp.", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("file.c.input", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("file.cpp.input", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("c", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("cpp", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("numerical", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("some/path/file.c", ICFileTypeConstants.FT_C_SOURCE); - doTestFileTypeResolution("some/path/file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, ".", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, ".c.", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, ".cpp.", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.c.", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.cpp.", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.c.input", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.cpp.input", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "c", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "cpp", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "numerical", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "some/path/file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "some/path/file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); // C source/header - doTestFileTypeResolution("file.c", ICFileTypeConstants.FT_C_SOURCE); - doTestFileTypeResolution("file.h", ICFileTypeConstants.FT_C_HEADER); - doTestFileTypeResolution("some.file.c", ICFileTypeConstants.FT_C_SOURCE); - doTestFileTypeResolution("some.file.h", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.h", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "some.file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "some.file.h", ICFileTypeConstants.FT_C_HEADER); // C++ source/header - doTestFileTypeResolution("file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); - doTestFileTypeResolution("file.cxx", ICFileTypeConstants.FT_CXX_SOURCE); - doTestFileTypeResolution("file.cc", ICFileTypeConstants.FT_CXX_SOURCE); - doTestFileTypeResolution("file.C", ICFileTypeConstants.FT_CXX_SOURCE); - doTestFileTypeResolution("file.hpp", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("file.hxx", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("file.hh", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("file.H", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("some.file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); - doTestFileTypeResolution("some.file.hxx", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.cxx", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.cc", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.C", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.hpp", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.hxx", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.hh", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.H", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "some.file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "some.file.hxx", ICFileTypeConstants.FT_CXX_HEADER); // Assembly - doTestFileTypeResolution("file.asm", ICFileTypeConstants.FT_ASM_SOURCE); - doTestFileTypeResolution("file.s", ICFileTypeConstants.FT_ASM_SOURCE); - doTestFileTypeResolution("file.S", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.asm", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.s", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.S", ICFileTypeConstants.FT_ASM_SOURCE); // Std C++ library - doTestFileTypeResolution("algorithm", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("bitset", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("deque", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("exception", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("fstream", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("functional", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("iomanip", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("ios", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("iosfwd", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("iostream", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("istream", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("iterator", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("limits", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("list", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("locale", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("map", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("memory", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("new", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("numeric", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("ostream", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("queue", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("set", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("sstream", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("stack", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("stdexcept", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("streambuf", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("string", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("typeinfo", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("utility", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("valarray", ICFileTypeConstants.FT_CXX_HEADER); - doTestFileTypeResolution("vector", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "algorithm", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "bitset", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "deque", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "exception", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "fstream", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "functional", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "iomanip", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "ios", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "iosfwd", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "iostream", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "istream", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "iterator", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "limits", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "list", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "locale", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "map", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "memory", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "new", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "numeric", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "ostream", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "queue", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "set", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "sstream", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "stack", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "stdexcept", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "streambuf", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "string", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "typeinfo", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "utility", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "valarray", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "vector", ICFileTypeConstants.FT_CXX_HEADER); // Failure cases - doTestFileTypeResolution("file.txt", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("file.doc", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("files", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("FILES", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("stream", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("streambu", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("streambuff", ICFileTypeConstants.FT_UNKNOWN); - doTestFileTypeResolution("sstreams", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.txt", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.doc", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "files", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "FILES", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "stream", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "streambu", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "streambuff", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "sstreams", ICFileTypeConstants.FT_UNKNOWN); } + public final void testWorkspaceFileTypeResolution() { + // Reset the resolver + model.setResolver(null); + workspaceResolver = model.getResolver(); + + // Validate that we are using the default resolver set... + doTestFileTypeResolution(workspaceResolver, "file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.h", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.hpp", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.s", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.sam", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.shari", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.delainey", ICFileTypeConstants.FT_UNKNOWN); + + // Set up a new resolver just for the tests + // This one will only recognize '*.c', '*.h', and '*.sam' + ICFileTypeResolver resolver = model.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)); + + // Set the workspace to use the new resolver + model.setResolver(resolver); + workspaceResolver = model.getResolver(); + + // Test the known types + doTestFileTypeResolution(workspaceResolver, "file.sam", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.shari", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.delainey", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "some.file.sam", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "some.file.shari", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "some.file.delainey", ICFileTypeConstants.FT_ASM_SOURCE); + + // Failure cases + doTestFileTypeResolution(workspaceResolver, "file.c", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.h", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.cpp", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.hpp", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.s", ICFileTypeConstants.FT_UNKNOWN); + + // Reset the resolver + model.setResolver(null); + workspaceResolver = model.getResolver(); + + // Validate that we are back to using the default resolver set... + doTestFileTypeResolution(workspaceResolver, "file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.h", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.hpp", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(workspaceResolver, "file.s", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(workspaceResolver, "file.sam", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.shari", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(workspaceResolver, "file.delainey", ICFileTypeConstants.FT_UNKNOWN); + } + + public final void testProjectFileTypeResolution() { + + // Reset the resolver(s) + model.setResolver(null); + workspaceResolver = model.getResolver(); + + model.setResolver(project, null); + projectResolver = model.getResolver(project); + + // Validate that we are using the default resolver set... + doTestFileTypeResolution(projectResolver, "file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(projectResolver, "file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(projectResolver, "file.hpp", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(projectResolver, "file.s", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(projectResolver, "file.sam", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.shari", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.delainey", ICFileTypeConstants.FT_UNKNOWN); + + // Set up a new resolver just for the tests + // This one will only recognize '*.c', '*.h', and '*.sam' + ICFileTypeResolver resolver = model.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)); + + // Set the workspace to use the new resolver + model.setResolver(project, resolver); + projectResolver = model.getResolver(project); + + // Test the known types + doTestFileTypeResolution(projectResolver, "file.sam", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(projectResolver, "file.shari", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(projectResolver, "file.delainey", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(projectResolver, "some.file.sam", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(projectResolver, "some.file.shari", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(projectResolver, "some.file.delainey", ICFileTypeConstants.FT_ASM_SOURCE); + + // Failure cases + doTestFileTypeResolution(projectResolver, "file.c", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.h", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.cpp", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.hpp", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.s", ICFileTypeConstants.FT_UNKNOWN); + + // Reset the resolver + model.setResolver(project, null); + projectResolver = model.getResolver(project); + + // Validate that we are back to using the default resolver set... + doTestFileTypeResolution(projectResolver, "file.c", ICFileTypeConstants.FT_C_SOURCE); + doTestFileTypeResolution(projectResolver, "file.h", ICFileTypeConstants.FT_C_HEADER); + doTestFileTypeResolution(projectResolver, "file.cpp", ICFileTypeConstants.FT_CXX_SOURCE); + doTestFileTypeResolution(projectResolver, "file.hpp", ICFileTypeConstants.FT_CXX_HEADER); + doTestFileTypeResolution(projectResolver, "file.s", ICFileTypeConstants.FT_ASM_SOURCE); + doTestFileTypeResolution(projectResolver, "file.sam", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.shari", ICFileTypeConstants.FT_UNKNOWN); + doTestFileTypeResolution(projectResolver, "file.delainey", ICFileTypeConstants.FT_UNKNOWN); + } + public final void testGetLanguages() { - ICLanguage[] languages = resolver.getLanguages(); + ICLanguage[] languages = model.getLanguages(); assertNotNull(languages); for (int i = 0; i < languages.length; i++) { - ICLanguage lang = resolver.getLanguageById(languages[i].getId()); + ICLanguage lang = model.getLanguageById(languages[i].getId()); assertNotNull(lang); assertEquals(languages[i], lang); } } public final void testGetTypes() { - ICFileType[] types = resolver.getFileTypes(); + ICFileType[] types = model.getFileTypes(); assertNotNull(types); for (int i = 0; i < types.length; i++) { - ICFileType type = resolver.getFileTypeById(types[i].getId()); + ICFileType type = model.getFileTypeById(types[i].getId()); assertNotNull(type); assertEquals(types[i], type); } } public final void testGetFileTypeAssociations() { - ICFileTypeAssociation[] assocs = resolver.getFileTypeAssociations(); + ICFileTypeAssociation[] assocs = workspaceResolver.getFileTypeAssociations(); assertNotNull(assocs); @@ -324,7 +509,7 @@ public class ResolverTests extends TestCase { assertNotNull(type); - ICFileType typeById = resolver.getFileTypeById(type.getId()); + ICFileType typeById = model.getFileTypeById(type.getId()); assertNotNull(typeById); assertEquals(type, typeById); @@ -340,7 +525,7 @@ public class ResolverTests extends TestCase { assertNotNull(langId); assertTrue(langId.length() > 0); - ICLanguage langOut = resolver.getLanguageById(langId); + ICLanguage langOut = model.getLanguageById(langId); assertNotNull(langOut); assertEquals(langIn, langOut); @@ -354,13 +539,13 @@ public class ResolverTests extends TestCase { ICLanguage langIn = new CLanguage(LANG_TEST, "Test Language"); - result = resolver.removeLanguage(langIn); + result = ((ResolverModel) model).removeLanguage(langIn); assertFalse(result); - result = resolver.addLanguage(langIn); + result = ((ResolverModel) model).addLanguage(langIn); assertTrue(result); - ICLanguage langOut = resolver.getLanguageById(LANG_TEST); + ICLanguage langOut = model.getLanguageById(LANG_TEST); assertNotNull(langOut); assertEquals(langIn, langOut); @@ -372,37 +557,37 @@ public class ResolverTests extends TestCase { // -- header - result = resolver.removeFileType(th); + result = ((ResolverModel) model).removeFileType(th); assertFalse(result); - result = resolver.addFileType(th); + result = ((ResolverModel) model).addFileType(th); assertTrue(result); - ICFileType thOut = resolver.getFileTypeById(FT_TEST_HEADER); + ICFileType thOut = model.getFileTypeById(FT_TEST_HEADER); assertNotNull(thOut); assertEquals(th, thOut); // -- source - result = resolver.removeFileType(ts); + result = ((ResolverModel) model).removeFileType(ts); assertFalse(result); - result = resolver.addFileType(ts); + result = ((ResolverModel) model).addFileType(ts); assertTrue(result); - ICFileType tsOut = resolver.getFileTypeById(FT_TEST_SOURCE); + ICFileType tsOut = model.getFileTypeById(FT_TEST_SOURCE); assertNotNull(tsOut); assertEquals(ts, tsOut); // -- unknown - result = resolver.removeFileType(tu); + result = ((ResolverModel) model).removeFileType(tu); assertFalse(result); - result = resolver.addFileType(tu); + result = ((ResolverModel) model).addFileType(tu); assertTrue(result); - ICFileType tuOut = resolver.getFileTypeById(FT_TEST_WHASAT); + ICFileType tuOut = model.getFileTypeById(FT_TEST_WHASAT); assertNotNull(tuOut); assertEquals(tu, tuOut); @@ -414,92 +599,90 @@ public class ResolverTests extends TestCase { // -- header - result = resolver.removeFileTypeAssociation(tha); + result = workspaceResolver.removeAssociation(tha); assertFalse(result); - result = resolver.addFileTypeAssociation(tha); + result = workspaceResolver.addAssociation(tha.getPattern(), tha.getType()); assertTrue(result); - ICFileType thaOut = resolver.getFileType("file.aest"); + ICFileType thaOut = workspaceResolver.getFileType("file.aest"); assertNotNull(thaOut); assertEquals(tha.getType(), thaOut); // -- source - result = resolver.removeFileTypeAssociation(tsa); + result = workspaceResolver.removeAssociation(tsa); assertFalse(result); - result = resolver.addFileTypeAssociation(tsa); + result = workspaceResolver.addAssociation(tsa.getPattern(), tsa.getType()); assertTrue(result); - ICFileType tsaOut = resolver.getFileType("file.test"); + ICFileType tsaOut = workspaceResolver.getFileType("file.test"); assertNotNull(tsaOut); assertEquals(tsa.getType(), tsaOut); // -- unknown - result = resolver.removeFileTypeAssociation(tua); + result = workspaceResolver.removeAssociation(tua); assertFalse(result); - result = resolver.addFileTypeAssociation(tua); + result = workspaceResolver.addAssociation(tua.getPattern(), tua.getType()); assertTrue(result); - ICFileType tuaOut = resolver.getFileType("file.zest"); + ICFileType tuaOut = workspaceResolver.getFileType("file.zest"); assertNotNull(tuaOut); assertEquals(tua.getType(), tuaOut); } public final void testRemove() { boolean result = false; - + // Languages - ICLanguage lang = resolver.getLanguageById(LANG_TEST); + ICLanguage lang = model.getLanguageById(LANG_TEST); + ICFileType fth = model.getFileTypeById(FT_TEST_HEADER); + ICFileType fts = model.getFileTypeById(FT_TEST_SOURCE); + ICFileType ftu = model.getFileTypeById(FT_TEST_WHASAT); + + // Test two file types + + result = ((ResolverModel) model).removeFileType(fth); + assertTrue(result); + + result = ((ResolverModel) model).removeFileType(fth); + assertFalse(result); + + result = ((ResolverModel) model).removeFileType(fts); + assertTrue(result); + + result = ((ResolverModel) model).removeFileType(fts); + assertFalse(result); + + // Removing the language should remove the + // remaining file type + assertNotNull(lang); assertEquals(LANG_TEST, lang.getId()); - result = resolver.removeLanguage(lang); + result = ((ResolverModel) model).removeLanguage(lang); assertTrue(result); - result = resolver.removeLanguage(lang); + result = ((ResolverModel) model).removeLanguage(lang); assertFalse(result); - // File types - - ICFileType ft = resolver.getFileTypeById(FT_TEST_HEADER); - - result = resolver.removeFileType(ft); - assertTrue(result); - - result = resolver.removeFileType(ft); - assertFalse(result); - - ft = resolver.getFileTypeById(FT_TEST_SOURCE); - - result = resolver.removeFileType(ft); - assertTrue(result); - - result = resolver.removeFileType(ft); - assertFalse(result); - - ft = resolver.getFileTypeById(FT_TEST_WHASAT); - - result = resolver.removeFileType(ft); - assertTrue(result); - - result = resolver.removeFileType(ft); + result = ((ResolverModel) model).removeFileType(ftu); assertFalse(result); // File type associations - ICFileTypeAssociation[] assocs = resolver.getFileTypeAssociations(); + ICFileTypeAssociation[] assocs = workspaceResolver.getFileTypeAssociations(); assertNotNull(assocs); assertTrue(assocs.length > 3); for (int i = 0; i < assocs.length; i++) { if (assocs[i].getType().getLanguage().getId().equals(LANG_TEST)) { - resolver.removeFileTypeAssociation(assocs[i]); + workspaceResolver.removeAssociation(assocs[i]); } } diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 5a96434646e..a797c0eb312 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,8 @@ +2004-05-25 Alain Magloire + + Major Patch from Sam Robb + bring to a close PR 52864. + 2004-05-25 Alain Magloire Ask the IScannerInfo for the IResource. diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java index 0b67adce39d..90354164f66 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java @@ -4,7 +4,6 @@ package org.eclipse.cdt.core; * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved. */ - import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; @@ -19,7 +18,8 @@ import java.util.ResourceBundle; import org.eclipse.cdt.core.filetype.ICFileType; import org.eclipse.cdt.core.filetype.ICFileTypeResolver; -import org.eclipse.cdt.core.internal.filetype.CFileTypeResolver; +import org.eclipse.cdt.core.filetype.IResolverModel; +import org.eclipse.cdt.core.internal.filetype.ResolverModel; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.parser.IScannerInfoProvider; @@ -136,7 +136,7 @@ public class CCorePlugin extends Plugin { private CoreModel fCoreModel; - private ICFileTypeResolver fFileTypeResolver; + private ResolverModel fResolverModel; // -------- static methods -------- @@ -265,7 +265,7 @@ public class CCorePlugin extends Plugin { getPluginPreferences().setDefault(PREF_USE_STRUCTURAL_PARSE_MODE, false); // Start file type manager - fFileTypeResolver = CFileTypeResolver.getDefault(); + fResolverModel = ResolverModel.getDefault(); } @@ -662,6 +662,22 @@ public class CCorePlugin extends Plugin { return new DefaultPathEntryStore(project); } + /** + * Returns the file type object corresponding to the provided + * file name, using the workspace resolver. + * + * If no file type object exists, a default file type object is + * returned. + * + * @param fileName Name of the file to resolve type info for. + * + * @return File type object for the provided file name, in the + * context of the workspace + */ + public ICFileType getFileType(String fileName) { + return getFileTypeResolver().getFileType(fileName); + } + /** * Returns the file type object corresponding to the provided * file name. @@ -669,21 +685,45 @@ public class CCorePlugin extends Plugin { * If no file type object exists, a default file type object is * returned. * - * The implementation checks for a match for the provided file name - * - By looking for an exact filename match ("iostream" == "iostream") - * - By looking for an extension match ("foo.c" == "*.c") - * - By looking for a pattern match ("libfoo.so.1.0" == "*.so*") + * @param project Project to resolve type info for. + * @param fileName Name of the file to resolve type info for. * - * @param fileName Name of the file to resolve type infor for. - * - * @return File type object for the provided file name. + * @return File type object for the provided file name, in the context + * of the given project (or the workspace, if project is null) */ public ICFileType getFileType(IProject project, String fileName) { - return fFileTypeResolver.getFileType(fileName); + return getFileTypeResolver(project).getFileType(fileName); } + /** + * Return the file type resolver for the workspace. + * + * @param project Project to get file type resolver for. + * + * @return File type resolver for the project. + */ public ICFileTypeResolver getFileTypeResolver() { - return fFileTypeResolver; + return getResolverModel().getResolver(); + } + + /** + * Return the file type resolver for the specified project. + * Specifying a null project returns the file type resolver + * for the workspace. + * + * @param project Project to get file type resolver for. + * * + * @return File type resolver for the project. + */ + public ICFileTypeResolver getFileTypeResolver(IProject project) { + if (null == project) { + return getResolverModel().getResolver(); + } + return getResolverModel().getResolver(project); + } + + public IResolverModel getResolverModel() { + return fResolverModel; } public CoreModel getCoreModel() { @@ -958,7 +998,7 @@ public class CCorePlugin extends Plugin { if(option != null) MatchLocator.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ option = Platform.getDebugOption(RESOLVER); - if(option != null) CFileTypeResolver.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ + if(option != null) ResolverModel.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$ if (indexFlag == true){ JobManager.VERBOSE = true; 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 23e53cbdb7c..7716f604903 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 @@ -10,6 +10,7 @@ ***********************************************************************/ package org.eclipse.cdt.core.filetype; + /** * Class responsible for resolving a file name into the * associated file type. @@ -17,68 +18,11 @@ package org.eclipse.cdt.core.filetype; * Accessed by ICFileTypeResolver and file type management UI. */ public interface ICFileTypeResolver { - /** - * @return array containing all known languages. - */ - public ICLanguage[] getLanguages(); - - /** - * @return array containing all known file types. - */ - public ICFileType[] getFileTypes(); - /** * @return array containing all known file types. */ public ICFileTypeAssociation[] getFileTypeAssociations(); - /** - * Add a new language to the resolver's list. - * - * @param language language to add. - * - * @return true if the language was added. - */ - public boolean addLanguage(ICLanguage language); - - /** - * Remove a language from the resolver's list. - * - * @param language language to remove. - * - * @return true if the language was removed. - */ - public boolean removeLanguage(ICLanguage language); - - /** - * Get the language that has the specified id. - * Returns null if no language has that id. - * - * @param languageId language id - * - * @return language with the specified id, or null - */ - public ICLanguage getLanguageById(String languageId); - - /** - * Add a new file type to the resolver's list. - * - * @param type file type to add. - * - * @return true if the file type object was added. - */ - public boolean addFileType(ICFileType type); - - /** - * Remove the file specified file type object from the - * resolver's list. - * - * @param type file type to remove. - * - * @return true if the file type was found and removed. - */ - public boolean removeFileType(ICFileType type); - /** * Determine which file type corresponds to the given * file name. @@ -87,17 +31,7 @@ public interface ICFileTypeResolver { * * @return file type for the provided file name */ - public ICFileType getFileType(String fileName); - - /** - * Get the file type that has the specified id. - * Returns null if no file type has that id. - * - * @param typeId file type id - * - * @return file type with the specified id, or null - */ - public ICFileType getFileTypeById(String typeId); + public ICFileType getFileType(String fileName); /** * Add a new file type association to the resolver's list. @@ -107,14 +41,14 @@ public interface ICFileTypeResolver { * * @return true if the file type association was added. */ - public boolean addFileTypeAssociation(ICFileTypeAssociation assoc); + public boolean addAssociation(String pattern, ICFileType type); /** * Remove a file type association from the resolver's list. * - * @param pattern file name pattern to remove. + * @param assoc file type association to remove. * * @return true if the file type association was removed. */ - public boolean removeFileTypeAssociation(ICFileTypeAssociation assoc); + public boolean removeAssociation(ICFileTypeAssociation assoc); } 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 new file mode 100644 index 00000000000..58079a2ff4a --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/filetype/IResolverModel.java @@ -0,0 +1,114 @@ +/********************************************************************** + * 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 + * 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; + +/** + * Main entry point for dealign with the resolver model. + */ +public interface IResolverModel { + /** + * @return array containing all known languages. + */ + public ICLanguage[] getLanguages(); + + /** + * @return array containing all known file types. + */ + public ICFileType[] getFileTypes(); + + /** + * Get the language that has the specified id. + * Returns null if no language has that id. + * + * @param languageId language id + * + * @return language with the specified id, or null + */ + public ICLanguage getLanguageById(String languageId); + + /** + * Get the file type that has the specified id. + * Returns null if no file type has that id. + * + * @param typeId file type id + * + * @return file type with the specified id, or null + */ + public ICFileType getFileTypeById(String typeId); + + /** + * Set the resolver for the current workspace. + * + * The workspace resolver is set to the specified + * resolver, and the resolver data is persisted + * in the workspace. + * + * @param resolver new workspace resolver. + */ + public void setResolver(ICFileTypeResolver resolver); + + /** + * Get the resolver for the current workspace. + * + * If the workspace resolver is unavailable (or + * identical to the default resolver), then the + * default resolver is returned. + * + * @return workspace resolver + */ + public ICFileTypeResolver getResolver(); + + /** + * Set the resolver for the specified project. + * + * The project resolver is set to the specified + * resolver, and the resolver data is persisted + * in the project (in the .cdtproject file). + * + * @param project project this resolver applied to + * @param resolver new project resolver + */ + public void setResolver(IProject project, ICFileTypeResolver resolver); + + /** + * Get the resolver for the specified project. + * + * If the project resolver is unavailable, or the + * project does not use a custom resolver, then the + * workspace resolver is returned. + * + * @param project to retrieve resolver for + * + * @return project resolver + */ + 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. + * + * @param pattern filename pattern for the association. + * @param type association file type. + * + * @return newly created file type association + */ + public ICFileTypeAssociation createAssocation(String pattern, ICFileType type); +} 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 03a30c182df..b25ae553ab9 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 @@ -10,104 +10,41 @@ ***********************************************************************/ package org.eclipse.cdt.core.internal.filetype; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.filetype.ICFileType; 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.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.Platform; -/** - * Implementation of the file type resolver interface. - */ public class CFileTypeResolver implements ICFileTypeResolver { - - public static boolean VERBOSE = false; - - private static final String EXTENSION_LANG = "CLanguage"; //$NON-NLS-1$ - private static final String EXTENSION_TYPE = "CFileType"; //$NON-NLS-1$ - private static final String EXTENSION_ASSOC = "CFileTypeAssociation"; //$NON-NLS-1$ - private static final String ATTR_ID = "id"; //$NON-NLS-1$ - private static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$ - private static final String ATTR_NAME = "name"; //$NON-NLS-1$ - private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - private static final String ATTR_EXT = "pattern"; //$NON-NLS-1$ - private static final String ATTR_FILE = "file"; //$NON-NLS-1$ - private static final String ATTR_VAL_SOURCE = "source"; //$NON-NLS-1$ - private static final String ATTR_VAL_HEADER = "header"; //$NON-NLS-1$ - - private static final String NAME_UNKNOWN = "Unknown"; - - /** - * Default language, returned when no other language matches a language id. - */ - public static final ICLanguage DEFAULT_LANG_TYPE = - new CLanguage(ICFileTypeConstants.LANG_UNKNOWN, NAME_UNKNOWN); - - /** - * Default file type, returned when no other file type matches a file name. - */ - public static final ICFileType DEFAULT_FILE_TYPE = - new CFileType(ICFileTypeConstants.FT_UNKNOWN, DEFAULT_LANG_TYPE, NAME_UNKNOWN, ICFileType.TYPE_UNKNOWN); - - // Singleton - private static ICFileTypeResolver instance = null; - - // Private ctor to preserve singleton status - private CFileTypeResolver() { - loadLanguages(); - loadTypes(); - loadAssociations(); - } - - /** - * @return the default instance of this singleton - */ - synchronized public static ICFileTypeResolver getDefault() { - if (null == instance) { - instance = new CFileTypeResolver(); - } - return instance; - } - - /** - * The language map holds a map of language IDs to descriptive strings. - */ - private Map fLangMap = new HashMap(); - - /** - * The type map holds a map of file type IDs to file types. - */ - private Map fTypeMap = new HashMap(); - /** * The association list holds a list of known file associations. */ - private List fAssocList = new ArrayList(); + 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 DEFAULT_FILE_TYPE if the file name could not be - * resolved to a particular file type. + * 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 DEFAULT_FILE_TYPE + * @return associated file type, or ResolverModel.DEFAULT_FILE_TYPE */ public ICFileType getFileType(String fileName) { for (Iterator iter = fAssocList.iterator(); iter.hasNext();) { @@ -116,135 +53,9 @@ public class CFileTypeResolver implements ICFileTypeResolver { return element.getType(); } } - return DEFAULT_FILE_TYPE; + return ResolverModel.DEFAULT_FILE_TYPE; } - - /** - * Get the file type that has the specified id. - * Returns null if no file type has that id. - * - * @param typeId file type id - * - * @return file type with the specified id, or null - */ - public ICFileType getFileTypeById(String typeId) { - ICFileType type = (ICFileType) fTypeMap.get(typeId); - return ((null != type) ? type : DEFAULT_FILE_TYPE); - } - - /** - * Get the language that has the specified id. - * Returns null if no language has that id. - * - * @param languageId language id - * - * @return language with the specified id, or null - */ - public ICLanguage getLanguageById(String languageId) { - ICLanguage lang = (ICLanguage) fLangMap.get(languageId); - return ((null != lang) ? lang : DEFAULT_LANG_TYPE); - } - - - /** - * @return the languages known to the resolver - */ - public ICLanguage[] getLanguages() { - Collection values = fLangMap.values(); - return (ICLanguage[]) values.toArray(new ICLanguage[values.size()]); - } - - /** - * @return the file types known to the resolver - */ - public ICFileType[] getFileTypes() { - Collection values = fTypeMap.values(); - return (ICFileType[]) values.toArray(new ICFileType[values.size()]); - } - - /** - * @return the file type associations known to the resolver - */ - public ICFileTypeAssociation[] getFileTypeAssociations() { - return (ICFileTypeAssociation[]) fAssocList.toArray(new ICFileTypeAssociation[fAssocList.size()]); - } - - /** - * Add an instance of a language to the languages 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 lang language instance to add - * - * @return true if the language is added, false otherwise - */ - public boolean addLanguage(ICLanguage lang) { - if (VERBOSE) { - debugLog("+ language " + lang.getId() + " as " + lang.getName()); - } - boolean added = false; - if (!fLangMap.containsValue(lang)) { - fLangMap.put(lang.getId(), lang); - added = true; - } - return added; - } - - /** - * Remove a language from the list of languages known to the resolver. - * - * @param lang language to remove - * - * @return true if the language is removed, false otherwise - */ - public boolean removeLanguage(ICLanguage lang) { - if (VERBOSE) { - debugLog("- language " + lang.getId() + " as " + lang.getName()); - } - // TODO: must remove any file types based on this language as well - return (null != fLangMap.remove(lang.getId())); - } - - /** - * Add an instance of a file type to the file types 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 type file type to add - * - * @return true if the file type is added, false otherwise - */ - public boolean addFileType(ICFileType type) { - if (VERBOSE) { - debugLog("+ type " + type.getId() + " as " + type.getName()); - } - boolean added = false; - if (!fTypeMap.containsValue(type)) { - fTypeMap.put(type.getId(), type); - added = true; - } - return added; - } - - /** - * Remove a file type from the list of type known to the resolver. - * - * @param type file type to remove - * - * @return true if the file type is removed, false otherwise - */ - public boolean removeFileType(ICFileType type) { - if (VERBOSE) { - debugLog("- type " + type.getId() + " as " + type.getName()); - } - // TODO: must remove any associations based on this file type as well - return (null != fTypeMap.remove(type.getId())); - } - + /** * Add an instance of a file type association to the associations * known to the resolver. @@ -256,190 +67,17 @@ public class CFileTypeResolver implements ICFileTypeResolver { * * @return true if the association is added, false otherwise */ - public boolean addFileTypeAssociation(ICFileTypeAssociation assoc) { - if (VERBOSE) { - debugLog("+ association " + assoc.getPattern() + " as " + assoc.getType().getId()); - } - boolean added = false; + public boolean addAssociation(String pattern, ICFileType type) { + boolean added = false; + ICFileTypeAssociation assoc = new CFileTypeAssociation(pattern, type); if (!fAssocList.contains(assoc)) { added = fAssocList.add(assoc); } return added; } - public boolean removeFileTypeAssociation(ICFileTypeAssociation assoc) { - if (VERBOSE) { - debugLog("- association " + assoc.getPattern() + " as " + assoc.getType().getId()); - } + public boolean removeAssociation(ICFileTypeAssociation assoc) { return fAssocList.remove(assoc); } - /** - * Load languages declared through the CLanguage extension point. - */ - private void loadLanguages() { - IExtensionPoint point = getExtensionPoint(EXTENSION_LANG); - IExtension[] extensions = point.getExtensions(); - IConfigurationElement[] elements = 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 name = elements[j].getAttribute(ATTR_NAME); - - try { - addLanguage(new CLanguage(id, name)); - } catch (IllegalArgumentException e) { - CCorePlugin.log(e); - } - } - } - - } - - /** - * Load file type declared through the CFileType extension point. - */ - private void loadTypes() { - IExtensionPoint point = getExtensionPoint(EXTENSION_TYPE); - IExtension[] extensions = point.getExtensions(); - IConfigurationElement[] elements = 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); - } - - } - } - } - - /** - * Load file type associations declared through the CFileTypeAssociation - * extension point. - */ - private void loadAssociations() { - IExtensionPoint point = getExtensionPoint(EXTENSION_ASSOC); - IExtension[] extensions = point.getExtensions(); - IConfigurationElement[] elements = null; - //ICFileTypeAssociation[] assocs = null; - - for (int i = 0; i < extensions.length; i++) { - elements = extensions[i].getConfigurationElements(); - for (int j = 0; j < elements.length; j++) { - ICFileType typeRef = getFileTypeById(elements[j].getAttribute(ATTR_TYPE)); - if (null != typeRef) { - addAssocFromPattern(typeRef, elements[j]); - addAssocFromFile(typeRef, elements[j]); - } - } - } - } - - /** - * Convenience method for getting an IExtensionPoint instance. - * - * @see org.eclipse.core.runtime.IPluginDescriptor#getExtensionPoint(String) - * - * @param extensionPointId the simple identifier of the extension point - * - * @return the extension point, or null - */ - private IExtensionPoint getExtensionPoint(String extensionPointId) { - return Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, extensionPointId); - } - - /** - * Turn a type string into an ICFileType.TYPE_* value. - * - * @param typeString type string ("source" or "header") - * - * @return corresponding ICFileType.TYPE_* value, or ICFileType.UNKNOWN - */ - private int parseType(String typeString) { - int type = ICFileType.TYPE_UNKNOWN; - - if (typeString.equals(ATTR_VAL_SOURCE)) { - type = ICFileType.TYPE_SOURCE; - } else if (typeString.equals(ATTR_VAL_HEADER)) { - type = ICFileType.TYPE_HEADER; - } - - return type; - } - - /** - * Associate one or more file extensions with an ICFileType instance. - * - * @param typeRef reference to the ICFileType instance - * - * @param element configuration element to get file extensions from - */ - private void addAssocFromPattern(ICFileType typeRef, IConfigurationElement element) { - String attr = element.getAttribute(ATTR_EXT); - if (null != attr) { - String[] item = attr.split(","); - for (int i = 0; i < item.length; i++) { - try { - addFileTypeAssociation(new CFileTypeAssociation(item[i].trim(), typeRef)); - } catch (IllegalArgumentException e) { - CCorePlugin.log(e); - } - } - } - } - - /** - * Associate the contents of a file with an ICFileType instance. - * - * The file is read, one entry per line; each line is taken as - * a pattern that should be associated with the specified ICFileType - * instance. - * - * @param typeRef reference to the ICFileType instance - * - * @param element configuration element to get file extensions from - */ - private void addAssocFromFile(ICFileType typeRef, IConfigurationElement element) { - String attr = element.getAttribute(ATTR_FILE); - - if (null != attr) { - URL baseURL = null; - URL fileURL = null; - BufferedReader in = null; - String line = null; - - try { - //baseURL = element.getDeclaringExtension().getDeclaringPluginDescriptor().getInstallURL(); - baseURL = Platform.getBundle(element.getDeclaringExtension().getNamespace()).getEntry("/"); //$NON-NLS-1$ - fileURL = new URL(baseURL, attr); - in = new BufferedReader(new InputStreamReader(fileURL.openStream())); - line = in.readLine(); - while (null != line) { - try { - addFileTypeAssociation(new CFileTypeAssociation(line, typeRef)); - } catch (IllegalArgumentException e) { - CCorePlugin.log(e); - } - line = in.readLine(); - } - in.close(); - } catch (IOException e) { - } - } - } - - private 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/ResolverModel.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java new file mode 100644 index 00000000000..f28df8b92af --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/internal/filetype/ResolverModel.java @@ -0,0 +1,680 @@ +/********************************************************************** + * 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 + * 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.internal.filetype; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.core.filetype.ICFileType; +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.IResolverModel; +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.IExtensionPoint; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.QualifiedName; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Implementation of the file type resolver interface. + */ +public class ResolverModel implements IResolverModel { + + /** + * Name used to describe an unknown language or file type + */ + public static final String NAME_UNKNOWN = "Unknown"; + + /** + * Default language, returned when no other language matches a language id. + */ + public static final ICLanguage DEFAULT_LANG_TYPE = + new CLanguage(ICFileTypeConstants.LANG_UNKNOWN, NAME_UNKNOWN); + + /** + * Default file type, returned when no other file type matches a file name. + */ + public static final ICFileType DEFAULT_FILE_TYPE = + new CFileType(ICFileTypeConstants.FT_UNKNOWN, DEFAULT_LANG_TYPE, NAME_UNKNOWN, ICFileType.TYPE_UNKNOWN); + + // The language map holds a map of language IDs to descriptive strings. + private Map fLangMap = new HashMap(); + + // The type map holds a map of file type IDs to file types. + private Map fTypeMap = new HashMap(); + + // Workspace resolver + private ICFileTypeResolver fWkspResolver = null; + + // XML tag names, etc. + private static final String EXTENSION_LANG = "CLanguage"; //$NON-NLS-1$ + private static final String EXTENSION_TYPE = "CFileType"; //$NON-NLS-1$ + private static final String EXTENSION_ASSOC = "CFileTypeAssociation"; //$NON-NLS-1$ + private static final String TAG_CUSTOM = "custom"; //$NON-NLS-1$ + private static final String TAG_ASSOC = "associations"; //$NON-NLS-1$ + private static final String TAG_ENTRY = "entry"; //$NON-NLS-1$ + private static final String ATTR_TYPE = "type"; //$NON-NLS-1$ + private static final String ATTR_PATTERN = "pattern"; //$NON-NLS-1$ + private static final String ATTR_FILE = "file"; //$NON-NLS-1$ + private static final String ATTR_ID = "id"; //$NON-NLS-1$ + private static final String ATTR_LANGUAGE = "language"; //$NON-NLS-1$ + private static final String ATTR_NAME = "name"; //$NON-NLS-1$ + private static final String ATTR_VAL_SOURCE = "source"; //$NON-NLS-1$ + private static final String ATTR_VAL_HEADER = "header"; //$NON-NLS-1$ + private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ + private static final String WKSP_STATE_FILE = "resolver.properties"; //$NON-NLS-1$ + private static final String CDT_RESOLVER = "cdt_resolver"; //$NON-NLS-1$ + + // Trace flag + public static boolean VERBOSE = false; + + // Singleton + 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 ctor to preserve singleton status + private ResolverModel() { + loadDeclaredLanguages(); + loadDeclaredTypes(); + } + + /** + * @return the default instance of this singleton + */ + synchronized public static ResolverModel getDefault() { + if (null == fInstance) { + fInstance = new ResolverModel(); + } + return fInstance; + } + + public ICLanguage[] getLanguages() { + Collection values = fLangMap.values(); + return (ICLanguage[]) values.toArray(new ICLanguage[values.size()]); + } + + public ICFileType[] getFileTypes() { + Collection values = fTypeMap.values(); + return (ICFileType[]) values.toArray(new ICFileType[values.size()]); + } + + public ICLanguage getLanguageById(String languageId) { + ICLanguage lang = (ICLanguage) fLangMap.get(languageId); + return ((null != lang) ? lang : DEFAULT_LANG_TYPE); + } + + public ICFileType getFileTypeById(String typeId) { + ICFileType type = (ICFileType) fTypeMap.get(typeId); + return ((null != type) ? type : DEFAULT_FILE_TYPE); + } + + synchronized public void setResolver(ICFileTypeResolver resolver) { + fWkspResolver = resolver; + saveWorkspaceResolver(resolver); + } + + synchronized public ICFileTypeResolver getResolver() { + if (null == fWkspResolver) { + fWkspResolver = internalGetWorkspaceResolver(); + } + return fWkspResolver; + } + + public void setResolver(IProject project, ICFileTypeResolver resolver) { + setResolverForSession(project, resolver); + saveProjectResolver(project, resolver); + } + + public ICFileTypeResolver getResolver(IProject project) { + ICFileTypeResolver resolver = null; + + if (null == project) { + resolver = getResolver(); + } else { + resolver = getResolverForSession(project); + if (null == resolver) { + resolver = internalGetProjectResolver(project); + } + } + + 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); + } + + /** + * Add an instance of a language to the languages 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 lang language instance to add + * + * @return true if the language is added, false otherwise + */ + public boolean addLanguage(ICLanguage lang) { + if (isDebugging()) { + debugLog("+ language " + lang.getId() + " as " + lang.getName()); + } + boolean added = false; + if (!fLangMap.containsValue(lang)) { + fLangMap.put(lang.getId(), lang); + added = true; + } + return added; + } + + /** + * Add an instance of a file type to the file types 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 type file type to add + * + * @return true if the file type is added, false otherwise + */ + public boolean addFileType(ICFileType type) { + if (isDebugging()) { + debugLog("+ type " + type.getId() + " as " + type.getName()); + } + boolean added = false; + if (!fTypeMap.containsValue(type)) { + fTypeMap.put(type.getId(), type); + added = true; + } + return added; + } + + /** + * Remove a language from the list of languages known to the resolver. + * + * @param lang language to remove + * + * @return true if the language is removed, false otherwise + */ + public boolean removeLanguage(ICLanguage lang) { + if (isDebugging()) { + debugLog("- language " + lang.getId() + " as " + lang.getName()); + } + 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; + } + + /** + * Remove a file type from the list of type known to the resolver. + * + * @param type file type to remove + * + * @return true if the file type is removed, false otherwise + */ + public boolean removeFileType(ICFileType type) { + if (isDebugging()) { + debugLog("- type " + type.getId() + " as " + type.getName()); + } + // 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())); + } + + /** + * Load languages declared through the CLanguage extension point. + */ + private void loadDeclaredLanguages() { + IExtensionPoint point = getExtensionPoint(EXTENSION_LANG); + IExtension[] extensions = point.getExtensions(); + IConfigurationElement[] elements = 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 name = elements[j].getAttribute(ATTR_NAME); + + try { + addLanguage(new CLanguage(id, name)); + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } + } + } + + } + + /** + * Load file type declared through the CFileType extension point. + */ + private void loadDeclaredTypes() { + IExtensionPoint point = getExtensionPoint(EXTENSION_TYPE); + IExtension[] extensions = point.getExtensions(); + IConfigurationElement[] elements = 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); + } + + } + } + } + + /** + * Turn a type string into an ICFileType.TYPE_* value. + * + * @param typeString type string ("source" or "header") + * + * @return corresponding ICFileType.TYPE_* value, or ICFileType.UNKNOWN + */ + private int parseType(String typeString) { + int type = ICFileType.TYPE_UNKNOWN; + + if (typeString.equals(ATTR_VAL_SOURCE)) { + type = ICFileType.TYPE_SOURCE; + } else if (typeString.equals(ATTR_VAL_HEADER)) { + type = ICFileType.TYPE_HEADER; + } + + 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 + //---------------------------------------------------------------------- + + /** + * Initialize the default resolver by loading data from + * declared extension points. + */ + private ICFileTypeResolver loadResolverDefaults() { + 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)); + if (null != typeRef) { + addAssocFromPattern(resolver, typeRef, elements[j]); + addAssocFromFile(resolver, typeRef, elements[j]); + } + } + } + + return resolver; + } + + /** + * Associate one or more file extensions with an ICFileType instance. + * + * @param typeRef reference to the ICFileType instance + * + * @param element configuration element to get file extensions from + */ + private void addAssocFromPattern(ICFileTypeResolver resolver, ICFileType typeRef, IConfigurationElement element) { + 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); + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } + } + } + } + + /** + * Associate the contents of a file with an ICFileType instance. + * + * The file is read, one entry per line; each line is taken as + * a pattern that should be associated with the specified ICFileType + * instance. + * + * @param typeRef reference to the ICFileType instance + * + * @param element configuration element to get file extensions from + */ + private void addAssocFromFile(ICFileTypeResolver resolver, ICFileType typeRef, IConfigurationElement element) { + String attr = element.getAttribute(ATTR_FILE); + + if (null != attr) { + URL baseURL = null; + URL fileURL = null; + BufferedReader in = null; + String line = null; + + try { + baseURL = Platform.getBundle(element.getDeclaringExtension().getNamespace()).getEntry("/"); //$NON-NLS-1$ + fileURL = new URL(baseURL, attr); + in = new BufferedReader(new InputStreamReader(fileURL.openStream())); + line = in.readLine(); + while (null != line) { + try { + resolver.addAssociation(line, typeRef); + } catch (IllegalArgumentException e) { + CCorePlugin.log(e); + } + line = in.readLine(); + } + in.close(); + } catch (IOException e) { + CCorePlugin.log(e); + } + } + } + + //---------------------------------------------------------------------- + // Workspace resolver + //---------------------------------------------------------------------- + + public boolean customWorkspaceResolverExists() { + return getWorkspaceResolverStateFilePath().toFile().exists(); + } + + private IPath getWorkspaceResolverStateFilePath() { + return CCorePlugin.getDefault().getStateLocation().append(WKSP_STATE_FILE); + } + + private ICFileTypeResolver loadWorkspaceResolver() { + ICFileTypeResolver resolver = null; + File file = getWorkspaceResolverStateFilePath().toFile(); + + if (file.exists()) { + Properties props = new Properties(); + ResolverModel model = ResolverModel.getDefault(); + FileInputStream in = null; + + resolver = new CFileTypeResolver(); + + try { + in = new FileInputStream(file); + + props.load(in); + + 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); + } + + in.close(); + } catch (IOException e) { + CCorePlugin.log(e); + } + + if (null != in) { + in = null; + } + } + + return resolver; + } + + public void saveWorkspaceResolver(ICFileTypeResolver resolver) { + File file = getWorkspaceResolverStateFilePath().toFile(); + BufferedWriter out = null; + + try { + if (null == resolver) { + file.delete(); + } else { + out = new BufferedWriter(new FileWriter(file)); + + ICFileTypeAssociation[] assoc = resolver.getFileTypeAssociations(); + + for (int i = 0; i < assoc.length; i++) { + out.write(assoc[i].getPattern() + '=' + assoc[i].getType().getId() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + if (null != out) { + out = null; + } + } + + //---------------------------------------------------------------------- + // Project resolver + //---------------------------------------------------------------------- + + public boolean customProjectResolverExists(IProject project) { + Element data = getProjectData(project); + Node child = ((null != data) ? data.getFirstChild() : null); + Boolean custom = new Boolean(false); + + while (child != null) { + if (child.getNodeName().equals(TAG_CUSTOM)) { + custom = Boolean.valueOf(((Element)child).getAttribute(ATTR_VALUE)); + } + child = child.getNextSibling(); + } + + return custom.booleanValue(); + } + + private ICDescriptor getProjectDescriptor(IProject project) { + ICDescriptor descriptor = null; + try { + descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + } catch (CoreException e) { + } + return descriptor; + } + + private Element getProjectData(IProject project) { + Element data = null; + try { + data = getProjectDescriptor(project).getProjectData(CDT_RESOLVER); + } catch (CoreException e) { + } + return data; + } + + public ICFileTypeResolver loadProjectResolver(IProject project) { + ICFileTypeResolver resolver = new CFileTypeResolver(); + ResolverModel model = ResolverModel.getDefault(); + Element data = getProjectData(project); + Node child = ((null != data) ? data.getFirstChild() : null); + + while (child != null) { + if (child.getNodeName().equals(TAG_ASSOC)) { + Node assoc = child.getFirstChild(); + while (assoc != null) { + if (assoc.getNodeName().equals(TAG_ENTRY)) { + Element element = (Element) assoc; + String pattern = element.getAttribute(ATTR_PATTERN); + String typeId = element.getAttribute(ATTR_TYPE); + resolver.addAssociation(pattern, model.getFileTypeById(typeId)); + } + assoc = assoc.getNextSibling(); + } + } + child = child.getNextSibling(); + } + + return resolver; + } + + public void saveProjectResolver(IProject project, ICFileTypeResolver resolver) { + ResolverModel model = ResolverModel.getDefault(); + Element root = getProjectData(project); + Document doc = root.getOwnerDocument(); + Node child = root.getFirstChild(); + Element element = null; + + while (child != null) { + root.removeChild(child); + child = root.getFirstChild(); + } + + element = doc.createElement(TAG_CUSTOM); + element.setAttribute(ATTR_VALUE, new Boolean(null != resolver).toString()); + root.appendChild(element); + + if (null != resolver) { + element = doc.createElement(TAG_ASSOC); + root.appendChild(element); + + root = element; // Note that root changes... + + ICFileTypeAssociation[] assoc = resolver.getFileTypeAssociations(); + + for (int i = 0; i < assoc.length; i++) { + element = doc.createElement(TAG_ENTRY); + element.setAttribute(ATTR_PATTERN, assoc[i].getPattern()); + element.setAttribute(ATTR_TYPE, assoc[i].getType().getId()); + root.appendChild(element); + } + } + + try { + getProjectDescriptor(project).saveProjectData(); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + +} diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 1c49cbaf2d3..ebb11515ab7 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -63,6 +63,7 @@ CPluginPreferencePage.name=C/C++ CPluginEditorPreferencePage.name=C/C++ Editor CPluginTemplatePreferencePage.name=Code Templates CPluginBuildConsolePreferencePage.name=Build Console +CPluginFileTypesPreferencePage.name=C/C++ File Types CProjectPropertyPage.name=C/C++ Project CLaunchingPropertyPage.executionArguments.name=C Execution Arguments CApplicationLauncher.label=Executable @@ -155,6 +156,8 @@ WorkInProgress.name=Work In Progress CDTIndexerProperty.name=C/C++ Indexer +CDTFileTypesProperty.name=C/C++ File Types + cDocumentFactory=C Document Factory cDocumentSetupParticipant=C Document Setup Participant diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 3bef483e034..ae439ab71d0 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -298,6 +298,18 @@ class="org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage" id="org.eclipse.cdt.ui.preferneces.CBuildConsolePreferernces"> + + + + @@ -636,15 +648,6 @@ overviewRulerPreferenceKey="indexResultIndicationInOverviewRuler"> - - - - + + + + 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 new file mode 100644 index 00000000000..a73258ebb15 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypeDialog.java @@ -0,0 +1,164 @@ +/********************************************************************** + * 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.preferences; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.filetype.ICFileType; +import org.eclipse.cdt.core.filetype.IResolverModel; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class CFileTypeDialog extends Dialog { + + public CFileTypeDialog(Shell parentShell) { + super(parentShell); + } + + private Text fTextPattern; + private Combo fComboType; + + private String fPattern; + private ICFileType fType; + + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(PreferencesMessages.getString("CFileTypeDialog.title")); //$NON-NLS-1$ + } + + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + + getOkayButton().setEnabled(getPatternFromControl().length() > 0); + } + + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea(parent); + ((GridLayout) composite.getLayout()).numColumns = 2; + + // Pattern row + + Label pattern = new Label(composite, SWT.NONE); + + pattern.setText(PreferencesMessages.getString("CFileTypeDialog.patternLabel")); //$NON-NLS-1$ + + fTextPattern = new Text(composite, SWT.BORDER | SWT.SINGLE); + + fTextPattern.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + if (null != fPattern) { + fTextPattern.setText(fPattern); + } + + fTextPattern.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getOkayButton().setEnabled(getPatternFromControl().length() > 0); + } + }); + + // Type row + + Label type = new Label(composite, SWT.NONE); + + type.setText(PreferencesMessages.getString("CFileTypeDialog.typeLabel")); //$NON-NLS-1$ + + fComboType = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.SINGLE); + + fComboType.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + populateTypesCombo(); + + return composite; + } + + public void setPattern(String pattern) { + fPattern = pattern; + } + + public String getPattern() { + return fPattern; + } + + public void setType(ICFileType type) { + fType = type; + } + + public ICFileType getType() { + return fType; + } + + private void populateTypesCombo() { + ICFileType[] types = getResolverModel().getFileTypes(); + int index = -1; + + for (int i = 0; i < types.length; i++) { + fComboType.add(types[i].getName()); + } + + fComboType.setData(types); + + if (null != fType) { + index = fComboType.indexOf(fType.getName()); + } + + fComboType.select((index < 0) ? 0 : index); + } + + private IResolverModel getResolverModel() { + return CCorePlugin.getDefault().getResolverModel(); + } + + private Button getOkayButton() { + return getButton(IDialogConstants.OK_ID); + } + + private String getPatternFromControl() { + return fTextPattern.getText().trim(); + } + + private ICFileType getTypeFromControl() { + String typeId = null; + int index = fComboType.getSelectionIndex(); + + if (-1 != index) { + String name = fComboType.getItem(index); + ICFileType[] types = (ICFileType[]) fComboType.getData(); + for (int i = 0; i < types.length; i++) { + if (name.equals(types[i].getName())) { + typeId = types[i].getId(); + } + } + } + + return getResolverModel().getFileTypeById(typeId); + } + + protected void okPressed() { + fPattern = getPatternFromControl(); + fType = getTypeFromControl(); + + super.okPressed(); + } + + +} 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 new file mode 100644 index 00000000000..6cd70ce4f76 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferenceBlock.java @@ -0,0 +1,348 @@ +/********************************************************************** + * 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial implementation +***********************************************************************/ +package org.eclipse.cdt.internal.ui.preferences; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.filetype.ICFileTypeAssociation; +import org.eclipse.cdt.core.filetype.ICFileTypeResolver; +import org.eclipse.cdt.core.filetype.IResolverModel; +import org.eclipse.cdt.internal.ui.util.PixelConverter; +import org.eclipse.cdt.internal.ui.util.SWTUtil; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableLayout; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +/* + * Preference block that encapsulates the controls used + * for displaying/editing CDT file type associations + */ +public class CFileTypesPreferenceBlock { + + private static final int COL_PATTERN = 0; + private static final int COL_DESCRIPTION = 1; + private static final int COL_LANGUAGE = 2; + + private ICFileTypeResolver fResolver; + private ArrayList fAddAssoc; + private ArrayList fRemoveAssoc; + + private TableViewer fAssocViewer; + private Button fBtnNew; + private Button fBtnRemove; + + private class AssocSorter extends ViewerSorter { + public int category(Object element) { + if (element instanceof ICFileTypeAssociation) { + ICFileTypeAssociation assoc = (ICFileTypeAssociation) element; + if (-1 != assoc.getPattern().indexOf('*')) { + return 10; + } + return 20; + } + return 30; + } + }; + + private class AssocContentProvider implements IStructuredContentProvider { + ICFileTypeAssociation[] assocs; + + public Object[] getElements(Object inputElement) { + return assocs; + } + + public void dispose() { + assocs = null; + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput instanceof ICFileTypeAssociation[]) { + assocs = (ICFileTypeAssociation[]) newInput; + } + } + }; + + private class AssocLabelProvider implements ILabelProvider, ITableLabelProvider { + private ListenerList listeners = new ListenerList(); + + public Image getColumnImage(Object element, int columnIndex) { + if (element instanceof ICFileTypeAssociation) { + if (COL_PATTERN == columnIndex) { + // TODO: add image support to table + return null; + } + } + return null; + } + + public String getColumnText(Object element, int columnIndex) { + if (element instanceof ICFileTypeAssociation) { + ICFileTypeAssociation assoc = (ICFileTypeAssociation) element; + switch (columnIndex) { + case COL_PATTERN: + return assoc.getPattern(); + + case COL_DESCRIPTION: + return assoc.getType().getName(); + + case COL_LANGUAGE: + return assoc.getType().getLanguage().getName(); + } + } + return element.toString(); + } + + public void addListener(ILabelProviderListener listener) { + listeners.add(listener); + } + + public void dispose() { + listeners.clear(); + listeners = null; + } + + public boolean isLabelProperty(Object element, String property) { + return false; + } + + public void removeListener(ILabelProviderListener listener) { + listeners.remove(listener); + } + + public Image getImage(Object element) { + return getColumnImage(element, 0); + } + + public String getText(Object element) { + return getColumnText(element, 0); + } + + }; + + public CFileTypesPreferenceBlock(ICFileTypeResolver input) { + fResolver = input; + fAddAssoc = new ArrayList(); + fRemoveAssoc = new ArrayList(); + } + + public Control createControl(Composite parent) { + Composite control = new Composite(parent, SWT.NONE); + GridLayout controlLayout = new GridLayout(2, false); + + controlLayout.marginHeight = 0; + controlLayout.marginWidth = 0; + + control.setLayout(controlLayout); + control.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL)); + + // Create the table viewer for file associations + + Composite tablePane = new Composite(control, SWT.NONE); + GridLayout tablePaneLayout = new GridLayout(); + GridData gridData = new GridData(GridData.FILL_BOTH); + + tablePaneLayout.marginHeight = 0; + tablePaneLayout.marginWidth = 0; + + tablePane.setLayout(tablePaneLayout); + tablePane.setLayoutData(gridData); + + Table table = new Table(tablePane, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); + + TableLayout tblLayout = new TableLayout(); + TableColumn col = null; + + gridData = new GridData(GridData.FILL_BOTH); + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + gridData.heightHint = SWTUtil.getTableHeightHint(table, 25); + gridData.widthHint = new PixelConverter(parent).convertWidthInCharsToPixels(60); + + tblLayout.addColumnData(new ColumnWeightData(20)); + tblLayout.addColumnData(new ColumnWeightData(60)); + tblLayout.addColumnData(new ColumnWeightData(20)); + + table.setLayout(tblLayout); + table.setLayoutData(gridData); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + col = new TableColumn(table, SWT.LEFT); + col.setText(PreferencesMessages.getString("CFileTypesPreferencePage.colTitlePattern")); //$NON-NLS-1$ + + col = new TableColumn(table, SWT.LEFT); + col.setText(PreferencesMessages.getString("CFileTypesPreferencePage.colTitleDescription")); //$NON-NLS-1$ + + col = new TableColumn(table, SWT.LEFT); + col.setText(PreferencesMessages.getString("CFileTypesPreferencePage.colTitleLanguage")); //$NON-NLS-1$ + + // Create the button pane + + Composite buttonPane = new Composite(control, SWT.NONE); + GridLayout buttonPaneLayout = new GridLayout(); + GridData data = null; + + buttonPaneLayout.marginHeight = 0; + buttonPaneLayout.marginWidth = 0; + + buttonPane.setLayout(buttonPaneLayout); + buttonPane.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + + // New button + + fBtnNew = new Button(buttonPane, SWT.PUSH); + gridData = new GridData(GridData.FILL_HORIZONTAL); + + gridData.widthHint = SWTUtil.getButtonWidthHint(fBtnNew); + gridData.heightHint = SWTUtil.getButtonHeigthHint(fBtnNew); + + fBtnNew.setLayoutData(gridData); + fBtnNew.setText("New ..."); // TODO: get standard text + + fBtnNew.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + handleAdd(); + } + }); + + // Remove button + + fBtnRemove = new Button(buttonPane, SWT.PUSH); + gridData = new GridData(GridData.FILL_HORIZONTAL); + + gridData.widthHint = SWTUtil.getButtonWidthHint(fBtnRemove); + gridData.heightHint = SWTUtil.getButtonHeigthHint(fBtnRemove); + + fBtnRemove.setLayoutData(gridData); + fBtnRemove.setText("Remove"); // TODO: get standard text + + fBtnRemove.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + handleRemove(); + } + }); + + // Hook up the viewer + + fAssocViewer = new TableViewer(table); + + fAssocViewer.setSorter(new AssocSorter()); + fAssocViewer.setContentProvider(new AssocContentProvider()); + fAssocViewer.setLabelProvider(new AssocLabelProvider()); + fAssocViewer.setInput(getResolver().getFileTypeAssociations()); + + fAssocViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + handleSelectionChanged(); + } + }); + + handleSelectionChanged(); + + return control; + } + + public void setEnabled(boolean enabled) { + fAssocViewer.getTable().setEnabled(enabled); + fBtnNew.setEnabled(enabled); + fBtnRemove.setEnabled(enabled); + } + + public void setResolver(ICFileTypeResolver resolver) { + fAddAssoc.clear(); + fRemoveAssoc.clear(); + fResolver = resolver; + fAssocViewer.setInput(fResolver.getFileTypeAssociations()); + } + + 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()); + } + + for (Iterator iter = fRemoveAssoc.iterator(); iter.hasNext();) { + ICFileTypeAssociation assoc = (ICFileTypeAssociation) iter.next(); + fResolver.removeAssociation(assoc); + } + + fAddAssoc.clear(); + fRemoveAssoc.clear(); + } + + private void handleSelectionChanged() { + IStructuredSelection sel = getSelection(); + fBtnRemove.setEnabled(!sel.isEmpty()); + } + + private IResolverModel getResolverModel() { + return CCorePlugin.getDefault().getResolverModel(); + } + + private void handleAdd() { + ICFileTypeAssociation assoc = null; + + CFileTypeDialog dlg = new CFileTypeDialog(((Composite) fBtnNew.getParent()).getShell()); + + if (Window.OK == dlg.open()) { + assoc = getResolverModel().createAssocation(dlg.getPattern(), dlg.getType()); + if (null != assoc) { + fAssocViewer.add(assoc); + fAddAssoc.add(assoc); + fRemoveAssoc.remove(assoc); + } + } + } + + private void handleRemove() { + IStructuredSelection sel = getSelection(); + if ((null != sel) && (!sel.isEmpty())) { + for (Iterator iter = sel.iterator(); iter.hasNext();) { + ICFileTypeAssociation assoc = (ICFileTypeAssociation) iter.next(); + fAssocViewer.remove(assoc); + fAddAssoc.remove(assoc); + fRemoveAssoc.add(assoc); + } + } + } + + private IStructuredSelection getSelection() { + return (IStructuredSelection) fAssocViewer.getSelection(); + } +} 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 new file mode 100644 index 00000000000..fa258d55b72 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPreferencePage.java @@ -0,0 +1,89 @@ +/********************************************************************** + * 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial implementation +***********************************************************************/ +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.ui.CUIPlugin; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/* + * The preference page used for displaying/editing CDT file + * type associations for the workspace + */ +public class CFileTypesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private CFileTypesPreferenceBlock fPrefsBlock; + + public CFileTypesPreferencePage() { + setDescription(PreferencesMessages.getString("CFileTypesPreferencePage.description")); //$NON-NLS-1$ + setPreferenceStore(CUIPlugin.getDefault().getPreferenceStore()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + Composite topPane = new Composite(parent, SWT.NONE); + + topPane.setLayout(new GridLayout()); + topPane.setLayoutData(new GridData(GridData.FILL_BOTH)); + + ICFileTypeResolver resolver = CCorePlugin.getDefault().getFileTypeResolver(null); + fPrefsBlock = new CFileTypesPreferenceBlock(resolver); + + return fPrefsBlock.createControl(topPane); + + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + protected void performDefaults() { + IResolverModel model = getResolverModel(); + + model.setResolver(null); + fPrefsBlock.setResolver(model.getResolver()); + + super.performDefaults(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performApply() + */ + protected void performApply() { + IResolverModel model = getResolverModel(); + + fPrefsBlock.performApply(); + model.setResolver(fPrefsBlock.getResolver()); + + super.performApply(); + } + + private IResolverModel getResolverModel() { + return CCorePlugin.getDefault().getResolverModel(); + } + +} 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 new file mode 100644 index 00000000000..f562bf0bcb5 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java @@ -0,0 +1,143 @@ +/********************************************************************** + * 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 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * TimeSys Corporation - Initial implementation +***********************************************************************/ +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; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.dialogs.PropertyPage; + +/* + * The preference page used for displaying/editing CDT file + * type associations for a project + */ +public class CFileTypesPropertyPage extends PropertyPage { + + private Button fUseWorkspace; + private Button fUseProject; + private CFileTypesPreferenceBlock fPrefsBlock; + + public CFileTypesPropertyPage(){ + super(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + Composite topPane = new Composite(parent, SWT.NONE); + + topPane.setLayout(new GridLayout()); + topPane.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Workspace radio buttons + + Composite radioPane = new Composite(topPane, SWT.NONE); + + radioPane.setLayout(new GridLayout()); + radioPane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fUseWorkspace = new Button(radioPane, SWT.RADIO); + fUseWorkspace.setText(PreferencesMessages.getString("CFileTypesPropertyPage.useWorkspaceSettings")); + fUseWorkspace.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + fPrefsBlock.setEnabled(false); + } + }); + + fUseProject = new Button(radioPane, SWT.RADIO); + fUseProject.setText(PreferencesMessages.getString("CFileTypesPropertyPage.useProjectSettings")); + fUseProject.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event e) { + fPrefsBlock.setEnabled(true); + } + }); + + // 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); + + Composite blockPane = new Composite(topPane, SWT.NONE); + + blockPane.setLayout(new GridLayout()); + blockPane.setLayoutData(new GridData(GridData.FILL_BOTH)); + + fPrefsBlock = new CFileTypesPreferenceBlock(resolver); + + fPrefsBlock.createControl(blockPane); + + fUseWorkspace.setSelection(!custom); + fUseProject.setSelection(custom); + fPrefsBlock.setEnabled(custom); + + return topPane; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + protected void performDefaults() { + fUseWorkspace.setSelection(true); + fUseProject.setSelection(false); + + fPrefsBlock.setEnabled(false); + + super.performDefaults(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performApply() + */ + protected void performApply() { + IResolverModel model = getResolverModel(); + + fPrefsBlock.performApply(); + + if (fUseProject.getSelection()) { + model.setResolver(getProject(), null); + model.setResolver(getProject(), fPrefsBlock.getResolver()); + } else { + model.setResolver(getProject(), null); + } + + super.performApply(); + } + + private IProject getProject(){ + Object element = getElement(); + IProject project = null; + + if ((null != element) && (element instanceof IProject)) { + project = (IProject) element; + } + + return project; + } + + private IResolverModel getResolverModel() { + return CCorePlugin.getDefault().getResolverModel(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index 263efbfaa67..d41c42a7c66 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -125,3 +125,14 @@ CEditorPreferencePage.Navigation=Navigation CEditorPreferencePage.Enable_Hyperlink_Navigation=Enable Hyperlink Navigation TemplatePreferencePage.Viewer.preview=Preview: + +CFileTypesPreferencePage.description=C/C++ File Types +CFileTypesPreferencePage.colTitlePattern=Filename +CFileTypesPreferencePage.colTitleDescription=Description +CFileTypesPreferencePage.colTitleLanguage=Language + +CFileTypesPropertyPage.useWorkspaceSettings=Use workspace settings +CFileTypesPropertyPage.useProjectSettings=Use project settings + +CFileTypeDialog.patternLabel=Pattern: +CFileTypeDialog.typeLabel=Type: