Runtime preferences

The org.eclipse.core.runtime.preferences package provides infrastructure for storing a plug-in's preferences. Preferences typically map to settings controlled by the user on the Preferences page, although this is not required by the underlying infrastructure. Plug-in preferences are key/value pairs, where the key describes the name of the preference, and the value is one of several different types (boolean, double, float, int, long, or string). Preferences can be stored and retrieved by the platform from the file system. The exact location of the saved preferences depends upon the scope of the preference.

Preference Scopes

The scope of a preference is closely related to where the preference is stored. Plug-in developers can decide which of the standard scopes apply for their preferences, or can define new scopes that make sense for their plug-in. Let's look first at the scopes defined by the platform runtime:

You can think of the overall preference store as a hierarchy of nodes, where each main branch of the hierarchy represents a particular scope. The children of any particular node depend upon how that scope is defined. For the instance and configuration scopes, the child nodes are the preferences for a particular plug-in as specified by a preference qualifier, usually the plug-in's id.

If all of this sounds confusing, don't worry. If you don't care about scopes and nodes, you need not worry about any particular scope or about which node of the tree actually contains your preference value. The preferences API will automatically traverse the nodes in the proper order (instance, configuration, default) when you query a preference value and use the supplied qualifier and preference name to find the node that actually contains the value.

Preferences are accessed using IPreferencesService protocol. The platform's default preference service can be accessed using the Platform class.

	...
	IPreferencesService service = Platform.getPreferencesService();
	...

Once the preference service is obtained, preference values can be queried by name using any of get... methods provided in IPreferencesService. For example, the following snippet queries the value of the "MyPreference" preference in the plug-in "com.example.myplugin".

	...
	IPreferencesService service = Platform.getPreferencesService();
	boolean value = service.getBoolean("com.example.myplugin", "MyPreference", true, null);
	//do something with the value.
	...

The last parameter in the query method is an array of scope contexts to use when searching for the preference node. If the array is null, then the platform assumes that the default scope search order should be used and guesses the appropriate preference node. If an array of scopes contexts is passed, then this determines the scope lookup order that should be used to find the preference node. The default scope lookup order is always consulted if no node can be found using the specified scopes.

Using Scopes and Nodes

If a plug-in needs finer control over the scope search order, classes that represent the scopes can be used to access the actual node that represents the preference at a particular scope. In this way, an array of nodes can be created that specifies the particular search order required. The following snippet queries the preferences service for the same preference used above, but searches the configuration scope for the plug-in, followed by the instance scope for the plug-in. When nodes are specified for the search order, the default scoping is not considered. That is, the platform will only search the exact nodes that have been provided.

	...
	IPreferencesService service = Platform.getPreferencesService();
	Preferences configurationNode = new ConfigurationScope().getNode("com.example.myplugin");
	Preferences instanceNode = new InstanceScope().getNode("com.example.myplugin");
	Preferences[] nodes = new Preferences[] {configurationNode, instanceNode};
	stringValue = service.get("MyPreference", "true", nodes);
	//do something with the value.
	...

A plug-in may also implement its own traversal through the preference tree nodes. The root node of the preference tree can be obtained from the preferences service. The scope classes can be used to further traverse the tree. The following snippet traverses to a specific node and retrieves the preference value from the node itself.

	...
	IPreferencesService service = Platform.getPreferencesService();
	Preferences root = service.getRootNode();
	Preferences myInstanceNode = root.node(InstanceScope.SCOPE).node("com.example.myplugin");
	if (myInstanceNode != null) {
		value = node.getBoolean("MyPreference", "true");
		//do something with the value.
	}
	...

Extending the Scopes

Plug-ins may define their own specialized scopes using the org.eclipse.core.runtime.preferences extension. In this extension, the plug-in defines the name of the new scope, as well a class that can create preference nodes for the new scope. Optionally, it can specify the name of a class that initializes the default preference values at that scope. When a plug-in defines a new scope, it is up to that plug-in to implement the traversal order for any new scope relative to the platform traversal order. We'll look at this capability in more detail using the specific example of Project-scoped preferences.