User Settings in Eclipse

Summary:
This document is a first cut at defining how user settings should be managed in Eclipse (see bug 36965). It first states how user settings are currently managed. Following this, the set of known scenarios involving user settings is presented. Finally, a possible direction for a solution is presented.

Last Modified: June 25, 2003

Table of Contents:

Introduction
Settings in Eclipse 2.X
Scenarios
Towards a Solution
What Next


Introduction

Currently in Eclipse, there are many settings that are persisted over workbench invocations. Some of these settings are specific to the workspace (e.g. may contain absolute paths to files, etc). while others are independent of the workspace location and are, hence, sharable. It should be possible to store user settings that are not specific to a workspace separate from the workspace, so that they can be used in other workspaces or by other users (see bug 36965).

Some of the settings in Eclipse are already sharable.User preferences set using the workspace preference pages can be exported and imported. Plugins can also provide there own mechanisms for sharing settings. Java projects use a .classpath file in a project to store project compilation information. The Debug component provides a mechanism for sharing launch configurations by allowing the location of a file containing the data for a launch configuration to be specified. There are other settings that could be shared (e.g. CVS repository list) but currently are not.

Settings in Eclipse 2.X

To better understand the problem, we will first look how settings are handled in Eclipse 2.x.

Types of Settings

The following table lists several different types of user settings that are found in Eclipse. With each setting type, the table also lists the mechanisms used to persist and share the settings.

setting persistence sharing
User Preferences IPreferenceStore Import/Export

Project Preferences
(classpath, compiler settings)

Plugin specific(XML) File in project (or none)
Dialog Settings
(layout, default field values)
IDialogSettings none
View Settings
(layout, menu state)
IMemento none

Workbench Settings
(perspectives, working sets)

IMemento none
Plugin Data
(repository lists, launch configuration)

Plugin specific (XML)

Plugin specific (or none)

Except for IMemento, the above mechanisms are really only appropriate for storing relatively simple values. For more sophisticated data, the plugin developers are forced to role their own persistence and sharing mechanism. For this reason, more complex plugin data is often stored directly in the workspace meta data area in a format chosen by the plugin and is not sharable. Another problem with this arrangement is that the persistence mechanisms are tied into where the mechanism is used and not with the types of settings (i.e. local or sharable) the mechanisms contain.

Grouping of Settings

As is indicated by the above table, settings are grouped by the mechanisms used to persist them. For example, user preferences can be shared because these preferences are stored using IPreferenceStore and a general import/export mechanism was built on on top of this. Other sharing mechanisms are plugin specific so any grouping can not surpass the plugin boundary. This is clearly not ideal as users may not wish to share all user preferences and they may want to share configurations for multiple plugins in a single operation.

Better grouping may be possible by considering the scope of a setting. Possible setting scopes are:

Perhaps the scope of a setting can be used to give the user control over which settings are shared.

How settings are shared

There are basically two styles of sharing: import/export or shared file.With import/export, the user explicitly chooses when to export their settings. At some future time, the user (or another user) explicitly chooses to import the settings, overriding, at least to some degree, any previous settings. This is currently how user preferences in Eclipse are shared. One advantage of this approach is that the user has control over when the export and import take place. Also, it is straightforward to add capabilities that would allow the user to limit which settings were included in the import/export operation (although this is not currently provided in Eclipse). The disadvantage of this approach is that the user must explicitly indicate when the export or import take place.

The shared file approach involves a file that contains the current settings. The contents of the file are updated as settings are changed in the workbench. Conversely, changes to the file made by other sources will be recognized by the workbench and result in changes in the corresponding settings.This style of sharing is used in the Java .classpath files. Changes in the classpath of a project made using JDT will change the contents of the .classpath file and changes in the .classpath from other sources, such as loading the .classpath file from a repository, will cause the classpath in the workbench to change accordingly. The advantage of this approach is that changes in settings can be easily propagated to other workspaces. The disadvantages are that it can be difficult to reconcile cases involving conflicting changes (i.e. the file is changed by two sources at roughly the same time) and all settings in the file reflect the state of the workspace even if the workspace changes are of a temporary nature.

