Bug 281487 - [clean up] Save Participant Cleanup preferences cannot be defined as default in plugin_customization.ini
Summary: [clean up] Save Participant Cleanup preferences cannot be defined as default ...
Status: ASSIGNED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.5   Edit
Hardware: PC Windows XP
: P3 normal with 9 votes (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted
: 375740 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-06-25 07:30 EDT by Thorsten Wärtel CLA
Modified: 2023-11-17 15:09 EST (History)
13 users (show)

See Also:


Attachments
A plugin fixing the plugin_customization.ini settings not read properly (3.25 KB, application/octet-stream)
2017-04-01 15:47 EDT, Arnaud Dovi CLA
no flags Details
plugin_customization.ini (22.39 KB, application/octet-stream)
2017-04-01 15:51 EDT, Arnaud Dovi CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thorsten Wärtel CLA 2009-06-25 07:30:03 EDT
Build ID: 20090619-0625

Steps To Reproduce:
1. Edit plugin_customization.ini of product-defining plugin and include:
org.eclipse.jdt.ui/editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true

and any of

org.eclipse.jdt.ui/sp_cleanup.*

2. Start Eclipse with a new workspace

3. Preferences -> Java -> Editor -> Save Actions -> Additional Actions should be checked and all defined sp_cleanup settings should be displayed in the List below, but only the hardcoded defaults are set.

Likewise, pressing "Restore Defaults" should restore the preferences set in plugin_customization.ini, not the hardcoded defaults.

More information:
org.eclipse.jdt.internal.ui.fix.CleanUpSaveParticipantPreferenceConfiguration.performDefaults() gets hardcoded defaults if scope is not "project", a DefaultScope() should be consulted first here.

org.eclipse.jdt.internal.ui.fix.CleanUpSaveParticipantPreferenceConfiguration.initialize(IScopeContext, IAdaptable) uses org.eclipse.jdt.internal.corext.fix.CleanUpPreferenceUtil.loadSaveParticipantOptions(IScopeContext) to initialize preferences in a new workspace, which should also use a DefaultScope instead of hardcoded settings.
Comment 1 Dani Megert CLA 2013-06-03 04:41:45 EDT
*** Bug 375740 has been marked as a duplicate of this bug. ***
Comment 2 Stefan Cordes CLA 2013-10-18 03:55:50 EDT
Same for Kepler 4.3.1
All entries in plugin_customization.ini are ignored.
Even
org.eclipse.jdt.ui/editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
org.eclipse.jdt.ui/sp_cleanup.on_save_use_additional_actions=true
org.eclipse.jdt.ui/sp_cleanup.format_source_code=true
Comment 3 Stefan Cordes CLA 2014-01-25 16:34:01 EST
Workaround:

Write a Plugin and initialize programmatically via CleanUpPreferenceUtil.saveSaveParticipantOptions:

	/**
	 * See org.eclipse.jdt.internal.ui.fix.CleanUpSaveParticipantPreferenceConfiguration.performDefaults()
	 * org.eclipse.jdt.internal.ui.fix.CleanUpSaveParticipantPreferenceConfiguration.settingsChanged()
	 */
	private void initSaveActions() {
		CleanUpRegistry tempCleanUpRegistry = JavaPlugin.getDefault().getCleanUpRegistry();
		MapCleanUpOptions tempDefaultOptions = tempCleanUpRegistry
				.getDefaultOptions(CleanUpConstants.DEFAULT_SAVE_ACTION_OPTIONS);
		logInfo("tempDefaultOptions=" + tempDefaultOptions);
		Map<String, String> tempMap = tempDefaultOptions.getMap();
		logInfo("tempDefaultOptions.map=" + tempMap);

		tempMap.put(CleanUpConstants.FORMAT_SOURCE_CODE, CleanUpOptions.TRUE);
		tempMap.put(CleanUpConstants.CLEANUP_ON_SAVE_ADDITIONAL_OPTIONS, CleanUpOptions.TRUE);

		//		Window > Preferences > Java > Editor > Save Actions:
		//			[x] Format Code
		//			[x] Additional Actions
		//			    [Configure...]
		//			         Tab Code Organization
		//			                 Remove trailing whitespaces an
		tempMap.put(CleanUpConstants.FORMAT_REMOVE_TRAILING_WHITESPACES, CleanUpOptions.TRUE);
		//			                 Correct indentation: an
		tempMap.put(CleanUpConstants.FORMAT_CORRECT_INDENTATION, CleanUpOptions.TRUE);
		//			         Tab CodeStyle
		//			                  Use Blocks in if/while/for/do statements: an
		tempMap.put(CleanUpConstants.CONTROL_STATEMENTS_USE_BLOCKS, CleanUpOptions.TRUE);
		//			                  Use Modifier 'final' where possible: aus,
		tempMap.put(CleanUpConstants.VARIABLE_DECLARATIONS_USE_FINAL, CleanUpOptions.FALSE);
		//			         Tab Missing Code
		//			                   '@Override' aus.
		tempMap.put(CleanUpConstants.ADD_MISSING_ANNOTATIONS_OVERRIDE, CleanUpOptions.FALSE);
		//			         Tab Unnecessary Code
		//			                   Remove unused imports: an.
		tempMap.put(CleanUpConstants.REMOVE_UNUSED_CODE_IMPORTS, CleanUpOptions.TRUE);

		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_FIELD_USE_THIS, CleanUpOptions.TRUE);
		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_FIELD_USE_THIS_ALWAYS, CleanUpOptions.FALSE);
		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_FIELD_USE_THIS_IF_NECESSARY, CleanUpOptions.TRUE);

		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_METHOD_USE_THIS, CleanUpOptions.TRUE);
		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_METHOD_USE_THIS_ALWAYS, CleanUpOptions.FALSE);
		tempMap.put(CleanUpConstants.MEMBER_ACCESSES_NON_STATIC_METHOD_USE_THIS_IF_NECESSARY, CleanUpOptions.TRUE);

		logInfo("tempDefaultOptions.map=" + tempMap);

		CleanUpPreferenceUtil.saveSaveParticipantOptions(InstanceScope.INSTANCE, tempMap);
		//		tempCleanUpRegistry.getDefaultOptions(ICleanUp.DEFAULT_SAVE_ACTION_OPTIONS);
		//		CleanUpTabPageDescriptor[] descriptors= tempCleanUpRegistry.getCleanUpTabPageDescriptors();
		//
		//	      CleanUpProfileVersioner versioner= new CleanUpProfileVersioner();
		//	    	ProfileStore profileStore= new ProfileStore(CleanUpConstants.CLEANUP_PROFILES, versioner);
		//

	}


