Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 385291

Summary: [Preferences] [preferences] Surprising behavior of ScopedPreferenceStore
Product: [Eclipse Project] Platform Reporter: Sebastian Zarnekow <sebastian.zarnekow>
Component: UIAssignee: Platform UI Triaged <platform-ui-triaged>
Status: CLOSED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: dennis.huebner, henrik.lindberg, john.arthorne, pwebster
Version: 3.8Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Mac OS X   
Whiteboard: stalebug
Bug Depends on:    
Bug Blocks: 384706    

Description Sebastian Zarnekow CLA 2012-07-17 08:17:22 EDT
In Xtext, we observed a strange behavior of the ScopedPreferenceStore. A preference store with the scopes
  ProjectScope
  InstanceScope
  ConfigurationScope

will fail to store project specific settings iff they reflect the same value as the setting in the instance scope. This leads to changed project settings as soon as the workspace setting is modified which renders project specific settings pretty much useless. JDT fixes this by not using the ScopedPreferenceStore but the EclipsePreferences directly.

Could you please elaborate on that design. Is it intentional or was it implemented by accident. Is the API used correctly or are there any issues in the code below?

This is a test case that illustrates the problem:

	@Test
	public void testProjectScopeReadWrite() throws Exception {
		try {
			
			String qualifier = "qualifier";
			
			InstanceScope instanceScope = new InstanceScope();
			ScopedPreferenceStore instanceStore = new ScopedPreferenceStore(instanceScope, qualifier);
			instanceStore.setSearchContexts(new IScopeContext[] { instanceScope, new ConfigurationScope() });

			IProject project = IResourcesSetupUtil.createProject("test");
			ProjectScope projectScope = new ProjectScope(project);
			ScopedPreferenceStore projectStore = new ScopedPreferenceStore(projectScope, qualifier);
			projectStore
					.setSearchContexts(new IScopeContext[] { projectScope, instanceScope, new ConfigurationScope() });

			instanceStore.setValue("lineWidth", 100);
			projectStore.setValue("lineWidth", 100);
			assertEquals(100, instanceStore.getInt("lineWidth"));
			assertEquals(100, projectStore.getInt("lineWidth"));

			instanceStore.setValue("lineWidth", 120);
			assertEquals(120, instanceStore.getInt("lineWidth"));

	// test fails here:
			assertEquals(100, projectStore.getInt("lineWidth"));
		} finally {
			IResourcesSetupUtil.cleanWorkspace();
		}
	}

see also bug 384706
Comment 1 Sebastian Zarnekow CLA 2012-07-17 08:20:04 EDT
This was observed with 3.5.2, 3.8 and 4.2
Comment 2 Dennis Huebner CLA 2012-07-17 08:31:07 EDT
An another behavior with String values:

@Test
	public void testProjectScopeStringReadWrite() throws Exception {
		try {
			
			String qualifier = "qualifier";
			
			InstanceScope instanceScope = new InstanceScope();
			ScopedPreferenceStore instanceStore = new ScopedPreferenceStore(instanceScope, qualifier);
			instanceStore.setSearchContexts(new IScopeContext[] { instanceScope, new ConfigurationScope() });
			
			IProject project = IResourcesSetupUtil.createProject("test");
			ProjectScope projectScope = new ProjectScope(project);
			ScopedPreferenceStore projectStore = new ScopedPreferenceStore(projectScope, qualifier);
			projectStore
			.setSearchContexts(new IScopeContext[] { projectScope, instanceScope, new ConfigurationScope() });
			
			String key = "newInt";
			String originalValue = "100";
			instanceStore.setValue(key, originalValue);
			projectStore.setValue(key, originalValue);
			assertEquals(originalValue, instanceStore.getString(key));
			assertEquals(originalValue, projectStore.getString(key));
			
			String otherValue = "120";
			instanceStore.setValue(key, otherValue);
			
			assertEquals(otherValue, instanceStore.getString(key));
			assertEquals(originalValue, projectStore.getString(key));
		} finally {
			IResourcesSetupUtil.cleanWorkspace();
		}
	}
Comment 3 Sebastian Zarnekow CLA 2012-07-19 11:06:56 EDT
Any rough estimate on when somebody can take a look at this one? We are currently holding our hourses with workarounds / suggested changes in the actual ScopedPreferenceStore because we'd like to understand the initial design and reasoning behind it better.
Comment 4 Paul Webster CLA 2012-07-19 11:23:00 EDT
No one is looking at this area ATM.  John is on vacation until next week, and Oleg is taking some time off.

But I see what you mean, almost every set does a "get*(*)" first instead of a getStorePreferences().get*(*)

Maybe I can get John to comment on it next week.

PW
Comment 5 John Arthorne CLA 2012-07-24 12:03:43 EDT
I don't know much about ScopedPreferenceStore. I wonder if it should be deprecated. I guess its role is adapting IEclipsePreferences to the JFace IPreferenceStore API so maybe it is still needed.

I agree the set* methods look suspect to me. Changing to getStorePreferences().get* on the first line of each set* method sounds like the right answer.
Comment 6 Eclipse Genie CLA 2020-06-03 15:08:57 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.