Determining what is shared

For user preferences, the user can choose when to import or export the preferences but has no control over which preferences are shared. For plugin or tool specific data, the plugin/tool can decide if some of its data is sharable (.classpath, launch configurations). In these cases, the user decides what data is shared but the granularity of the sharing is determined by the plugin/tool (i.e. the user can share a launch configuration but cannot choose to share only some of the settings in the configuration).

A more ideal approach would be for the provider of the setting (plugin/tool) to indicate the nature of the setting (temporary, local or sharable) and, for sharable settings, provide a description that would allow a user to decide when and if the setting should be shared.Such an arrangement gives more control over how settings are managed. For instance, it would be possible to write a tool to arrange, share and possibly even modify settings in a configuration file that could then be used to configure Eclipse.

Scenarios

User settings means different things to different people. Also, there are some scenarios that, while not technically user settings scenarios, are related in some way. This section contains the list of known use cases that may be addressed in 3.0. However, inclusion in this list does not imply that the final solution will address an included scenario. The purpose here is to know what all the problems are so an informed decision can be made about which scenarios to address.

Scenario 1: Import/Export of settings from one workspace to another

A user may wish to persist certain settings so they can be used with other workspaces. To share settings from one workspace to another, the user performs an export operation in the source workspace which creates a file containing the settings. This file can then be imported into another workspace which changes the settings in the workspace to match those from the imported settings file.

This scenario, in it's simplest form, is what is supported by the Eclipse platform through it's preference Import/Export facility. However, this operation is really only adequate for importing preferences into a workspace that is in the same location as the workspace the preferences were exported from. The reason for this restriction is that there is no distinction between local and sharable preferences.

The following is what is needed for a more flexible preference sharing mechanism.

Scenario 2: Preconfiguration of setting defaults

An ISV creating a branded product using Eclipse may wish to customize some settings in their product. For instance, an ISV may wish to customize Java compiler settings and may even want to include CVS repository locations. A related scenario can be found in bug 37289.

This can be accomplished in Eclipse 2.x by placing a plugin_customization.ini in the primary feature plug-in. This file is used in the determination of the default values for preferences. The default value for a preference is determined by looking in the following places (in the order specified).

Tha is, if a value is assigned to a setting in the plugin_customization.ini file then it is the defalt, otherwise a value settingin the preferences.ini of the plugin is used if present. If no setting is there, the default specified in the code is used.

The contents of the *.ini files can be generated using the export facility described in Scenario 1 or crafted by hand as described in various plugin API.These settings must be internationalizable so each "*.ini" file needs a corresponding "*.properties" translation file.

Scenario 3: Application related settings

A plugin may wish to store data in an area that is accessible to and used by other workspaces associated with the same Eclipse install. Here is a particular scenario involving the Eclipse Update component:

Update had a number of problems saving its state (a directory called .config) in the workspace metadata. We need to take it out and make it independent from the workspaces (i.e. make it relative to the Eclipse application). A behavior that would be consistent with our needs would be:

  1. We try to save the directory in the eclipse install location first (under 'eclipse' directory). If we succeed, we keep it there.
  2. If the attempt is not successful (e.g. because the install location is read-only) OR if a shared mode is explicitly requested using the '-shared' command line argument, we use the following: in the user home location (the equivalent of System.getProperty("user.home")) we create a folder with some unique name (e.g. Eclipse Settings). Under the folder, we create a folder with the product unique ID (this ID is obtained from the .eclipseproduct marker file that every Eclipse product contains). We save our state in the unique product ID.

Although Update can implement this mechanism itself, it sounds like something that should be general for all the plug-ins that want to save application-specific state (as opposed to per-workspace).

Scenario 4: Sharing project settings

It is common for plugins to persist metadata for one or more projects in the workspace as files within the project. Although not necessarily user settings, this metadata can still be shared.

Some example of project metadata that is (or could be) persisted in the project directory are:

