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

Bug 346269

Summary: Add refactor participant for project-level settings
Product: z_Archived Reporter: Justin Spadea <jspadea>
Component: EDTAssignee: Yun Feng Ma <mayunf>
Status: CLOSED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: chenzhh
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
Patch
none
New Patch
lasher: iplog+
Patch 2
lasher: iplog+
Get the EDT preference nodes for a project
lasher: iplog+
Patch lasher: iplog+

Description Justin Spadea CLA 2011-05-18 10:55:57 EDT
When renaming a project, we need to look at the all project-level settings for the workspace to see if the project was used in any of the output directories, and update the setting if so.

Also need to update settings keys when renaming a .egl file or egl package.
Comment 1 Justin Spadea CLA 2011-07-05 10:45:53 EDT
Hi Forest, I made you the owner of this since you're looking at refactoring in general (bug 349847).

The settings are stored in a file in the project's .settings folder. It can be retrieved via:

IEclipsePreferences prefs = new ProjectScope(project).getNode(EDTCoreIDEPlugin.PLUGIN_ID);

Each setting is a sub-node, and then its key is either <project> or the path to a resource within the project. You can use the following as a starting point for updating keys when a source file or package is renamed:

String[] names = prefs.childrenNames();
for (String name : names) {
	Preferences nextNode = prefs.node(name);
	String[] keys = nextNode.keys();
	for (String key : keys) {
		if (key.equals(pathThatChanged)) {
			nextNode.put(newKey, nextNode.get(key, null));
			nextNode.remove(key);
		}
	}
}
Comment 2 Justin Spadea CLA 2011-07-05 10:47:35 EDT
Another thing to be handled - removing keys when a file/folder is deleted.
Comment 3 Yun Feng Ma CLA 2011-08-31 23:31:24 EDT
Hi Tony and Justin,

For renaming a project, I didn't see anything needs to be updated. Here is a .Settings file, the project name is substituted by <project>: 
   javaGenDirectory/<project>=P/generatedJava
   javaGenDirectory//eglsource/services=P/generatedJava
   jsGenDirectory/<project>=P/generatedJavaScript

For renaming a gen out directory, such as generatedJava, we do need to update the .Settings file.

Anyway, I don't think this a must-have feature in 0.7.0, so defer it to future. Let me know if you think it must be in 0.7.0. Thanks a lot.
Comment 4 Justin Spadea CLA 2011-09-01 09:28:10 EDT
Hi Forest,

I agree with the change about renaming a directory that's being used as the gen directory. Note that you will need to check every EGL project because some other project might be generating into this directory. Example: ProjectA generates into ProjectB/generatedJava. ProjectB/generatedJava gets renamed to ProjectB/genJava - ProjectA's project-level setting needs to be updated with this new value.

The same thing is true when renaming a project. ProjectA generates into ProjectB, so its path key would be something like: "javaGenDirectory/<project>=W/ProjectB/generatedJava" - if you rename ProjectB then the path key for ProjectA needs to be updated.

One more thing that will need to be updated: The default DD file for a project will be stored inside the .settings/ folder, and this DD file can be located anywhere in the workspace. When the path to this file is changed (the project name, one or more folders, or the DD file name) then this property needs to be updated.

I think a general-purpose path key updater is necessary. The code in Comment 1 is a starting point for this general-purpose refactor participant. Make it reusable so that different plug-ins can contribute it, passing in the plug-in ID for its particular node. Then any changed key paths within that node would get updated.
Comment 5 Yun Feng Ma CLA 2011-09-22 03:52:22 EDT
Created attachment 203820 [details]
Patch

Here is a patch for this. Thanks.
Comment 6 Yun Feng Ma CLA 2011-09-26 22:50:23 EDT
Created attachment 204043 [details]
New Patch

Here is a new patch.
Comment 7 Justin Spadea CLA 2011-09-27 15:12:21 EDT
Hi Yun Feng,

A couple things:

1. When renaming or removing a folder or project, it's updating references to that specific folder or project, but it also needs to update any keys that have a path that is a child of the folder or project. For example:

pkg/foo.egl

Put some generator settings specifically on 'pkg', and then do the same for 'foo.egl'. Keys will be added for both the 'pkg' and the 'foo.egl' paths. Rename 'pkg' to 'pkg2'. The key for 'pkg' has been updated appropriately. The key foe 'foo.egl' has not, and is still using 'pkg' in its path. This most likely has to do with returning 'false' in the visitor when it should return 'true' to visit the child delta for foo.egl.

2. None of the *values* of the settings get updated. If I rename a folder that happens to be a generation folder for project X, the generation setting for project X does not get updated. This is also true for the DefaultDeploymentDescriptorPath setting.

3. While the code works for the settings that we provide (using a hardcoded array of .settings files to check), it won't update any contributed compilers/generators that use a different .settings file (e.g. my.company.android.generator.prefs). There's a couple options: add API to IGenerator that returns the plug-in ID containing its project-level settings. This already exists in AbstractGenerator.getProjectSettingsPluginId(), just needs to be made public and added to the interface. Then you could iterate over the generators for the changed path, processing each of their .prefs files. OR... instead of using ProjectScope just directly using the preferences service:

Preferences projectPrefs = Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE).node(project.getName());
String[] prefsFiles = projectPrefs.childrenNames();
for (String file : prefsFiles) {
	Preferences prefs = projectPrefs.node(file); // e.g. org.eclipse.edt.ide.core.prefs

This last way can be dangerous in that we might update a file that has nothing to do with EDT. I'm okay with opening a separate bug for this and addressing it in 1.0.
Comment 8 Yun Feng Ma CLA 2011-09-29 04:16:33 EDT
Created attachment 204264 [details]
Patch 2

Hi Justin,

Thanks a lot for your review. I've made changes. This patch also fixed bug 359229. Thanks.
Comment 9 Yun Feng Ma CLA 2011-09-29 05:30:59 EDT
Fix has been checked in, let me know if you see other issue. I've opened a enhancement Bug 359381  for the issue in comment 7. Thanks.
Comment 10 Justin Spadea CLA 2011-09-29 11:57:19 EDT
Hi Yun Feng,

I was unclear in my last comment. I see that you implemented the code snippet I pasted, but I was suggesting we leave it to only update the two hardcoded .prefs files for now and then address a more general solution later on.

I took a quick look at a good way to 1) not update files that aren't related to EDT, and 2) support third-party generators. I'll attach a patch that includes the work that can provide to you the relevant nodes to be updated. You will need to update your code to make use of ProjectSettingsUtility.getPreferenceNodes() in the same way that it was previously using the 'plugins' array.

I changed my mind about deferring this to 1.0, since it would look pretty bad if third-party generators lost their settings then resources were renamed.
Comment 11 Justin Spadea CLA 2011-09-29 11:58:26 EDT
Created attachment 204308 [details]
Get the EDT preference nodes for a project
Comment 12 Yun Feng Ma CLA 2011-09-30 02:50:27 EDT
Created attachment 204344 [details]
Patch

Justin,

I've attached a patch, which include yours. Let me know if you have any other comments. Thanks.
Comment 13 Yun Feng Ma CLA 2011-09-30 06:12:29 EDT
This fix is in. Thanks.
Comment 14 Justin Spadea CLA 2011-11-04 15:36:42 EDT
I'm closing this enhancement but opening a bug for an issue i found.