With bundle:
 org.eclipse.jdt.ui
and
  <extension
        point="org.eclipse.ui.startup">
     <startup
           class="com.retail_sc.eclipse.RscStartup"></startup>
  </extension>
Comment 4 Robert Platt CLA 2014-09-01 10:42:29 EDT
Confirmed also for Eclipse Luna (4.4)

The functional effect is that we cannot define our preferences simply with an ini file included in with a zipped up Eclipse. This would makes it much easier for people to get started as they just unzip, start eclipse and get working working. However, these important save action preferences aren't honored.
Comment 5 Tanya Yourchuck CLA 2015-12-10 16:04:26 EST
Confirmed also for Eclipse Mars (4.5.1)

These settings in custom.ini file are not taking effect.
org.eclipse.jdt.ui/sp_cleanup.format_source_code=true
org.eclipse.jdt.ui/sp_cleanup.format_source_code_changes_only=true
org.eclipse.jdt.ui/sp_cleanup.remove_trailing_whitespaces_all=true
org.eclipse.jdt.ui/sp_cleanup.on_save_use_additional_actions=true
Comment 6 Arnaud Dovi CLA 2017-04-01 15:42:34 EDT
Confirmed also for Eclipse Neon (4.6.3)

While the Stefan Cordes workaround approach works, it is not good because you are hardcoding option values in a plugin and so on, the maintenance is horrible in a team point of view.

Instead, I have found a cleaner workaround, to maintain a full usage of the plugin_customization.ini file and and more generic code very easy to maintain, with it you will be able to setup even more settings straight from the plugin_customization.ini

I will attach the compiled plugin and my own plugin_customization.ini in here if it is of interest

Pros:
- Fixes even more settings like Themes, Editor Syntax Color, etc...
- Only eclipse_plugin_customization_fix_1.0.0.jar to be copied in plugins/

bundles:
org.eclipse.ui,
org.eclipse.equinox.preferences,
org.apache.commons.lang3

<extension point="org.eclipse.ui.startup">

Code:
/**
 * 
 */
package eclipse_plugin_customization_fix.main;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.ui.IStartup;
import org.osgi.service.prefs.Preferences;

/**
 * @author Administrator
 *
 */
public class Main implements IStartup {

	@SuppressWarnings("serial")
	private final Map<String, String> buggedNameSpace = new HashMap<String, String>() {
		{
			this.put("org.eclipse.jdt.ui", "sp_cleanup|java_|semanticHighlighting|editor_save_participant_org");
			this.put("org.eclipse.e4.ui.css.swt.theme", null);
			this.put("org.eclipse.e4.ui.workbench.renderers.swt", null);
			this.put("org.eclipse.wst.jsdt.ui", "java_|semanticHighlighting");
			this.put("org.eclipse.wst.css.ui", null);
			this.put("org.eclipse.wst.html.ui", null);
		}
	};