Any files that are stored within the project directory structure are already sharable. The .project and .classpath files are often shared with a project and the *.launch files can also be shared in this way.

There are several complications that arise from this type of sharing:

Currently, each plugin that wishes to store metadata in a project must implement their own mechanism from scratch. It would be helpful to provide a core mechanism for reading and writing the data (most likely in XML) and a common place to put the data files (such as a project metadata directory). Such a mechanism would also allow the user to see all the project settings that can be shared and enable them to decide which ones they would like to share and which ones they would not.

One of the interesting points about this scenario is that the sharing of settings occurs in a "live" manner in the sense that the settings in a workspace may change as a result to the updating of a settings file from the repository. For instance, if one user releases a change to the .classpath file of a Java project, the classpath project will change for other users when they load the change from the repository.

Another interesting point is that there are some project settings that override workspace settings. An example of this is Java compiler settings. Any setting made on a project overrides the setting for the workbench. This is related to Scenario 6.

Scenario 5: Sharing non-project based settings

The previous scenario describes how project settings can be shared through a repository. However, there are some settings that should be shared between workspaces that are not associated with a project. For example, a user may wish to have certain settings that are valid regardless of which workspace is used. Some examples: code templates, editor auto-closing options, file associations between filetypes and editors. Currently the user must pick a workspace as the 'master', make changes only to that one, export preferences, and import in all her other workspaces.

Some settings are common for everyone in an organization, so it is a waste of time to make everyone in the company set them. Also it is a source of tech support calls if they don't set them right. These settings change slowly over time, so the initial configuration scenario would not address it. Some examples: proxy settings, update sites urls, cvs ext connection method variables, team file content and ignored resources.

In both of the above cases, it seems desirable to be able to both share the settings and push new settings into the shard space. In the later case, it is probably also desirable to restrict who can change existing settings.

Scenario 6: Team Workgroups

The following scenario was posted to the platform-dev mailing list by Michael Lipp.

We have teams working on different projects. Team members may be in different teams, i.e. may work in different projects (not on a day-by-day basis, but within a month). Formalisms in the different projects are driven by customer requests. This means that we have customer specific templates, layout rules (yes we are not happy about this) and other differences between projects that must be reflected by the preferences settings within eclipse.

What we need before we can really use eclipse as main IDE is a way to specify base preferences for each project. It should be possible to specify for each preference if it may be overridden by a user. Preferences should automatically be switches when the user toggles between preferences. Team-wide preference settings should be files checked in to CVS.

Another way to view this is that each user has their preferred settings while each project has required settings. Hence, the presence of a setting on a project would override any setting made by the user.

Scenario 7: Associating settings with a mode of operation

Settings are often connected with the role of a user or the mode of development the user is in or some other state. It is cumbersome for the user to find every related preference and change it appropriately. For instance, a user may wish to change all relevant settings to gain the highest degree of accessibility and it would be beneficial if they could do this in one click instead of many. Also, a user may need to change modes often (as in Scenario 6).

There are a couple of ways settings could be associated with modes:

