blob: d8ea1175d79914e37911506b5777dbc3542b0eaf [file] [log] [blame]
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Eclipse Project">
<title>User Settings: Proposed Solution</title>
<link rel="stylesheet" href="http://dev.eclipse.org/default_style.css" type="text/css">
</head>
<h1>User Settings in Eclipse: Proposed Solution</h1>
<blockquote>
<p><strong>Summary</strong>:<br>
The document &quot;<a href="settings.html">User Settings In Eclipse</a>&quot;
presented the known scenarios in Eclipse involving the sharing of user settings
along with some thoughts on a possible solution. This document outlines a
more in-depth proposed solution for meeting the requirements of these scenarios.</p>
<p>Last Modified: July 18, 2003</p>
<p><strong>Table of Contents:</strong></p>
<p><a href="#intro">Introduction</a><br>
<a href="#SettingsAPI">Settings Node API</a><br>
<a href="#RootsAndTypes">Settings Roots and Setting Types</a><br>
<a href="#SettingsModes">Settings Modes</a><br>
<a href="#DefaultDetermination">Default Value Determination</a><br>
<a href="#ConfigureSettings">Settings Related Configuration Information</a><br>
<a href="#BackwardsCompatibility">Backwards Compatibility</a><br>
<a href="#Requirements">Relating to the Requirements</a><br>
<a href="#TimeTable">Time Table</a></p>
</blockquote>
<hr>
<h2><a name="intro">Introduction</a></h2>
<p>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 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=36965">36965</a>).
</p>
<p>The document &quot;<a href="settings.html">User Settings In Eclipse</a>&quot;
describes the known scenarios involving user settings and presents some ideas
on a possible solution. This document contains an in-depth description of a
possible solution that was designed based on the scenarios presented in the initial document.</p>
<p>The proposed solution that is outlined in this document consists of the following
pieces:</p>
<ul>
<li>A Settings node/hierarchy API that is similar to the Java 1.4 Preferences
API with defaults determination similar to the Preferences handling in Eclipse
2.x.</li>
<li>An extension point for registering SettingsRoots which act as a scope for
settings. There are two types of scopes identified in the requirements: Platform
(where each plugin stores it's general settings) and each Project in the workspace
(where plugins can store project specific settings).</li>
<li>API on a Settings node which allows for the assignment of a setting type
to a setting. The SettingsRoot will use the setting types to determine how
or where particular settings are persisted.</li>
<li>API on SettingsRoot for using an object (i.e. non-String) as a key to a
Settings node in order to allow settings to be associated with particular
objects.</li>
<li>A strategy for determining settings defaults for the Platform settings that
is similar to that currently used by Eclipse. Possible strategies for determining
defaults for Project settings will also be discussed.</li>
<li>The specification of settings modes and a description of how active modes
affect the Platform settings.</li>
<li>A discussion of possible configuration mechanisms related to settings.</li>
<li>A discussion of backwards compatibility with existing settings mechanisms
in Eclipse</li>
</ul>
<p>The above are described in more detail in the sections that follow.</p>
<h2><a name="SettingsAPI"></a>Settings Node API</h2>
<p>The core component of this proposal is the Settings class.
The API for this class is derived from the existing settings classes
in Eclipse and Java 1.4 Preferences class. Therefore, these classes
are summarized before the Settings class is presented.</p>
<h3>Settings APIs in Eclipse 2.x</h3>
<p>Currently Eclipse has several mechanisms for persisting and potentially sharing
settings. These include:</p>
<ul>
<li>org.eclipse.core.runtime.Preferences</li>
<li>org.eclipse.jface.preferences.IPreferenceStore</li>
<li>org.eclipse.jface.dialogs.IDialogSettings</li>
<li>org.eclipse.ui.IMemento</li>
</ul>
<p>Although each of these APIs has unique aspects, there is a large degree of
commonality. The following lists describes the features of these APIs.</p>
<ul>
<li>storage and persistence of keyed properties (String, boolean, int, etc.):
All</li>
<li>import/export: Preferences, IPreferenceStore</li>
<li>hierarchy of nodes: IMemento, IDialogSettings
<ul>
<li>list of nodes: IMemento</li>
<li>array of strings: IDialogSettings</li>
</ul>
</li>
<li>change notification: Preferences, IPreferenceStore</li>
<li>defaults: Preferences, IPreferenceStore</li>
</ul>
<p>For backwards compatibility reasons, any solution that is proposed for 3.0
must be compatible with the existing mechanisms. In other words, the existing
mechanisms must remain but could be reimplemented to make use of new API. It
is a requirement that this be possible for Preferences and IPreferenceStore
and may be desirable for IMemento and IDialogSettings. It is also desirable
that any new API meet the requirements outlined in the known <a href="settings.html#scenarios">scenarios</a>.</p>
<h3>Java 1.4 Preferences API</h3>
<p>A Preferences API has also been defined as part of Java 1.4. This API has many
of the same aspects of the current settings APIs in Eclipse.</p>
<ul>
<li>storage and persistence of keyed properties</li>
<li>import/export</li>
<li>hierarchy of nodes</li>
<li>change notification</li>
</ul>
<p>Furthermore, the other aspects (lists of nodes, arrays of Strings and defaults)
could be built on top of the above mentioned features.</p>
<p>However, there are two aspects of the Java 1.4 API that may not be suitable
for use in Eclipse. First of all, there are two setting types hard coded into
the API: user and system. The known scenarios in Eclipse have, at least, the
additional types workspace and project and potentially others (organization).
Also, the Java 1.4 Preferences provide a mechanism for associating preferences
with a package by mapping the package name to a path in a preference tree. It
is not clear that this is how preferences will be organized in Eclipse. Another
complication is that Eclipse currently supports being run on 1.3.1 VMs. Until
1.4 becomes the lowest supported VM, we cannot depend on 1.4 API. </p>
<p>Another aspect of the Java 1.4 Preferences API is that it does not provide
the underlying implementation for the in-memory or serialized representations
of the preferences. Given that the Java 1.4 API is mostly in-line with what
is needed in Eclipse, every effort will be taken to ensure that the API that
will be proposed for 3.0 will be compatible with the Java 1.4 API in the sense
that, if and when Eclipse moves to Java 1.4, the Java 1.4 Preferences could
be made a superclass of the Eclipse preference class (or be supported in some
other form).</p>
<h4>Deviations from previous APIs</h4>
<p>The Settings API being proposed for 3.0 will not differ greatly from the org.eclipse.core.runtime.Preferences
with the addition of the ability to nest preference nodes hierarchically as
in the Java 1.4 Preferences API. The main difference will be in how settings
are persisted and shared. This will be controlled by the following factors:</p>
<ul>
<li>Settings Root: A settings root is a root entity or object to which the settings
apply. The Platform and a project are two examples of setting roots in Eclipse.</li>
<li>Setting Type: The type of a setting provides a hint about how the setting
should be persisted or shared. Example settings types are private (unsharable),
local (sharable but not shared), user, system, etc.</li>
</ul>
<h3>Settings Class</h3>
<p>To avoid confusion with the existing Eclipse and Java 1.4 <code>Preference</code>
classes, a <code>Settings</code> class will be defined in Eclipse 3.0. The new
class will have many similarities to both of the mentioned preferences classes.
The goal is define a class that can be used to provide the implementation for
both of the existing preferences APIs.</p>
<p>This section outlines the methods that will be part of the <code>Settings</code>
class API.</p>
<h4>Getting and setting property values</h4>
<p>The <code>Settings</code> class will define methods for the storage and retrieval
of primitive typed properties.</p>
<blockquote>
<pre>public String getString(String name);
public boolean getBoolean(String name);
...//other primitive type gets
public void putString(String name, String value);
public void putBoolean(String name, boolean value);
...//other primitive type puts
public String[] propertyNames();
public boolean remove(String name);
public boolean contains(String name);</pre>
</blockquote>
<p>As in the existing <code>org.eclipse.core.runtime.Preferences</code> class,
the get methods of <code>Settings</code> will return appropriate defaults for
the primitive types if the property does not exist. The next section describes
how explicit defaults can be provided.</p>
<h4>Specifying default property values</h4>
<p>Explicit defaults can be provided through specifying another <code>Settings</code>
node that will provide the defaults.</p>
<blockquote>
<pre>
public Settings getDefaultSettings();
public void setDefaultSettings(Settings settings);</pre>
</blockquote>
<p>If no default settings is provided, the &quot;default&quot; default (as described
in <code>org.eclipse.core.runtime.Preferences</code>) will be used. The following
helper methods will be added to the <code>Settings</code> class to access defaults
so that users of the API will not have to differentiate between when a default
<code>Settings</code> has been assigned using <code>setDefaultSettings()</code>.</p>
<blockquote>
<pre>
public String[] defaultPropertyNames();
public boolean isDefault(String name);
public String getDefaultString(String name);
public boolean getDefaultBoolean(String name);
...//other primitive type get defaults</pre>
</blockquote>
<p>The <code>propertyNames()</code> method mentioned previously will only return
those properties that have had values assigned to them in the settings node.
An additional <code>keys()</code> method will provide the set of property names
for which values exist in the settings itself or it's default settings.</p>
<blockquote>
<pre>public String[] keys();</pre>
</blockquote>
<h4>Settings node hierarchy</h4>
<p>As in the Java 1.4 preferences API, settings nodes can be arranged hierarchically.
Each node is identified by a path from a parent node. The path can be provided
as either a String or an IPath.</p>
<blockquote>
<pre>public boolean nodeExists(IPath path);
public boolean nodeExists(String path);
public Settings getNode(IPath path);
public Settings getNode(String path);
public String[] childNames();
public String getName();
public Settings getParent();
public IPath getFullPath();
public void removeNode();
public SettingsRoot getRoot();
</pre>
</blockquote>
<h4>Change events</h4>
<p>There will be two types of events: property changes and child changes. Property
change events are fired when the value assigned to a property changes. Child
change events are triggered when child nodes are added or removed.</p>
<blockquote>
<pre>public void addPropertyChangeListener(IPropertyChangeListener listener);
public void removePropertyChangeListener(IPropertyChangeListener listener);
public void addChildChangeListener(IChildChangeListener listener);
public void removeChildChangeListener(IChildChangeListener listener);</pre>
</blockquote>
<h4>Settings persistence</h4>
<p>Methods will be supported to load and save settings.</p>
<blockquote>
<pre>public void save() throws CoreException;
public void load() throws CoreException;
</pre>
</blockquote>
<p>Additionally, a method may be added to synchronize the local copy of the settings
with what is serialized. This will be required for situations when multiple
running instances of Eclipse share an underlying settings store (such as user
settings).</p>
<blockquote>
<pre>public void syncWithStore() throws CoreException;</pre>
</blockquote>
<p>Although these methods appear on a Settings node, the task of serializing the
settings is delegated to the <a href="#SettingsRoot"><code>SettingsRoot</code></a>
and <a href="#SettingsStore"><code>SettingsStore</code></a>.</p>
<h4>Import/Export</h4>
<p>Import and export of settings will be supported. It should be possible to build
an import/export wizard that utilizes setting types to help the user decide
what settings to include. Such a UI would be added by a mechanism to associate
descriptions with each setting key.</p>
<h2><a name="RootsAndTypes"></a>Settings Roots and Setting Types</h2>
<p>The concept of SettingsRoots is proposed as a way to support the association
of settings with different settings scopes. One such scope would be the Eclipse
platform itself while another would be projects within an Eclipse workspace.</p>
<p>Within each scope, settings may be sharable in different ways or may be local
to a specific workspace. Thus, each property in a Settings node can have a settings
type associated with it that indicated whether the settings can be shared and,
if it is sharable, how it is shared. A SettingsStore is associated with a settings
root and is responsible for mapping settings types into the locations where
each setting type is persisted.</p>
<h3><a name="SettingsRoot"></a>Settings Roots</h3>
<p>The platform settings (i.e. those currently associated with plugins) will be stored in
the <code>PlatformSettingsRoot</code> defined by the org.eclipse.core.runtime plugin.
Other settings
roots, such as the <code>ProjectSettingsRoot</code> will be contributable through
a plugin's manifest file (<em>plugin.xml</em>). An extension point will be added
to the <em>org.eclipse.core.runtime</em> package for defining a settings scope.</p>
<blockquote>
<pre>&lt;extension-point name=&quot;Settings Root&quot; id=&quot;settingsRoot&quot;/&gt;</pre>
</blockquote>
<p>A settings root will be defined by contributing to this extension point.</p>
<blockquote>
<pre>&lt;extension
point=&quot;org.eclipse.core.runtime.settingsRoot&quot;
id=&quot;pluginRoot&quot; name=&quot;Settings Root for MyObject&quot;&gt;<br> &lt;settingsRoot<br> objectClass=&quot;org.eclipse.core.runtime.MyObject&quot;<br> rootClass=&quot;org.eclipse.core.runtime.MyObjectSettingsRoot&quot;/&gt;<br> &lt;/extension&gt;</pre>
</blockquote>
<p>The <code>objectClass</code> defines the class to which the settings root is
associated while the <code>rootClass</code> provides access to the settings
for each instance of the <code>objectClass</code>. The <code>MyObjectSettingsRoot</code>
class needs to extend the <code>SettingsRoot</code> class which is a subclass
of <code>Settings</code>.</p>
<blockquote>
<pre>public class MyObjectSettingsRoot extends SettingsRoot {<br> ...
}</pre>
</blockquote>
<p>The following API on the <code>Settings</code> class provides access to the
settings for a particular settings root.</p>
<blockquote>
<pre>MyObject o = ...;
Settings settings = Settings.getSettings(o);</pre>
</blockquote>
<p>The <code>Settings.getSettings(Object)</code> method uses the settings root
contributed to the <code>settingsRoot</code> extension point for the given object's
class. If there is no settings root defined for the object's class, then the
superclasses of the object's class will be used in order to search for a settings
root. If none is found for any superclasses, <code>null</code> is returned.
Although it would be technically possible to use interfaces as well, this can
lead to non-deterministic behavior in the case where an object
extends a class and implements an interface where both are settings roots.</p>
<h4>Platform Settings Root</h4>
<p>The <code>PlatformSettingsRoot</code> class needs to extend the <code>SettingsRoot</code>
class which is a subclass of <code>Settings</code>.</p>
<blockquote>
<pre>public class PlatformSettingsRoot extends SettingsRoot {<br> ...
}</pre>
</blockquote>
<p>However, the <code>PlatformSettingsRoot</code> is not contributed in XML but
is instead, provided by the <em>org.eclipse.core.runtime</em> plugin. An API
method (<code>getPluginSettings()</code>) will be added to the <code>Plugin</code>
class for implementing the node in the <code>PlatformSettingsTree</code> associated
with a given plugin. In addition to this API, the <code>Plugin</code> class
will implement the <a href="#ISettingsLocator"><code>ISettingsLocator</code></a>
interface.</p>
<h4>Project Settings Root</h4>
<p>The <code>ProjectSettingsRoot</code> will be contributed by the <em>org.eclipse.core.resources</em>
plugin. Given that settings roots are associated with classes and not interfaces,
the <code>objectClass</code> for the settings root for projects will need to
be the class <code>org.eclipse.core.internal.resources.Project</code> instead
of the interface <code>org.eclipse.core.resources.IProject</code>. The implication
of this is that the following extension contribution must be made by the <code>org.eclipse.core.resources</code>
plugin.</p>
<blockquote>
<pre> &lt;extension <br> point=&quot;org.eclipse.core.runtime.settingsRoot&quot; <br> id=&quot;projectRoot&quot; name=&quot;Plugin Settings Root&quot;&gt;<br> &lt;settingsRoot<br> objectClass=&quot;org.eclipse.core.internal.resources.Project&quot;<br> rootClass=&quot;org.eclipse.core.runtime.ProjectSettingsRoot&quot;/&gt;<br> &lt;/extension&gt;</pre>
</blockquote>
<p>An additional requirement for the project settings root is that the settings
(and any data stored on disk) for a project need to be removed and when the
project is deleted. The implementation of a <code>ProjectSettingsRoot</code>
will be responsible for listening for project removals and purging any persisted
settings for the project.</p>
<h3><a name="SettingsStore"></a>Settings Store</h3>
<p>Associated with each <code>SettingsRoot</code> is a strategy for mapping setting
types to a storage location. This mapping is handled by a separate <code>SettingsStore</code>
object. A settings store defines which settings types are supported and handles
the serialization of the settings in its associated <code>SettingsRoot</code>.</p>
<h4>Platform Settings Store</h4>
<p>Setting types for the platform are:</p>
<ul>
<li><strong>private</strong>: private to the workspace.</li>
<li><strong>local</strong>: local to the workspace but sharable</li>
<li><strong>user</strong>: to be shared between all workspaces of the current
user.</li>
<li><strong>system</strong>: to be shared between all workspaces for all users
of this CPU.</li>
</ul>
<p>Each setting type will be stored in a separate location. The private and local
settings will be stored in the workspace metadata area in the following manner.</p>
<ul>
<li>workspace/.metadata</li>
<ul>
<li>.plugins</li>
<ul>
<li>pluginX</li>
<ul>
<li>private_settings.ini</li>
<li>local_settings.ini</li>
</ul>
<li>pluginY</li>
<ul>
<li>...</li>
</ul>
</ul>
</ul>
</ul>
<p>The local and private settings are stored separately to allow local settings to be easily
differentiated from private settings without special tools that query the setting types defined in Eclipse.</p>
<p>The user and system
settings will be stored in location where the settings can be appropriately
shared. For instance, user settings will be store in a location relative to
the <em>user.home</em> java property. </p>
<ul>
<li><em>user.home</em>/<em>.applicationId</em></li>
<ul>
<li>.plugins</li>
<ul>
<li>pluginX</li>
<ul>
<li>settings.ini</li>
</ul>
<li>pluginY</li>
<ul>
<li>...</li>
</ul>
</ul>
</ul>
</ul>
<p>The applicationId will be an identifier that differentiates applications build
using Eclipse. See the section of configuring Eclipse for more details.</p>
<p>The concept of a system setting has been included because it is part of the Java 1.4 API and
because we have at least one requirement that mentions such an area. Where this area would live is still to be determined.</p>
<h4>Project Settings Store</h4>
<p>Project settings can be private, local or <strong>shared</strong>. Shared project
settings will be persisted within the project. Given this, the project settings
store will have the following characteristics:</p>
<ul>
<li>The settings will be written to disk whenever they change. This should not
have a large performance impact given that the number of project settings
should be relatively small.</li>
<li>Changes that occur to shared project settings will be loaded automatically.
This is made possible by the fact that the shared portion will be contained
in one or more IFile instance in the project and deltas can be used to detect
the changes.</li>
</ul>
<p>The private and local settings for projects will be stored in the workspace metadata
area in the following structure.</p>
<ul>
<li>workspace/.metadata</li>
<ul>
<li>.projects</li>
<ul>
<li>projectA</li>
<ul>
<li>pluginX</li>
<ul>
<li>private_settings.ini</li>
<li>local_settings.ini</li>
</ul>
<li>pluginY</li>
<ul>
<li>...</li>
</ul>
</ul>
<li>projectB</li>
<ul>
<li>...</li>
</ul>
</ul>
</ul>
</ul>
<p>The shared settings will be stored in the project in the following structure.</p>
<ul>
<li>projectA</li>
<ul>
<li>.data</li>
<ul>
<li>pluginX</li>
<ul>
<li>settings.ini</li>
</ul>
<li>pluginY</li>
<ul>
<li>...</li>
</ul>
</ul>
</ul>
</ul>
<h3>Settings Types</h3>
<p>As mentioned previously, a setting may have a type associated with it that
will determine where the setting is persisted and how it is shared. This section
is an initial attempt at describing how the setting type for settings could
be determined.</p>
<h4>Platform Setting Type Determination</h4>
<p>The following order will be used when determining the type of a setting in
the platform settings.</p>
<ol>
<li>chosen by user (local or user)</li>
<li>determined by setting location</li>
<li>assigned by main feature (local or user)</li>
<li>assigned by plugin (private, system, unassigned)</li>
</ol>
<p>A plugin can assign, either programmatically or in a configuration file, the
settings types of private or system to one or more of its settings. Settings
that are marked as private or system by a plugin cannot have their setting type
changed. However, settings that are not assigned a type by the plugin can be
assigned a type by another source. These settings will use the default setting
type which will be user.</p>
<p>Settings that were not assigned a type by the plugin can be assigned a type
in the main feature. The main feature can also mark settings as private. This
will not be done often but provides a way to correct oversights by the plugin
developer (i.e. if the setting causes problems if it is shared).</p>
<p>If a setting was marked as local in the main feature but exists in the user
setting location, that setting will be considered a user setting. The reason
for this is that the user may have changed the setting type to user in another
workspace and would expect that setting to be picked up by other workspaces.
The setting type change will be persisted in the workspace where the user made
the setting type change.</p>
<h4>Project Setting Type Determination</h4>
<p>The following order will be used when determining the type of a setting in
a project's settings.</p>
<ol>
<li>chosen by user (local or user)</li>
<li>determined by setting location</li>
<li>assigned by plugin (private, system, unassigned)</li>
</ol>
<p>This is basically the same ordering as the platform settings with the exclusion
of the main feature. Unassigned settings will default to local and must be explicitly
shared. </p>
<h4> <a name="SettingType"></a>Settings node API</h4>
<p>API will exist on a Settings node for associating a type with a setting.</p>
<blockquote>
<pre>public String getSettingType(String name);
public void setSettingType(String name, String settingType);
public String[] propertyNames(String settingType);</pre>
</blockquote>
<p>Setting types need not be assigned to all properties. Properties that do not
have an assigned type will have the default type assigned to them. The setting
type is used by the <a href="#SettingsRoot"><code>SettingsRoot</code></a> and
<a href="#SettingsStore"><code>SettingsStore</code></a> to determine how to
persist the setting.</p>
<h3><a name="ISettingsLocator"></a>Accessing Settings for an Arbitrary Object</h3>
<p>To ease the association of settings with a particular object, the settings
API will provide an <code>ISettingsLocator</code> interface which will support
the following statements for accessing settings.</p>
<blockquote>
<pre>Settings rootSettings = Settings.getSettingsRoot(myPlugin)
Settings repoSettings = rootSettings.getSettings(myRepository);</pre>
</blockquote>
<p>The provided object need not implement the <code>ISettingsLocator</code> interface
(but can). The platforms <code>IAdaptable</code> mechanism will also be used.
In other words, the provided object must implement <code>IAdaptable</code> and
must adapt to the interface given below. If either of these is not the case,
<code>null</code> will be returned.</p>
<blockquote>
<pre>public interface ISettingsLocator {
public IPath getSettingsPath(Object object);
}</pre>
</blockquote>
<p>This interface is designed to allow a single instance to provide the paths
for multiple objects. The returned path will be used to get the Settings node
for the object. The path returned is always relative to a settings root and
the <code>Settings#getSettings(Object)</code> method will always use the root
to find the settings for the object.</p>
<h2><a name="SettingsModes"></a>Settings Modes</h2>
<p>One of the requirements identified in the original <a href="settings.html">settings
document</a> involved the ability to enable and disable modes that have multiple
settings associated with them. To accomplish this, the user will be able to
activate one or more modes, which are simply settings nodes themselves. </p>
<h3>Activating Modes</h3>
<p>There will be UI to activate modes. This area will be investigated in more
detail during prototyping.</p>
<h3>Combining Active Mode Settings</h3>
<p>The following diagram illustrates how the active mode settings will be determined
from the active modes.</p>
<center>
<p><img src="images/modes.gif" width="241" height="277"></p>
</center>
<p>Given that multiple modes can be active at a given time, an ordering is required
to determine which value settings have priority. It is planned that the ordering
of active modes will be configurable by the user. Each mode will be configured
to obtain its defaults from the next lower priority active mode. The Active
Mode Settings node that is used to determine the <a href="#PlatformSettingsDiagram">platform
settings</a> will obtain its values from the modes.</p>
<p>One special consideration to be made with this arrangement is that, when modes
are activated, deactivated or rearranged, value in the Active Mode Settings
will change and must result in change notification events. There may be salability
issues to consider given the number of settings that could potentially change
value at the same time.</p>
<h3>Mode Specification</h3>
<p>The following are the methods being considered for mode specification.</p>
<ul>
<li>A plugin may contribute values for its own settings to one or more modes.</li>
<li>The main feature of an Eclipse product can contribute mode settings for any plugin.</li>
<li>Import one or more settings files as a mode.</li>
</ul>
<h4>Modes in a Plugin</h4>
<p>The existence of modes within a plugin will be signaled by contributing to
an extension point in the plugin.xml file that indicates that the platform should
look in the .modes directory for mode specifications.</p>
<ul>
<li>pluginX</li>
<ul>
<li>plugin.xml</li>
<li>.modes</li>
<ul>
<li>modes.xml</li>
<li>mode1.ini</li>
<li>mode2.ini</li>
</ul>
</ul>
</ul>
<p> The modes.xml file contains
a description of the modes defined by this plugin. The settings for each mode are contained in
a separate file.
A plugin can also contribute to the modes defined by other plugins but can only add
settings that apply to itself.</p>
<h4>Modes in a Main Feature</h4>
<p>Mode specification is a feature is similar to specifying them in a plugin except that
the mode is a directory containing specifications for multiple plugins.</p>
<ul>
<li>main feature</li>
<ul>
<li>plugin.xml</li>
<li>.modes</li>
<ul>
<li>mode1</li>
<ul>
<li>pluginX</li>
<ul>
<li>settings.ini</li>
</ul>
<li>plugin Y</li>
<ul>
<li>settings.ini</li>
</ul>
</ul>
<li>mode2</li>
<ul>
<li>...</li>
</ul>
</ul>
</ul>
</ul>
<p>The settings made in a feature would take precedence over those contained in the plugins.</p>
<h4>Importing Settings as a Mode</h4>
<p>It would also be beneficial for the user to have the ability to import settings
and assign them to a mode.</p>
<h2><a name="DefaultDetermination"></a>Default Value Determination</h2>
<p>In this section, the strategies for determining the defaults for the platform
settings and project settings is presented.</p>
<h3>Platform Settings</h3>
<p>Currently, Eclipse determines the defaults for platform settings by obtaining
settings from the following sources in the given priority order:</p>
<ol>
<li>file specified on the Eclipse command line </li>
<li><em>plugin_customization.ini</em> in the primary feature plug-in </li>
<li><em>preferences.ini</em> file in a plugin </li>
<li>settings made programmatically by a plugin</li>
</ol>
<p>That is, if a value is assigned to a setting in the <em>plugin_customization.ini</em>
file then it is the default (unless it appears in the <em>ini</em> file given
on the command line), otherwise a value set in the <em>preferences.ini</em>
of the plugin is used if present. If no setting is there, the default specified
in the code is used.</p>
<p>This strategy will remain largely unchanged. The same sources will be loaded
into a <code>PlatformDefaultSettingsRoot</code>. This settings node will be
used as the default settings node for the <code>PlatformSettingsRoot</code>
which will result in the same preferences determination strategy that currently
exists in Eclipse. However, <a href="#SettingsModes">settings modes</a> will
also play a role in determining the default values of platform settings, resulting
in the following default determination ordering.</p>
<p><center>
<a name="PlatformSettingsDiagram"></a><img src="images/settings1.gif" width="205" height="229">
</center></p>
<h3>Project Settings</h3>
<p>Each project will have a <code>ProjectSettingsRoot</code> associated with it.
Plugins will use the <a href="#ISettingsLocator"><code>ISettingsLocator</code></a>
facility to access the plugin's settings node associated with a project. The
code to access the project settings for a plugin would be:</p>
<blockquote>
<pre>IProject aProject = ...;
Plugin aPlugin = ...;
SettingsRoot projectSettings = Settings.getSettingsRoot(aProject);
Settings pluginProjectSettings = projectSettings.getSettings(aPlugin);</pre>
</blockquote>
<p>It will be up to the plugin provider to determine how defaults for their project
settings are determined. However, a special settings node will be created which
supports the specification of settings (inherited from Settings) as well as
the specification of a filter which will allow settings defaults to be obtained
from the platform settings for the plugin.</p>
<p><center>
<img src="images/settings2.gif" width="253" height="229">
</center>
</p><br>
<p>The middle settings node in the above diagram can have defaults set directly.
Also, it can be provided with a list of property keys for which the defaults
should be passed through from the plugin settings. The filter is provided to
avoid getting change events for all platform settings when only a small fraction
may apply to projects.</p>
<h2><a name="ConfigureSettings"></a>Settings Related Configuration Information</h2>
<p>It would be beneficial to have an Eclipse configuration file in the main feature
that allows the specification of the following information.</p>
<ul>
<li>an application ID used to allow different applications built using Eclipse
to differentiate their user and system settings.</li>
<li>user and system settings locations either relative to known user and system
locations(java user.home property) or as absolute paths (may not be necessary
given an application ID). </li>
<li>platform defaults settings location(s) which could be specified as file
paths or URLs.</li>
<li>values and types for particular settings</li>
</ul>
<p>&nbsp;</p>
<h2><a name="BackwardsCompatibility"></a>Backwards Compatibility</h2>
<p>In order to support backwards compatibility, the following will be done:</p>
<ul>
<li>The org.eclipse.core.runtime.Preferences class and the org.eclipse.jface.preference.IPreferenceStore
interface will be implemented on top of the new Settings API.</li>
<li>When upgrading from an older Eclipse version, the old preference files will
be read to determine preference values.</li>
<li>IDialogSettings will be reimplemented in terms of Settings.</li>
</ul>
<p>It is not clear if the IMemento should be implemented on top of Settings or
not. This will be determined later.</p>
<h2><a name="Requirements"></a>Relating to the Requirements</h2>
<p>The only requirement mentioned in &quot;<a href="settings.html">User Settings
In Eclipse</a>&quot; that is not addressed by this proposal is the scenario
for supporting policies for when settings can be changed by the user. This requirement
may be addressed in the future.</p>
<h2><a name="TimeTable"></a>Timetable</h2>
<ul>
<li>3.0 M3: Incorporate feedback from community and prototype implementation</li>
<li>3.0 M4: Live with current mechanisms ported and initial UI.</li>
</ul>