	@Override
	public void earlyStartup() {

		final Iterator<Entry<String, String>> it = this.buggedNameSpace.entrySet().iterator();

		while (it.hasNext()) {
			final Map.Entry<String, String> pair = it.next();
			final String nameSpace = pair.getKey();
			final String[] filters = StringUtils.split(pair.getValue(), "|");
			final Preferences pluginCustomizationPreferences = DefaultScope.INSTANCE.getNode(nameSpace);
			final Preferences workspacePreferences = InstanceScope.INSTANCE.getNode(nameSpace);

			try {
				for (final String key : pluginCustomizationPreferences.keys()) {
					if (StringUtils.isNotBlank(key)) {
						if (filters == null || StringUtils.startsWithAny(key, filters)) {
							workspacePreferences.put(key, pluginCustomizationPreferences.get(key, StringUtils.EMPTY));
						}
					}
				}
				workspacePreferences.flush();
			} catch (final Exception e) {
				e.printStackTrace();
			}
			it.remove();
		}

	}

}
Comment 7 Arnaud Dovi CLA 2017-04-01 15:47:06 EDT
Created attachment 267591 [details]
A plugin fixing the plugin_customization.ini settings not read properly

A plugin fixing the plugin_customization.ini settings not read properly of namespaces : org.eclipse.jdt.ui, org.eclipse.e4.ui.css.swt.theme, org.eclipse.e4.ui.workbench.renderers.swt, org.eclipse.wst.jsdt.ui, org.eclipse.wst.css.ui and org.eclipse.wst.html.ui
Comment 8 Arnaud Dovi CLA 2017-04-01 15:51:12 EDT
Created attachment 267592 [details]
plugin_customization.ini

A sample configuration including the bugged one as Dark Theming, Editors Syntax Coloring, they will not work without the plugin and will work after installing the plugin. Enjoy
Comment 9 Andrey Loskutov CLA 2017-04-01 15:55:34 EDT
Arnaud, I wonder why don't you fix the root cause of this mess? Provide a Gerrit patch and we will merge it.
Comment 10 Arnaud Dovi CLA 2017-04-01 16:17:14 EDT
Because I'm just a user of eclipse not a dev of the team, so I'm sure providing a patch for Eclipse, requires a full source code checkout + a lot of free time for testing possible the regressions it will bring and honestly I don't have the solution of this problem. All the plugin does is reading the default values of the ini file and if there are any it 'injects' the settings in the workspace scope, btw a more elegant way of doing it over settings present only in the plugin_customization file would be :
public void earlyStartup() {

    final Iterator<Entry<String, String>> it = this.buggedNameSpace.entrySet().iterator();

    while (it.hasNext()) {
        final Map.Entry<String, String> pair = it.next();
        final String nameSpace = pair.getKey();
        final String[] filters = StringUtils.split(pair.getValue(), "|");
        final Preferences pluginCustomizationPreferences = DefaultScope.INSTANCE.getNode(nameSpace);
        final Preferences workspacePreferences = InstanceScope.INSTANCE.getNode(nameSpace);

        try {
            for (final String key : pluginCustomizationPreferences.keys()) {
                String defaultPluginCustomizationValue = pluginCustomizationPreferences.get(key, StringUtils.EMPTY);
                if (StringUtils.isNotBlank(defaultPluginCustomizationValue) && (filters == null || StringUtils.startsWithAny(key, filters))) {
                    workspacePreferences.put(key, defaultPluginCustomizationValue);
                }
            }
            workspacePreferences.flush();
        } catch (final Exception e) {
            e.printStackTrace();
        }
        it.remove();
    }

}
Comment 11 Arnaud Dovi CLA 2017-04-01 16:26:50 EDT
Also a reason I think this approach is probably even better than fixing the remaing settings of Eclipse in the code, is third party Extension like the Spring STS Toolsuite, it is not possible to change some default values of this extension actually (the one I have set to KO in the sample ini file) a,d with the plugin this becomes possible fixing any extensions not listening at Eclipse scopes
Comment 12 Arnaud Dovi CLA 2017-07-19 15:59:49 EDT
You can now store Eclipse perspectives properly, code cleanups, formatters aswell, maven M2E external install
Also take cares to recurse into configuration nodes to catch the runtimesNodes of m2e not loaded

(I have not shared the newest jar compiled but let me know if any interest if I could help you are welcome !)

https://pastebin.com/hdviyn26
Comment 13 Arnaud Dovi CLA 2017-07-19 16:07:09 EDT
Btw if you want the perspectives to work you have to create them with prefix "SDR " to the perspectives name of you edit "SDR" in the code to whatever you need
Comment 14 Eclipse Genie CLA 2019-10-23 13:40:09 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.