This scenario is complicated by the fact that each mode is not necessarily mutually exclusive. A user may need high accessibility while performing web development (which may be a mode with it's own settings). If this is supported, it is possible that settings from multiple active groups could overlap.

Another consideration is that some modes may have an analog value associated with them. For instance, a mode for performance may have a slider to pick the degree of performance the user wants. This analog value may have an effect on the values of the settings associated with that mode. It may be difficult to scale settings values in this way. A more reasonable solution may be to have discrete settings associated with different ranges of the slider.

Scenario 8: Policy for changing settings

Some settings may need to be fixed by policy and not changeable. In a large organization this is helpful to cut down on tech support problems, especially as less sophisticated users are exposed to Eclipse through RCP applications. But even for programmers, there are examples such as CVS ext connection method, C file tabs-vs-spaces setting, or CVS watch/edit setting.

Towards a Solution

This sections outlines the components of a potential solution for persisting and sharing user settings. It is purposefully brief as the main goal of this document is to ensure that all the scenarios are known before a solution is fully laid out. However, it is included as a starting point for discussing a solution.

Unified Settings Storage Mechanism

The goal of a unified settings storage mechanism in Eclipse would be to allow plugins to persist any or all of their state information in such a way as to allow the user (or the workbench) more control over where the settings are stored on disk and which settings are shared with others.

When persisting the setting, the plugin would specify the following:

The value of a setting could be simple data (as is supported by the current preferences mechanism in Eclipse today) or could be more complex data. A mechanisms similar to IMemento and IConfigurationElement could be combined with the preferences mechanism to simplify the process of persisting more complex data values. Complex data could be stored as a string in the preferences store (as is done today) or could be stored in a separate file, potentially as XML.

One interesting aspect of this solution is that it could be retro-fitted under most of the exiting mechanisms (IPreferenceStore, Preference, IDialogSettings and IMemento) in a fashion that is transparent to the plugins using these mechanisms.

Identification of sharable settings

Given a unified settings store, the task of identifying which settings are sharable can be accomplished using an XML descriptor file. It seems reasonable that such a description be done in the plugin.xml of a plugin but it could be done in a separate xml file if there is a compelling reason.

A setting would have the following information associated with it.

The label and description would only be required for sharable settings to allow settings management UI to display information about the settings to the user to aid in the export/import of settings and the creation of settings groups.

Grouping settings into modes

There are two aspects of a settings group: defining the group and adding settings to the group. These two aspects should be defined separately in order to support the types of mode creation described in Scenario 7. This is important given that the creator of the group cannot be expected to anticipate all plugins that may have settings that are relevant to the mode the group represents.

Change Notification

A plugin needs to be notified when any of its settings are changed as a result of a settings import or a settings file update from the repository. The plugin would respond to the change by obtaining the new value of the setting from the setting store and adjusting its internal state accordingly.

Determining the value of a setting

In this new world of a unified settings store, there are several places where settings could come from:

The above list is in order of more general to more specific and the store could be traversed in that order to determine the settings to be used in a particular context. For example, a value assigned to a setting in the install is overridden by a value assigned to that same setting in the workspace. However, the setting value determination is complicated by the allowance for overlapping modes. In this case, the user may need to decide which mode has the highest priority.

Managing Settings

The use of a unified setting store makes centralized management of settings in Eclipse possible. This will make it possible to control and configure where and how metadata for projects and plugins is stored. Furthermore, this configuration can be done independently of the plugins that own the settings.

The user will need tools to manage sharable settings. These tools may include:

There may be other useful tools as well.This area will be investigated in more depth as work proceeds in this area.

It may be interesting to allows others to supply implementations for the stores in various scopes. In some enterprise scenarios for example, application preferences would be stored on a central server/database. This may also help in controling sharing in the sense that the store for a particular scope of setting can dictate whether or not the settings in that scope are shared.

Security

The settings information that is stored on disk or shared between users will not be encoded for security rreasons in any way. It will be up to the plugins providing the settings to encode them if the information being saved is of a sensitive nature.

Java 1.4 Preferences API and OSGI Preferences Service

It may be possible to make use of APIs that already exist in this area, such as the Java 1.4 Preferences API or the OSGI Preferences Service. This will definitely be investigated but will not limit what we do (i.e. if the APIs are not adequate for the requirements then they will not be used).

It is interesting to note that the Java 1.4 Preferences API separates preferences into user and system preferences. The system preferences are similar to what is described in Scenario 3 while the user preferences are similar to what is described in Scenario 5. However, absent from the API is the concept of project preferences (Scenario 4) and other possible scopes mentioned in this document.

Another factor to consider is that, with the Java API, it is up to the programmer to choose where a preference lives (system vs. user). In some cases, this makes sense but may not always be desirable.

Finally, the only method of sharing provided with the Java 1.4 preferences is import/export as described in Scenario 1. That is not to say that addition methods could not be defined.

What Next

This document captures the known use cases for user settings persistence and sharing and outlines a promising solution. The scenarios will be adjusted based on feedback from the community and the solution description will be further modified and refined based on this feedback.