From 752e15020509afae15c35368c01cb044493d984a Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 12 Jul 2006 09:36:45 +0000 Subject: [PATCH] Extracted content type specific code to one common class. --- .../UpdateManagedProject21.java | 19 +- .../src/org/eclipse/cdt/core/CCorePlugin.java | 120 ++--------- .../cdt/internal/core/CContentTypes.java | 191 ++++++++++++++++++ .../preferences/CFileTypesPropertyPage.java | 84 ++------ 4 files changed, 225 insertions(+), 189 deletions(-) create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CContentTypes.java diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject21.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject21.java index 2a07c479a83..09244494d2f 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject21.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/projectconverter/UpdateManagedProject21.java @@ -6,13 +6,15 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Intel Corporation - Initial API and implementation + * Intel Corporation - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.managedbuilder.projectconverter; import java.io.File; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; @@ -27,7 +29,6 @@ import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; @@ -38,14 +39,8 @@ import org.eclipse.core.runtime.content.IContentTypeSettings; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.core.runtime.preferences.IScopeContext; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; class UpdateManagedProject21 { - - private static final String CONTENT_TYPE_PREF_NODE = "content-types"; //$NON-NLS-1$ - private static final String FULLPATH_CONTENT_TYPE_PREF_NODE = Platform.PI_RUNTIME + IPath.SEPARATOR + CONTENT_TYPE_PREF_NODE; - private static final String PREF_LOCAL_CONTENT_TYPE_SETTINGS = "enabled"; //$NON-NLS-1$ /** * @param monitor the monitor to allow users to cancel the long-running operation @@ -153,14 +148,8 @@ class UpdateManagedProject21 { // Unfortunately there is no clear API in Eclipse-3.1 to do this. // We should revisit this code when Eclipse-3.1.x and above is out // with more complete API. - Preferences contentTypePrefs = projectScope.getNode(FULLPATH_CONTENT_TYPE_PREF_NODE); // enable project-specific settings for this project - contentTypePrefs.putBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, true); - try { - contentTypePrefs.flush(); - } catch (BackingStoreException e) { - // ignore ?? - } + CCorePlugin.setUseProjectSpecificContentTypes(project, true); // Now the project setting is on/enable. // Add the new association in the project user setting. 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 e3cc636f55f..a990341e856 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 @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.core.resources.IPathEntryVariableManager; import org.eclipse.cdt.core.resources.ScannerProvider; +import org.eclipse.cdt.internal.core.CContentTypes; import org.eclipse.cdt.internal.core.CDTLogWriter; import org.eclipse.cdt.internal.core.CDescriptorManager; import org.eclipse.cdt.internal.core.PathEntryVariableManager; @@ -47,7 +48,6 @@ import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; @@ -63,9 +63,6 @@ import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.core.runtime.content.IContentTypeMatcher; -import org.eclipse.core.runtime.content.IContentTypeSettings; -import org.eclipse.core.runtime.preferences.IScopeContext; import org.osgi.framework.BundleContext; public class CCorePlugin extends Plugin { @@ -878,7 +875,7 @@ public class CCorePlugin extends Plugin { * @return */ public static IContentType getContentType(String filename) { - return getContentType(null, filename); + return CContentTypes.getContentType(null, filename); } /** @@ -890,108 +887,24 @@ public class CCorePlugin extends Plugin { * @return the content type found or null */ public static IContentType getContentType(IProject project, String filename) { - IContentTypeMatcher matcher= null; - IScopeContext scopeCtx= null; - boolean preferCpp= true; - if (project != null) { - // try with the project settings - try { - matcher= project.getContentTypeMatcher(); - scopeCtx= new ProjectScope(project); - preferCpp= CoreModel.hasCCNature(project); - } catch (CoreException e) { - // fallback to workspace wide definitions. - matcher= Platform.getContentTypeManager(); - } - } - else { - matcher= Platform.getContentTypeManager(); - } - - IContentType[] cts = matcher.findContentTypesFor(filename); - switch (cts.length) { - case 0: - return null; - case 1: - return cts[0]; - } - - int maxPossiblePriority= scopeCtx == null ? 11 : 101; - int bestPriority= -1; - IContentType bestResult= null; - - for (int i = 0; i < cts.length; i++) { - IContentType candidate= cts[i]; - int priority= 0; - try { - if (scopeCtx != null) { - IContentTypeSettings settings= candidate.getSettings(scopeCtx); - if (isStrictlyAssociatedWith(settings, filename)) { - priority= 100; - } - } - if (priority == 0 && bestPriority < 100) { - if (isStrictlyAssociatedWith(candidate, filename)) { - priority= 10; - } - } - if (isPreferredContentType(candidate, preferCpp)) { - priority+= 1; - } - } - catch (CoreException e) { - // skip it - } - if (priority > bestPriority) { - if (priority == maxPossiblePriority) { - return candidate; - } - bestPriority= priority; - bestResult= candidate; - } - } - return bestResult; + return CContentTypes.getContentType(project, filename); + } + + /** + * Tests whether the given project uses its project specific content types. + */ + public static boolean usesProjectSpecificContentTypes(IProject project) { + return CContentTypes.usesProjectSpecificContentTypes(project); } - private static boolean isPreferredContentType(IContentType candidate, boolean preferCpp) { - while (candidate != null) { - String id= candidate.getId(); - boolean isCpp= CONTENT_TYPE_CXXHEADER.equals(id) || CONTENT_TYPE_CXXSOURCE.equals(id); - if (isCpp) { - return preferCpp; - } - boolean isC= CONTENT_TYPE_CHEADER.equals(id) || CONTENT_TYPE_CSOURCE.equals(id); - if (isC) { - return !preferCpp; - } - candidate= candidate.getBaseType(); - } - return false; - } - - private static boolean isStrictlyAssociatedWith(IContentTypeSettings settings, String filename) { - String[] namespecs= settings.getFileSpecs(IContentType.FILE_NAME_SPEC); - for (int i = 0; i < namespecs.length; i++) { - String name = namespecs[i]; - if (name.equals(filename)) { - return true; - } - } - // check the file extensions only - int dotPosition = filename.lastIndexOf('.'); - if (dotPosition >= 0 && dotPosition < filename.length()-1) { - String fileExtension= filename.substring(dotPosition + 1); - String[] extensions= settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - for (int i = 0; i < extensions.length; i++) { - String ext = extensions[i]; - if (ext.equals(fileExtension)) { - return true; - } - } - } - return false; + /** + * Enables or disables the project specific content types. + */ + public static void setUseProjectSpecificContentTypes(IProject project, boolean val) { + CContentTypes.setUseProjectSpecificContentTypes(project, val); } + private static final String MODEL = CCorePlugin.PLUGIN_ID + "/debug/model" ; //$NON-NLS-1$ private static final String PARSER = CCorePlugin.PLUGIN_ID + "/debug/parser" ; //$NON-NLS-1$ @@ -1034,5 +947,4 @@ public class CCorePlugin extends Plugin { return CDOM.getInstance(); } - } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CContentTypes.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CContentTypes.java new file mode 100644 index 00000000000..f20d65e37f3 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CContentTypes.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.core.runtime.content.IContentTypeMatcher; +import org.eclipse.core.runtime.content.IContentTypeSettings; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +/** + * Handles the access to the content types of the platform. + * @author markus.schorn@windriver.com + */ +public class CContentTypes { + private static final String PREF_LOCAL_CONTENT_TYPE_SETTINGS = "enabled"; //$NON-NLS-1$ + private static final Preferences PROJECT_SCOPE = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); + private static final String CONTENT_TYPE_PREF_NODE = "content-types"; //$NON-NLS-1$ + private static final String FULLPATH_CONTENT_TYPE_PREF_NODE = Platform.PI_RUNTIME + IPath.SEPARATOR + CONTENT_TYPE_PREF_NODE; + + /** + * Implementation for {@link CCorePlugin#getContentType(IProject, String)}. + */ + public static IContentType getContentType(IProject project, String filename) { + IContentTypeMatcher matcher= null; + IScopeContext scopeCtx= null; + boolean preferCpp= true; + if (project != null) { + // try with the project settings + try { + matcher= project.getContentTypeMatcher(); + if (usesProjectSpecificContentTypes(project)) { + scopeCtx= new ProjectScope(project); + } + preferCpp= CoreModel.hasCCNature(project); + } catch (CoreException e) { + // fallback to workspace wide definitions. + matcher= Platform.getContentTypeManager(); + } + } + else { + matcher= Platform.getContentTypeManager(); + } + + IContentType[] cts = matcher.findContentTypesFor(filename); + switch (cts.length) { + case 0: + return null; + case 1: + return cts[0]; + } + + int maxPossiblePriority= scopeCtx == null ? 11 : 101; + int bestPriority= -1; + IContentType bestResult= null; + + for (int i = 0; i < cts.length; i++) { + IContentType candidate= cts[i]; + int priority= 0; + try { + if (scopeCtx != null) { + IContentTypeSettings settings= candidate.getSettings(scopeCtx); + if (isStrictlyAssociatedWith(settings, filename)) { + priority= 100; + } + } + if (priority == 0 && bestPriority < 100) { + if (isStrictlyAssociatedWith(candidate, filename)) { + priority= 10; + } + } + if (isPreferredContentType(candidate, preferCpp)) { + priority+= 1; + } + } + catch (CoreException e) { + // skip it + } + if (priority > bestPriority) { + if (priority == maxPossiblePriority) { + return candidate; + } + bestPriority= priority; + bestResult= candidate; + } + } + return bestResult; + } + + private static boolean isPreferredContentType(IContentType candidate, boolean preferCpp) { + while (candidate != null) { + String id= candidate.getId(); + if (CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(id) || + CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) { + return preferCpp; + } + + if (CCorePlugin.CONTENT_TYPE_CHEADER.equals(id) || + CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id)) { + return !preferCpp; + } + candidate= candidate.getBaseType(); + } + return false; + } + + private static boolean isStrictlyAssociatedWith(IContentTypeSettings settings, String filename) { + String[] namespecs= settings.getFileSpecs(IContentType.FILE_NAME_SPEC); + for (int i = 0; i < namespecs.length; i++) { + String name = namespecs[i]; + if (name.equals(filename)) { + return true; + } + } + // check the file extensions only + int dotPosition = filename.lastIndexOf('.'); + if (dotPosition >= 0 && dotPosition < filename.length()-1) { + String fileExtension= filename.substring(dotPosition + 1); + String[] extensions= settings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + for (int i = 0; i < extensions.length; i++) { + String ext = extensions[i]; + if (ext.equals(fileExtension)) { + return true; + } + } + } + return false; + } + + /** + * This method is copied from the resources plugin and figures out whether + * project specific settings are enabled or not. + * Implementation for {@link CCorePlugin#usesProjectSpecificContentTypes(IProject)}. + */ + public static boolean usesProjectSpecificContentTypes(IProject project) { + String projectName= project.getName(); + try { + // be careful looking up for our node so not to create any nodes as side effect + Preferences node = PROJECT_SCOPE; + //TODO once bug 90500 is fixed, should be simpler + // for now, take the long way + if (!node.nodeExists(projectName)) + return false; + node = node.node(projectName); + if (!node.nodeExists(Platform.PI_RUNTIME)) + return false; + node = node.node(Platform.PI_RUNTIME); + if (!node.nodeExists(CONTENT_TYPE_PREF_NODE)) + return false; + node = node.node(CONTENT_TYPE_PREF_NODE); + return node.getBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, false); + } catch (BackingStoreException e) { + // exception treated when retrieving the project preferences + } + return false; + } + + /** + * Implementation for {@link CCorePlugin#setUseProjectSpecificContentTypes(IProject, boolean)}. + */ + public static void setUseProjectSpecificContentTypes(IProject project, boolean val) { + ProjectScope projectScope = new ProjectScope(project); + Preferences contentTypePrefs = projectScope.getNode(FULLPATH_CONTENT_TYPE_PREF_NODE); + if (usesProjectSpecificContentTypes(project) != val) { + // enable project-specific settings for this project + contentTypePrefs.putBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, val); + try { + contentTypePrefs.flush(); + } catch (BackingStoreException e) { + // ignore ?? + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java index 2d18ccf9b4f..7aba75dd033 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CFileTypesPropertyPage.java @@ -7,20 +7,17 @@ * * Contributors: * TimeSys Corporation - Initial implementation + * Markus Schorn (Wind River Systems) **********************************************************************/ package org.eclipse.cdt.internal.ui.preferences; import java.util.ArrayList; -import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.internal.core.model.CModelManager; -import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentTypeManager; @@ -36,8 +33,13 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PropertyPage; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CoreModel; + +import org.eclipse.cdt.internal.core.model.CModelManager; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; /* * The preference page used for displaying/editing CDT file @@ -93,16 +95,6 @@ public class CFileTypesPropertyPage extends PropertyPage { } - private static final String CONTENT_TYPE_PREF_NODE = "content-types"; //$NON-NLS-1$ - private static final String FULLPATH_CONTENT_TYPE_PREF_NODE = Platform.PI_RUNTIME + IPath.SEPARATOR + CONTENT_TYPE_PREF_NODE; - private static final String PREF_LOCAL_CONTENT_TYPE_SETTINGS = "enabled"; //$NON-NLS-1$ -// private final static String PREF_FILE_EXTENSIONS = "file-extensions"; //$NON-NLS-1$ -// private final static String PREF_FILE_NAMES = "file-names"; //$NON-NLS-1$ -// private final static String PREF_SEPARATOR = ","; //$NON-NLS-1$ - private static final Preferences PROJECT_SCOPE = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE); - //private static final InstanceScope INSTANCE_SCOPE = new InstanceScope(); - - protected Button fUseWorkspace; protected Button fUseProject; protected FixCFileTypesPreferenceBlock fPrefsBlock; @@ -140,7 +132,7 @@ public class CFileTypesPropertyPage extends PropertyPage { }); final IProject project = getProject(); - boolean custom = isProjectSpecificContentType(project.getName()); + boolean custom = CCorePlugin.usesProjectSpecificContentTypes(project); fUseProject = new Button(radioPane, SWT.RADIO); fUseProject.setText(PreferencesMessages.getString("CFileTypesPropertyPage.useProjectSettings")); //$NON-NLS-1$ @@ -189,37 +181,11 @@ public class CFileTypesPropertyPage extends PropertyPage { * @see org.eclipse.jface.preference.IPreferencePage#performOk() */ public boolean performOk() { - - if (fUseProject.getSelection()) { - IProject project = getProject(); - ProjectScope projectScope = new ProjectScope(project); - Preferences contentTypePrefs = projectScope.getNode(FULLPATH_CONTENT_TYPE_PREF_NODE); - if (! isProjectSpecificContentType(project.getName())) { - // enable project-specific settings for this project - contentTypePrefs.putBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, true); - try { - contentTypePrefs.flush(); - } catch (BackingStoreException e) { - // ignore ?? - } - computeEvents(project); - } - fPrefsBlock.performOk(); - } else if (fUseWorkspace.getSelection()) { - IProject project = getProject(); - if (isProjectSpecificContentType(project.getName())) { - ProjectScope projectScope = new ProjectScope(project); - Preferences contentTypePrefs = projectScope.getNode(FULLPATH_CONTENT_TYPE_PREF_NODE); - // disable project-specific settings for this project - contentTypePrefs.putBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, false); - computeEvents(project); - try { - contentTypePrefs.flush(); - } catch (BackingStoreException e) { - // ignore ?? - } - computeEvents(project); - } + boolean useProjectContentTypes= fUseProject.getSelection(); + IProject project = getProject(); + if (CCorePlugin.usesProjectSpecificContentTypes(project) != useProjectContentTypes) { + CCorePlugin.setUseProjectSpecificContentTypes(project, useProjectContentTypes); + computeEvents(project); } return super.performOk(); } @@ -236,28 +202,6 @@ public class CFileTypesPropertyPage extends PropertyPage { return project; } - protected static boolean isProjectSpecificContentType(String projectName) { - try { - // be careful looking up for our node so not to create any nodes as side effect - Preferences node = PROJECT_SCOPE; - //TODO once bug 90500 is fixed, should be simpler - // for now, take the long way - if (!node.nodeExists(projectName)) - return false; - node = node.node(projectName); - if (!node.nodeExists(Platform.PI_RUNTIME)) - return false; - node = node.node(Platform.PI_RUNTIME); - if (!node.nodeExists(CONTENT_TYPE_PREF_NODE)) - return false; - node = node.node(CONTENT_TYPE_PREF_NODE); - return node.getBoolean(PREF_LOCAL_CONTENT_TYPE_SETTINGS, false); - } catch (BackingStoreException e) { - // exception treated when retrieving the project preferences - } - return false; - } - public IContentType[] getRegistedContentTypes() { String [] ids = CoreModel.getRegistedContentTypeIds(); IContentTypeManager manager = Platform.getContentTypeManager();