If you have further information on the current state of the bug, please add it. 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.
Comment 15 Antoine Tran CLA 2019-12-04 11:16:29 EST
I confirm the bug in 2019-03.

@Arnaud Dovi, thank you so much for the plugin as a workaround. It might even be a long-term solution in fact. It would be even better is we just have to do eclipse -IUinstall ... -repository .... to install this plugin in one-line, but right now, with you permission, I will copy that in our project.
Comment 16 Antoine Tran CLA 2019-12-04 13:41:57 EST
For people wanting to do the same JAR, but with Maven, here is my pom.xml (adapt the parent). One day I might put all of that in github and release in Maven centrale...

############### ./pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.eumetsat.l2pf.swci.pi.support_services_sdt.sdt-softwaredevelopmenttools</groupId>
		<artifactId>sdt-softwaredevelopmenttools-parent</artifactId>
		<version>2.1.0.1-ATR-Det-SNAPSHOT</version>
		<relativePath>../../pom.xml</relativePath>
	</parent>
	<artifactId>plugincustomization-fixer</artifactId>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<manifestEntries>
							<Manifest-Version>1.0</Manifest-Version>
							<Bundle-ManifestVersion>2</Bundle-ManifestVersion>
							<Bundle-Name>${project.artifactId}</Bundle-Name>
							<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
							<Bundle-Version>${project.version}</Bundle-Version>
							<Require-Bundle>org.eclipse.ui,org.eclipse.equinox.preferences</Require-Bundle>
						</manifestEntries>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build>
	
	<dependencies>
		<dependency>
			<groupId>org.eclipse.platform</groupId>
			<artifactId>org.eclipse.equinox.preferences</artifactId>
			<version>3.7.500</version>
		</dependency>
		<dependency>
			<groupId>org.eclipse.ui</groupId>
			<artifactId>workbench</artifactId>
			<version>3.3.0-I20070608-1100</version>
		</dependency>
	</dependencies>
</project>

############ ./src/main/resources/plugins.xml
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
   <extension point="org.eclipse.ui.startup">
         <startup
           class="org.eumetsat.l2pf.PluginCustomizationFixerStartup"></startup>
   </extension>

   <!-- <extension point="org.eclipse.core.runtime.preferences">
         <startup
           class="eclipse_plugin_customization_fix.main.Main"></startup>
   </extension> -->
</plugin>




###### ./src/main/java/org/eumetsat/l2pf/PluginCustomizationFixerStartup.java
package org.eumetsat.l2pf;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.ui.IStartup;
import org.osgi.service.prefs.Preferences;

public class PluginCustomizationFixerStartup implements IStartup {

    @SuppressWarnings("serial")
    private final Map<String, String> buggedNameSpace = new HashMap<String, String>() {
        {
            this.put("org.eclipse.jdt.ui", "sp_cleanup|java_|semanticHighlighting|editor_save_participant_org");
            this.put("org.eclipse.e4.ui.css.swt.theme", null);
            this.put("org.eclipse.e4.ui.workbench.renderers.swt", null);
            this.put("org.eclipse.wst.jsdt.ui", "java_|semanticHighlighting");
            this.put("org.eclipse.wst.css.ui", null);
            this.put("org.eclipse.wst.html.ui", null);
        }
    };

    /**
     * Constructor.
     */
    public PluginCustomizationFixerStartup() {
    }

    private static boolean startsWithAny(final String string1, final String[] patterns) {
        for (final String pattern : patterns) {
            if (string1.startsWith(pattern)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void earlyStartup() {

        final Iterator<Entry<String, String>> it = this.buggedNameSpace.entrySet().iterator();

        while (it.hasNext()) {
            final Map.Entry<String, String> pair = it.next();
            final String nameSpace = pair.getKey();
            final String[] filters = pair.getValue().split("|");
            final Preferences pluginCustomizationPreferences = DefaultScope.INSTANCE.getNode(nameSpace);
            final Preferences workspacePreferences = InstanceScope.INSTANCE.getNode(nameSpace);

            try {
                for (final String key : pluginCustomizationPreferences.keys()) {
                    if (null != key && !key.isEmpty()) {
                        if (null == filters || startsWithAny(key, filters)) {
                            workspacePreferences.put(key, pluginCustomizationPreferences.get(key, ""));
                        }
                    }
                }
                workspacePreferences.flush();
            } catch (final Exception e) {
                e.printStackTrace();
            }
            it.remove();
        }

    }

}
Comment 17 Eclipse Genie CLA 2021-11-24 14:56:55 EST
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.

If you have further information on the current state of the bug, please add it. 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.
Comment 18 Antoine Tran CLA 2021-11-26 10:14:12 EST
up
Comment 19 Eclipse Genie CLA 2023-11-17 15:09:22 EST
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.

If you have further information on the current state of the bug, please add it. 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.