From d1e9395955c0a09aed70263eadb705b28a7030fb Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Sun, 8 Apr 2012 15:42:24 -0400 Subject: [PATCH] Methods for background serialization of language settings providers. --- .../internal/core/PluginResources.properties | 1 - .../providers/AbstractBuildCommandParser.java | 45 +------- .../providers/LanguageSettingsManager.java | 19 +++- .../LanguageSettingsSerializableProvider.java | 18 ++++ .../LanguageSettingsProvidersSerializer.java | 100 ++++++++++++++++++ .../model/SettingsModelMessages.properties | 3 + 6 files changed, 140 insertions(+), 46 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index 2c339a4f22e..20bc65cd8d1 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -171,7 +171,6 @@ ToolInfo.0=conversion failure ToolInfo.1=the tool is removed #Language settings providers messages -AbstractBuildCommandParser.SerializeJobName=Serialize CDT language settings entries AbstractBuiltinSpecsDetector.AddScannerDiscoveryMarkers=Adding Scanner Discovery markers AbstractBuiltinSpecsDetector.ClearingMarkers=Clearing markers for {0} AbstractBuiltinSpecsDetector.DiscoverBuiltInSettingsJobName=Discover compiler built-in language settings diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java index 0d9499e54c5..efaf4829f8c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractBuildCommandParser.java @@ -21,16 +21,6 @@ import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.errorparsers.RegexErrorParser; import org.eclipse.cdt.core.errorparsers.RegexErrorPattern; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; -import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; -import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; -import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; /** * Abstract class for providers parsing compiler option from build command when present in build output. @@ -142,43 +132,10 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting @Override public void shutdown() { - scheduleSerializingJob(currentCfgDescription); + serializeLanguageSettingsInBackground(currentCfgDescription); super.shutdown(); } - - private void scheduleSerializingJob(final ICConfigurationDescription cfgDescription) { - Job job = new Job(ManagedMakeMessages.getResourceString("AbstractBuildCommandParser.SerializeJobName")) { //$NON-NLS-1$ - @Override - protected IStatus run(IProgressMonitor monitor) { - return serializeLanguageSettings(cfgDescription); - } - @Override - public boolean belongsTo(Object family) { - return family == JOB_FAMILY_BUILD_COMMAND_PARSER; - } - }; - - ISchedulingRule rule = null; - if (currentProject != null) { - IFolder settingsFolder = currentProject.getFolder(".settings"); - if (!settingsFolder.exists()) { - try { - settingsFolder.create(true, true, null); - if (settingsFolder.isAccessible()) - rule = currentProject.getFile(".settings/language.settings.xml"); - } catch (CoreException e) { - ManagedBuilderCorePlugin.log(e); - } - } - } - if (rule == null) { - rule = ResourcesPlugin.getWorkspace().getRoot(); - } - job.setRule(rule); - job.schedule(); - } - /** * Trivial Error Parser which allows highlighting of output lines matching the patterns * of this parser. Intended for better troubleshooting experience. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java index 69a2bd1e4a7..0c8928d997f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsManager.java @@ -330,9 +330,26 @@ public class LanguageSettingsManager { /** * Save language settings providers of the workspace (global providers) to persistent storage. * - * @throws CoreException + * @throws CoreException if something goes wrong. */ public static void serializeLanguageSettingsWorkspace() throws CoreException { LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspace(); } + + /** + * Save language settings providers of a project to persistent storage in a background job. + * + * @param prjDescription - project description of the project. + */ + public static void serializeLanguageSettingsInBackground(ICProjectDescription prjDescription) { + LanguageSettingsProvidersSerializer.serializeLanguageSettingsInBackground(prjDescription); + } + + /** + * Save language settings providers of the workspace (global providers) to persistent storage + * in a background job. + */ + public static void serializeLanguageSettingsWorkspaceInBackground() { + LanguageSettingsProvidersSerializer.serializeLanguageSettingsWorkspaceInBackground(); + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializableProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializableProvider.java index afcb5429f1d..3e428e778c7 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializableProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/LanguageSettingsSerializableProvider.java @@ -258,6 +258,24 @@ public class LanguageSettingsSerializableProvider extends LanguageSettingsBasePr return status; } + /** + * Convenience method to persist language settings entries in background for the project or + * workspace as often-used operation. + * Note that configuration description is passed as an argument but the + * current implementation saves all configurations. + * + * @param cfgDescription - configuration description. + * If not {@code null}, all providers of the project are serialized. + * If {@code null}, global workspace providers are serialized. + */ + public void serializeLanguageSettingsInBackground(ICConfigurationDescription cfgDescription) { + if (cfgDescription != null) { + LanguageSettingsManager.serializeLanguageSettingsInBackground(cfgDescription.getProjectDescription()); + } else { + LanguageSettingsManager.serializeLanguageSettingsWorkspaceInBackground(); + } + } + /** * Load provider from XML provider element. * This is convenience method not intended to be overridden on purpose. diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java index 559b00d9fb6..a19ec1b3272 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java @@ -38,6 +38,7 @@ import org.eclipse.cdt.core.settings.model.ICStorageElement; import org.eclipse.cdt.internal.core.XmlUtil; import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings; import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo; +import org.eclipse.cdt.internal.core.settings.model.SettingsModelMessages; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -49,13 +50,16 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; 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.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ILock; +import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.osgi.util.NLS; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -72,11 +76,16 @@ public class LanguageSettingsProvidersSerializer { public static final String ELEM_PROVIDER = LanguageSettingsExtensionManager.ELEM_PROVIDER; public static final String ELEM_LANGUAGE_SCOPE = LanguageSettingsExtensionManager.ELEM_LANGUAGE_SCOPE; + private static final String JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT = "CDT_JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT"; //$NON-NLS-1$ + private static final String JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE = "CDT_JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE"; //$NON-NLS-1$ private static final String PREFERENCE_WORSPACE_PROVIDERS_SET = "language.settings.providers.workspace.prefs.toggle"; //$NON-NLS-1$ private static final String CPROJECT_STORAGE_MODULE = "org.eclipse.cdt.core.LanguageSettingsProviders"; //$NON-NLS-1$ private static final String STORAGE_WORKSPACE_LANGUAGE_SETTINGS = "language.settings.xml"; //$NON-NLS-1$ private static final String STORAGE_PROJECT_PATH = ".settings/language.settings.xml"; //$NON-NLS-1$ + private static final int PROGRESS_MONITOR_SCALE = 100; + private static final int TICKS_SERIALIZING = 1 * PROGRESS_MONITOR_SCALE; + private static final String ELEM_PLUGIN = "plugin"; //$NON-NLS-1$ private static final String ELEM_EXTENSION = "extension"; //$NON-NLS-1$ private static final String ATTR_EXTENSION_POINT = "point"; //$NON-NLS-1$ @@ -542,6 +551,46 @@ public class LanguageSettingsProvidersSerializer { } } + /** + * Save language settings providers of the workspace (global providers) to persistent storage + * in background. + */ + public static void serializeLanguageSettingsWorkspaceInBackground() { + Job[] jobs = Job.getJobManager().find(JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE); + for (Job job : jobs) { + if (job.getState() == Job.WAITING) { + // do not schedule if there is serializing job in queue already + return; + } + } + + Job job = new Job(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializeJobName")) { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + monitor.beginTask(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializingForWorkspace"), //$NON-NLS-1$ + TICKS_SERIALIZING); + serializeLanguageSettingsWorkspace(); + monitor.worked(TICKS_SERIALIZING); + return Status.OK_STATUS; + } catch (Throwable e) { + String msg = "Internal error running job of serializing language settings in workspace"; //$NON-NLS-1$ + return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg, e); + } finally { + monitor.done(); + } + } + @Override + public boolean belongsTo(Object family) { + return family == JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE; + } + }; + + job.setRule(null); + job.schedule(); + } + + /** * Load language settings for workspace. */ @@ -819,6 +868,57 @@ public class LanguageSettingsProvidersSerializer { } } + /** + * Save language settings providers of a project to persistent storage in background. + * + * @param prjDescription - project description of the project. + */ + public static void serializeLanguageSettingsInBackground(final ICProjectDescription prjDescription) { + Job job = new Job(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializeJobName")) { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + monitor.beginTask(NLS.bind(SettingsModelMessages.getString("LanguageSettingsProvidersSerializer.SerializingForProject"), //$NON-NLS-1$ + prjDescription.getName()), TICKS_SERIALIZING); + serializeLanguageSettings(prjDescription); + monitor.worked(TICKS_SERIALIZING); + return Status.OK_STATUS; + } catch (Throwable e) { + String msg = "Internal error running job of serializing language settings for project " + prjDescription.getName(); //$NON-NLS-1$ + return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, msg, e); + } finally { + monitor.done(); + } + } + @Override + public boolean belongsTo(Object family) { + return family == JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_PROJECT; + } + }; + + ISchedulingRule rule = null; + IProject project = prjDescription.getProject(); + if (project != null) { + IFile fileStorePrj = getStoreInProjectArea(project); + IContainer folder = fileStorePrj.getParent(); + if (folder instanceof IFolder && !folder.exists()) { + try { + ((IFolder) folder).create(true, true, null); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + if (folder.isAccessible()) { + rule = fileStorePrj; + } + } + if (rule == null) { + rule = ResourcesPlugin.getWorkspace().getRoot(); + } + job.setRule(rule); + job.schedule(); + } + /** * Load language settings to the project description from XML. * diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsModelMessages.properties b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsModelMessages.properties index 38f30f17a08..0c15a9714c4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsModelMessages.properties +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SettingsModelMessages.properties @@ -51,6 +51,9 @@ ExtensionContainerFactory.4=invalid setting provider class specified ExtensionContainerFactory.5=provider element not specified LanguageSettingsBaseProvider.CanBeConfiguredOnlyOnce=LanguageSettingsBaseProvider can be configured only once LanguageSettingsScannerInfoProvider.UnableToDetermineLanguage=Error getting ScannerInfo: Unable to determine language for resource {0} +LanguageSettingsProvidersSerializer.SerializeJobName=Serialize CDT language settings entries +LanguageSettingsProvidersSerializer.SerializingForProject="Serializing language settings for project {0} +LanguageSettingsProvidersSerializer.SerializingForWorkspace="Serializing language settings for global providers SettingsContext.0=no project associated with the context SettingsContext.1=can not accept the not-context project description