diff options
author | Arthur Daussy | 2014-02-28 15:13:20 +0000 |
---|---|---|
committer | Arthur Daussy | 2014-03-13 10:34:32 +0000 |
commit | e931f76249ebe45d6569889b1c970078e2743ed7 (patch) | |
tree | 072941395eb6bcfe595122afbccb434664d12a60 | |
parent | e63deb9b180c40d8eea784f6846aafdcfad068af (diff) | |
download | org.eclipse.emf.compare-e931f76249ebe45d6569889b1c970078e2743ed7.tar.gz org.eclipse.emf.compare-e931f76249ebe45d6569889b1c970078e2743ed7.tar.xz org.eclipse.emf.compare-e931f76249ebe45d6569889b1c970078e2743ed7.zip |
[429441] Enable/Disable post processors.
Add UI to Enable/Disable post processors
Add preference for post processors.
Refactor preference page to be more generic.
Bug: 429441
Change-Id: Ib9482e5bf23c378c20ac7bfcbe91cd4f7a5469a9
Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr>
19 files changed, 1216 insertions, 608 deletions
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml index 87aef0b2b..4d522fe50 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml +++ b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml @@ -178,6 +178,12 @@ id="org.eclipse.emf.compare.rcp.ui.preferencePage.engines" name="Engines"> </page> + <page + category="org.eclipse.emf.compare.rcp.ui.preferencePage.global" + class="org.eclipse.emf.compare.rcp.ui.internal.preferences.PostProcessorPreferencePage" + id="org.eclipse.emf.compare.rcp.ui.preferencePage.postProcessors" + name="Post Processors"> + </page> </extension> <extension point="org.eclipse.emf.compare.rcp.ui.matchEngineFactoryConfigurationUI"> diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java index 66bd71f36..dbf92b78a 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java @@ -144,7 +144,7 @@ public class EMFCompareRCPUIPlugin extends AbstractUIPlugin { matchEngineConfiguratorRegistryListener = new ConfigurationUIRegistryEventListener(PLUGIN_ID, MATCH_ENGINE_FACTORY_CONFIGURATION_UI_PPID, getLog(), matchEngineConfiguratorRegistry, EMFCompareRCPPlugin.getDefault().getMatchEngineFactoryDescriptorRegistry()); - extensionRegistry.addListener(matchEngineConfiguratorRegistryListener, PLUGIN_ID + "." + extensionRegistry.addListener(matchEngineConfiguratorRegistryListener, PLUGIN_ID + '.' + MATCH_ENGINE_FACTORY_CONFIGURATION_UI_PPID); matchEngineConfiguratorRegistryListener.readRegistry(extensionRegistry); diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java index fe78b63e2..7747817ab 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java @@ -77,7 +77,7 @@ public class ConfigurationUIRegistryEventListener extends AbstractRegistryEventL .getAttribute(ITEM_TO_CONFIGURE_ATTR));
if (itemToConfigure == null) {
log(IStatus.WARNING, element, EMFCompareRCPUIMessages
- .getString("EnginesPreferencePagestatic.INCORRECT_ID_PARAMETER")); //$NON-NLS-1$
+ .getString("ConfigurationUIRegistryEventListener.INCORRECT_ID_PARAMETER")); //$NON-NLS-1$
ret = false;
} else {
ret = true;
@@ -113,7 +113,7 @@ public class ConfigurationUIRegistryEventListener extends AbstractRegistryEventL }
} else {
log(IStatus.WARNING, element, EMFCompareRCPUIMessages
- .getString("EnginesPreferencePagestatic.INCORRECT_CONFIGURATOR_PARAMETER")); //$NON-NLS-1$
+ .getString("ConfigurationUIRegistryEventListener.INCORRECT_CONFIGURATOR_PARAMETER")); //$NON-NLS-1$
}
} catch (CoreException e) {
e.printStackTrace();
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties index ed245eb4d..a825559f3 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties @@ -30,33 +30,34 @@ ThreeWayComparisonGroupProvider.right.label = Right Side BasicDifferenceGroup.name = Group +ConfigurationUIRegistryEventListener.INCORRECT_ID_PARAMETER = Id do not match any item to configure. +ConfigurationUIRegistryEventListener.INCORRECT_CONFIGURATOR_PARAMETER = The element is not an instance of IConfigurationUIFactory + +# Messages for preference pages. + +InteractiveUIContent.DEFAULT_CONFIGURATION_LABEL = "The selected engine has no configuration option" +InteractiveUIContent.CONFIGURATION_COMPOSITE_LABEL = Configuration +InteractiveUIContent.DESCRIPTION_COMPOSITE_LABEL = Description +InteractiveUIContent.INCORRECT_SELECTION_TITLE =Incorrect selection +InteractiveUIContent.INCORRECT_SELECTION_MESSAGE = At least one item has to be selected. + +PostProcessorPreferencePage.PREFERENCE_PAGE_DESCRIPTION = Select active post processors: EditorPreferencePage.mainTab.label = Main EditorPreferencePage.mainTab.colorHyperLink.label = See <a>''Color and Fonts''</a> preferences for EMF Compare colors. - EditorPreferencePage.groupsTab.label = Groups EditorPreferencePage.filtersTab.label = Filters -InteractiveUIContent.DEFAULT_CONFIGURATION_LABEL = "The selected engine has no configuration option" - -EnginesPreferencePagestatic.CONFIGURATION_COMPOSITE_LABEL = Configuration -EnginesPreferencePagestatic.DESCRIPTION_COMPOSITE_LABEL = Description - EnginesPreferencePage.DIFFERENCES_ENGINE_TAB_LABEL = Difference EnginesPreferencePage.EQUIVALENCES_ENGINE_TAB_LABEL = Equivalence EnginesPreferencePage.REQUIREMENT_ENGINE_TAB_LABEL = Requirement EnginesPreferencePage.CONFLICT_DETECTOR_TAB_LABEL = Conflict EnginesPreferencePage.MATCH_ENGINE_TAB_LABEL = Match -EnginesPreferencePagestatic.MATCH_ENGINE_INTRO_TEXT = Select active matching engines: -EnginesPreferencePagestatic.DIFF_ENGINE_INTRO_TEXT = Select the difference engine to use: -EnginesPreferencePagestatic.EQUI_ENGINE_INTRO_TEXT = Select the equivalence engine to use: -EnginesPreferencePagestatic.REQ_ENGINE_INTRO_TEXT = Select the requirement engine to use: -EnginesPreferencePagestatic.CONFLICT_DETECTOR_INTRO_TEXT = Select the conflict detector to use: -EnginesPreferencePagestatic.INCORRECT_SELECTION_TITLE=Incorrect selection -EnginesPreferencePagestatic.INCORRECT_SELECTION_MESSAGE=At least one item has to be selected. - -EnginesPreferencePagestatic.INCORRECT_ID_PARAMETER = Id do not match any item to configure. -EnginesPreferencePagestatic.INCORRECT_CONFIGURATOR_PARAMETER = The element is not a instance of IConfigurationUIFactory +EnginesPreferencePage.MATCH_ENGINE_INTRO_TEXT = Select active matching engines: +EnginesPreferencePage.DIFF_ENGINE_INTRO_TEXT = Select the difference engine to use: +EnginesPreferencePage.EQUI_ENGINE_INTRO_TEXT = Select the equivalence engine to use: +EnginesPreferencePage.REQ_ENGINE_INTRO_TEXT = Select the requirement engine to use: +EnginesPreferencePage.CONFLICT_DETECTOR_INTRO_TEXT = Select the conflict detector to use: DefaultMatchEngineConfiguratorUI.USE_IDENTIFER_LABEL = Select if identifiers shall be used: DefaultMatchEngineConfiguratorUI.WHEN_AVAILABLE_LABEL = When avalaible\n The engine will use some heuristics when the identifiers are missing diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java new file mode 100644 index 000000000..98a4e94fd --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; + +/** + * POJO used to hold data from preference page. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + * @param <T> + * Type of the item descriptor. + */ +public class DataHolder<T> { + + /** Field name (used for databinding). */ + public static final String DATA_FIELD_NAME = "data"; //$NON-NLS-1$ + + /** Filed holding multiple data. */ + public Set<IItemDescriptor<T>> data = new LinkedHashSet<IItemDescriptor<T>>(); + + /** + * Get data + * + * @return + */ + public Set<IItemDescriptor<T>> getData() { + return data; + } + + /** + * Set data. + * + * @param currentSelection + */ + public void setData(Set<IItemDescriptor<T>> currentSelection) { + this.data = currentSelection; + } + +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java index 6c0cee248..1021746b9 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java @@ -10,24 +10,19 @@ *******************************************************************************/ package org.eclipse.emf.compare.rcp.ui.internal.preferences; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.eclipse.core.databinding.DataBindingContext; -import org.eclipse.core.databinding.beans.PojoProperties; -import org.eclipse.core.databinding.observable.set.IObservableSet; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.emf.compare.conflict.IConflictDetector; import org.eclipse.emf.compare.diff.IDiffEngine; @@ -45,36 +40,19 @@ import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.AbstractConfigurationUI; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.IConfigurationUIFactory; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.InteractiveUIContent.InteractiveUIBuilder; import org.eclipse.emf.compare.req.IReqEngine; -import org.eclipse.jface.databinding.viewers.IViewerObservableSet; -import org.eclipse.jface.databinding.viewers.ViewersObservables; -import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; -import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.preferences.ScopedPreferenceStore; @@ -88,26 +66,23 @@ import org.osgi.service.prefs.Preferences; */ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { - /** Label provider for {@link IItemDescriptor} */ - private final EngineDescriptorLabelProvider descriptorLabelProvider = new EngineDescriptorLabelProvider(); - /** Pointer to all {@link InteractiveUIContent} of each tab */ private final Map<String, InteractiveUIContent> interactiveUis = new HashMap<String, InteractiveUIContent>(); /** Data regarding the Difference selected engine */ - private final SingleValueHolder<IDiffEngine> diffEngineData = new SingleValueHolder<IDiffEngine>(); + private final DataHolder<IDiffEngine> diffEngineData = new DataHolder<IDiffEngine>(); /** Data regarding the Equivalence selected engine */ - private final SingleValueHolder<IEquiEngine> equiEngineData = new SingleValueHolder<IEquiEngine>(); + private final DataHolder<IEquiEngine> equiEngineData = new DataHolder<IEquiEngine>(); /** Data regarding the Requirement selected engine */ - private final SingleValueHolder<IReqEngine> reqEngineData = new SingleValueHolder<IReqEngine>(); + private final DataHolder<IReqEngine> reqEngineData = new DataHolder<IReqEngine>(); /** Data regarding the Conflicts detector selected engine */ - private final SingleValueHolder<IConflictDetector> conflictsDetectorData = new SingleValueHolder<IConflictDetector>(); + private final DataHolder<IConflictDetector> conflictsDetectorData = new DataHolder<IConflictDetector>(); /** Data regarding the selected match engine factories. */ - private final MultipleValueHolder<IMatchEngine.Factory> matchEnginesData = new MultipleValueHolder<IMatchEngine.Factory>(); + private final DataHolder<IMatchEngine.Factory> matchEnginesData = new DataHolder<IMatchEngine.Factory>(); public EnginesPreferencePage() { super(); @@ -123,6 +98,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP public void init(IWorkbench workbench) { // Do not use InstanceScope.Instance to be compatible with Helios. + @SuppressWarnings("deprecation") ScopedPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(), EMFCompareRCPPlugin.PLUGIN_ID); setPreferenceStore(store); @@ -150,6 +126,34 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP } /** + * Create an {@link InteractiveUIContent} object of a specific type of engine. + * + * @param registry + * Registry holding engines. + * @param enginePreferenceKey + * Preference key use to store preferences + * @param pref + * {@link IEclipsePreferences} holding preferences. + * @param tabComposite + * Holding composite. + * @param dataHolder + * Data that will be synchronoze with the UI. + * @param <T> + * type of engine. + * @return {@link InteractiveUIContent} for a specific type of engine. + */ + private <T> InteractiveUIContent createEngineUIBuilder(IItemRegistry<T> registry, + String enginePreferenceKey, IEclipsePreferences pref, Composite tabComposite, + DataHolder<T> dataHolder) { + IItemDescriptor<T> defaultEngine = ItemUtil.getDefaultItemDescriptor(registry, enginePreferenceKey, + pref); + InteractiveUIBuilder<T> uiBuilder = new InteractiveUIBuilder<T>(tabComposite, registry); + uiBuilder.setSimple(true).setDefaultCheck(Collections.singleton(defaultEngine)).setDefaultSelection( + defaultEngine).setHoldingData(dataHolder); + return uiBuilder.build(); + } + + /** * Create a tab to select one Conflict Detector. * * @param tabFolder @@ -160,15 +164,14 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP // Create tab structure Composite tabComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages .getString("EnginesPreferencePage.CONFLICT_DETECTOR_TAB_LABEL"),//$NON-NLS-1$ - EMFCompareRCPUIMessages.getString("EnginesPreferencePagestatic.CONFLICT_DETECTOR_INTRO_TEXT"));//$NON-NLS-1$ - // Create main content structure - InteractiveUIContent contentStructure = createContentSkeleton(tabComposite); + EMFCompareRCPUIMessages.getString("EnginesPreferencePage.CONFLICT_DETECTOR_INTRO_TEXT"));//$NON-NLS-1$ - setUpUniqueCheckViewer(conflictDetectorDescriptorRegistry, contentStructure, - EMFComparePreferences.CONFLICTS_DETECTOR, conflictsDetectorData); + InteractiveUIContent interactiveContent = createEngineUIBuilder(conflictDetectorDescriptorRegistry, + EMFComparePreferences.CONFLICTS_DETECTOR, EMFCompareRCPPlugin.getDefault() + .getEMFComparePreferences(), tabComposite, conflictsDetectorData); // Save for reset default - interactiveUis.put(EMFComparePreferences.CONFLICTS_DETECTOR, contentStructure); + interactiveUis.put(EMFComparePreferences.CONFLICTS_DETECTOR, interactiveContent); } /** @@ -182,15 +185,14 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP // Create tab structure Composite tabComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages .getString("EnginesPreferencePage.REQUIREMENT_ENGINE_TAB_LABEL"), //$NON-NLS-1$ - EMFCompareRCPUIMessages.getString("EnginesPreferencePagestatic.REQ_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - // Create main content structure - InteractiveUIContent contentStructure = createContentSkeleton(tabComposite); + EMFCompareRCPUIMessages.getString("EnginesPreferencePage.REQ_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - setUpUniqueCheckViewer(reqEngineDescriptorRegistry, contentStructure, - EMFComparePreferences.REQ_ENGINES, reqEngineData); + InteractiveUIContent interactiveContent = createEngineUIBuilder(reqEngineDescriptorRegistry, + EMFComparePreferences.REQ_ENGINES, EMFCompareRCPPlugin.getDefault() + .getEMFComparePreferences(), tabComposite, reqEngineData); // Save for reset default - interactiveUis.put(EMFComparePreferences.REQ_ENGINES, contentStructure); + interactiveUis.put(EMFComparePreferences.REQ_ENGINES, interactiveContent); } /** @@ -204,15 +206,14 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP // Create tab structure Composite tabComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages .getString("EnginesPreferencePage.EQUIVALENCES_ENGINE_TAB_LABEL"), //$NON-NLS-1$ - EMFCompareRCPUIMessages.getString("EnginesPreferencePagestatic.EQUI_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - // Create main content structure - InteractiveUIContent contentStructure = createContentSkeleton(tabComposite); + EMFCompareRCPUIMessages.getString("EnginesPreferencePage.EQUI_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - setUpUniqueCheckViewer(equiEngineDescriptorRegistry, contentStructure, - EMFComparePreferences.EQUI_ENGINES, equiEngineData); + InteractiveUIContent interactiveContent = createEngineUIBuilder(equiEngineDescriptorRegistry, + EMFComparePreferences.EQUI_ENGINES, EMFCompareRCPPlugin.getDefault() + .getEMFComparePreferences(), tabComposite, equiEngineData); // Save for reset default - interactiveUis.put(EMFComparePreferences.EQUI_ENGINES, contentStructure); + interactiveUis.put(EMFComparePreferences.EQUI_ENGINES, interactiveContent); } /** @@ -226,15 +227,14 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP // Create tab structure Composite tabComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages .getString("EnginesPreferencePage.DIFFERENCES_ENGINE_TAB_LABEL"), EMFCompareRCPUIMessages //$NON-NLS-1$ - .getString("EnginesPreferencePagestatic.DIFF_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - // Create main content structure - InteractiveUIContent contentStructure = createContentSkeleton(tabComposite); + .getString("EnginesPreferencePage.DIFF_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - setUpUniqueCheckViewer(diffEngineDescriptorRegistry, contentStructure, - EMFComparePreferences.DIFF_ENGINES, diffEngineData); + InteractiveUIContent interactiveContent = createEngineUIBuilder(diffEngineDescriptorRegistry, + EMFComparePreferences.DIFF_ENGINES, EMFCompareRCPPlugin.getDefault() + .getEMFComparePreferences(), tabComposite, diffEngineData); // Save for reset default - interactiveUis.put(EMFComparePreferences.DIFF_ENGINES, contentStructure); + interactiveUis.put(EMFComparePreferences.DIFF_ENGINES, interactiveContent); } @@ -250,44 +250,23 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP .getItemDescriptor(DefaultRCPMatchEngineFactory.class.getCanonicalName()); Composite tabComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages .getString("EnginesPreferencePage.MATCH_ENGINE_TAB_LABEL"), EMFCompareRCPUIMessages //$NON-NLS-1$ - .getString("EnginesPreferencePagestatic.MATCH_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ - // Create main content structure - InteractiveUIContent interactiveUI = createContentSkeleton(tabComposite); - // Create viewer + .getString("EnginesPreferencePage.MATCH_ENGINE_INTRO_TEXT")); //$NON-NLS-1$ + Map<String, IConfigurationUIFactory> configuratorUIRegistry = EMFCompareRCPUIPlugin.getDefault() .getMatchEngineConfiguratorRegistry(); String matchEnginePreferenceKey = EMFComparePreferences.MATCH_ENGINE_DISABLE_ENGINES; - setUpMultipleCheckViewer(matchEngineFactoryDescriptorRegistry, interactiveUI, - matchEnginePreferenceKey, configuratorUIRegistry); + Set<IItemDescriptor<Factory>> activeItems = ItemUtil.getActiveItems( + matchEngineFactoryDescriptorRegistry, matchEnginePreferenceKey); + + InteractiveUIBuilder<IMatchEngine.Factory> builder = new InteractiveUIBuilder<IMatchEngine.Factory>( + tabComposite, matchEngineFactoryDescriptorRegistry); + builder.setConfiguratorUIRegistry(configuratorUIRegistry).setDefaultCheck(activeItems) + .setConfigurationNodeKey(EMFComparePreferences.MATCH_ENGINE_DISABLE_ENGINES) + .setDefaultSelection(defaultMatchEngineDescriptor).setHoldingData(matchEnginesData); // Save for reset default - interactiveUis.put(matchEnginePreferenceKey, interactiveUI); - // Init default - interactiveUI.select(defaultMatchEngineDescriptor); - matchEnginesData.setCurrentSelection(getActiveItems(matchEngineFactoryDescriptorRegistry, - matchEnginePreferenceKey)); - bindMultipleData(MultipleValueHolder.DATA_FIELD_NAME, interactiveUI.getViewer(), matchEnginesData); - } + interactiveUis.put(matchEnginePreferenceKey, builder.build()); - /** - * Create the skeleton of a tab. All needed composites and layout. - * - * @param tabComposite - * @return - */ - private InteractiveUIContent createContentSkeleton(Composite tabComposite) { - Composite contentComposite = new Composite(tabComposite, SWT.NONE); - contentComposite.setLayout(new GridLayout(2, true)); - contentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - // Engine chooser composite - Composite viewerComposite = new Composite(contentComposite, SWT.NONE); - viewerComposite.setLayout(new GridLayout(1, true)); - viewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); - // Config composite - Group configComposite = createConfigComposite(contentComposite); - // Descriptor engine Text - Text descriptionText = createDescriptionComposite(tabComposite); - return new InteractiveUIContent(descriptionText, viewerComposite, configComposite); } /** @@ -313,187 +292,6 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP return tabComposite; } - /** - * Composite for description. This composite hold the text widget that will update with the current - * selection - * - * @param composite - * @return - */ - private Text createDescriptionComposite(Composite composite) { - Group descriptionComposite = new Group(composite, SWT.BORDER); - descriptionComposite.setText(EMFCompareRCPUIMessages - .getString("EnginesPreferencePagestatic.DESCRIPTION_COMPOSITE_LABEL")); //$NON-NLS-1$ - descriptionComposite.setLayout(new GridLayout(1, false)); - descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); - Text engineDescriptionText = new Text(descriptionComposite, SWT.WRAP | SWT.MULTI); - engineDescriptionText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1); - layoutData.heightHint = 50; - engineDescriptionText.setLayoutData(layoutData); - engineDescriptionText.setEditable(false); - return engineDescriptionText; - } - - /** - * Create the composite that will hold all configurations for a tab. - * - * @param composite - * @return - */ - private Group createConfigComposite(Composite composite) { - Group configurationComposite = new Group(composite, SWT.BORDER); - configurationComposite.setText(EMFCompareRCPUIMessages - .getString("EnginesPreferencePagestatic.CONFIGURATION_COMPOSITE_LABEL")); //$NON-NLS-1$ - StackLayout layout = new StackLayout(); - layout.marginHeight = 10; - layout.marginWidth = 10; - configurationComposite.setLayout(layout); - GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); - configurationComposite.setLayoutData(layoutData); - return configurationComposite; - } - - /** - * Set up a {@link CheckboxTableViewer} which accept only one element checked at a time - * - * @param registry - * @param interactiveUI - * @param preferenceKey - * @param dataObject - * @param configuratorRegistry - */ - private <T> void setUpUniqueCheckViewer(IItemRegistry<T> registry, - final InteractiveUIContent interactiveUI, String preferenceKey, - final SingleValueHolder<T> dataObject) { - - final CheckboxTableViewer descriptorViewer = CheckboxTableViewer.newCheckList(interactiveUI - .getViewerComposite(), SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE); - descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); - descriptorViewer.setLabelProvider(descriptorLabelProvider); - GridData gd = new GridData(GridData.FILL_BOTH); - descriptorViewer.getControl().setLayoutData(gd); - - // Only one check at a time - descriptorViewer.addCheckStateListener(new ICheckStateListener() { - public void checkStateChanged(CheckStateChangedEvent event) { - Object element = event.getElement(); - if (event.getChecked()) { - if (element instanceof IItemDescriptor<?>) { - @SuppressWarnings("unchecked") - IItemDescriptor<T> descriptor = (IItemDescriptor<T>)element; - dataObject.setCurrentSelection(descriptor); - } - descriptorViewer.setCheckedElements(new Object[] {element }); - } else { - // Prevent from nothing checked - if (descriptorViewer.getCheckedElements().length == 0) { - descriptorViewer.setCheckedElements(new Object[] {element }); - MessageDialog - .openWarning( - getShell(), - EMFCompareRCPUIMessages - .getString("EnginesPreferencePagestatic.INCORRECT_SELECTION_TITLE"), //$NON-NLS-1$ - EMFCompareRCPUIMessages - .getString("EnginesPreferencePagestatic.INCORRECT_SELECTION_MESSAGE")); //$NON-NLS-1$ - } - } - - } - }); - - List<IItemDescriptor<T>> itemDescriptors = registry.getItemDescriptors(); - Collections.sort(itemDescriptors, Collections.reverseOrder()); - descriptorViewer.setInput(itemDescriptors); - - interactiveUI.setViewer(descriptorViewer); - - // Init default value - IItemDescriptor<T> defaultEngine = ItemUtil.getDefaultItemDescriptor(registry, preferenceKey, - EMFCompareRCPPlugin.getDefault().getEMFComparePreferences()); - interactiveUI.select(defaultEngine); - interactiveUI.checkElement(defaultEngine); - dataObject.setCurrentSelection(defaultEngine); - - } - - /** - * Set up a {@link CheckboxTableViewer} which accept multiple checked element. - * - * @param registry - * @param interactiveUI - * @param preferenceKey - * @param configuratorRegistry - */ - private <T> void setUpMultipleCheckViewer(IItemRegistry<T> registry, - final InteractiveUIContent interactiveUI, String preferenceKey, - Map<String, IConfigurationUIFactory> configuratorUIRegistry) { - CheckboxTableViewer descriptorViewer = CheckboxTableViewer.newCheckList(interactiveUI - .getViewerComposite(), SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); - interactiveUI.setViewer(descriptorViewer); - descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); - descriptorViewer.setLabelProvider(descriptorLabelProvider); - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); - descriptorViewer.getControl().setLayoutData(gd); - - // Init configuration elements - for (IItemDescriptor<T> item : registry.getItemDescriptors()) { - String itemId = item.getID(); - IConfigurationUIFactory configuratorFactory = configuratorUIRegistry.get(itemId); - if (configuratorFactory != null) { - Preferences pref = ItemUtil.getConfigurationPreferenceNode(preferenceKey, itemId); - interactiveUI.addConfigurator(itemId, configuratorFactory, pref); - } - } - // Filter input with input with higher rank than default item descriptor - List<IItemDescriptor<T>> itemDescriptors = registry.getItemDescriptors(); - Collections.sort(itemDescriptors, Collections.reverseOrder()); - descriptorViewer.setInput(itemDescriptors); - - } - - /** - * Get all active item from a registry. (Filter out all disable element stored in preferences) - * - * @param registry - * @param preferenceKey - * Preference key where are stored disabled items. - * @return - */ - private <T> Set<IItemDescriptor<T>> getActiveItems(IItemRegistry<T> registry, String preferenceKey) { - List<IItemDescriptor<T>> itemsDescriptor = ItemUtil.getItemsDescriptor(registry, preferenceKey, - EMFCompareRCPPlugin.getDefault().getEMFComparePreferences()); - - if (itemsDescriptor == null) { - itemsDescriptor = Collections.emptyList(); - } - Set<IItemDescriptor<T>> disableFactories = Sets.newHashSet(itemsDescriptor); - Set<IItemDescriptor<T>> allFactories = Sets.newHashSet(registry.getItemDescriptors()); - Set<IItemDescriptor<T>> activeFactory = Sets.difference(allFactories, disableFactories); - - return activeFactory; - } - - /** - * Bind UI to data object. - * - * @param engineBindingProperty - * @param descriptorViewer - * @param dataObject - */ - private <T> void bindMultipleData(String engineBindingProperty, CheckboxTableViewer descriptorViewer, - final MultipleValueHolder<T> dataObject) { - DataBindingContext ctx = new DataBindingContext(); - // Bind the button with the corresponding field in data - IViewerObservableSet target = ViewersObservables.observeCheckedElements(descriptorViewer, - IItemDescriptor.class); - // IObservableValue target = WidgetProperties.selection().observe(viewer); - IObservableSet model = PojoProperties.set(MultipleValueHolder.class, engineBindingProperty).observe( - dataObject); - - ctx.bindSet(target, model); - } - @Override public boolean performOk() { @@ -502,7 +300,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP storeConfigurations(); if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { - StringBuilder traceMessage = new StringBuilder("Preference serialization:\n"); //$NON-NLS-1$ + StringBuilder traceMessage = new StringBuilder("Engines preference serialization:\n"); //$NON-NLS-1$ String prefDelimiter = " :\n"; //$NON-NLS-1$ String new_line = "\n"; //$NON-NLS-1$ traceMessage.append(EMFComparePreferences.DIFF_ENGINES).append(prefDelimiter).append( @@ -528,25 +326,25 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP */ private void setEnginesPreferences() { // Update preferences preferences - setEnginePreferences(EMFComparePreferences.DIFF_ENGINES, diffEngineData.getCurrentSelection(), - EMFCompareRCPPlugin.getDefault().getDiffEngineDescriptorRegistry() - .getHighestRankingDescriptor()); - setEnginePreferences(EMFComparePreferences.EQUI_ENGINES, equiEngineData.getCurrentSelection(), - EMFCompareRCPPlugin.getDefault().getEquiEngineDescriptorRegistry() - .getHighestRankingDescriptor()); - setEnginePreferences(EMFComparePreferences.REQ_ENGINES, reqEngineData.getCurrentSelection(), - EMFCompareRCPPlugin.getDefault().getReqEngineDescriptorRegistry() - .getHighestRankingDescriptor()); - setEnginePreferences(EMFComparePreferences.CONFLICTS_DETECTOR, conflictsDetectorData - .getCurrentSelection(), EMFCompareRCPPlugin.getDefault() - .getConflictDetectorDescriptorRegistry().getHighestRankingDescriptor()); + setEnginePreferences(EMFComparePreferences.DIFF_ENGINES, diffEngineData.getData(), Collections + .singleton(EMFCompareRCPPlugin.getDefault().getDiffEngineDescriptorRegistry() + .getHighestRankingDescriptor())); + setEnginePreferences(EMFComparePreferences.EQUI_ENGINES, equiEngineData.getData(), Collections + .singleton(EMFCompareRCPPlugin.getDefault().getEquiEngineDescriptorRegistry() + .getHighestRankingDescriptor())); + setEnginePreferences(EMFComparePreferences.REQ_ENGINES, reqEngineData.getData(), Collections + .singleton(EMFCompareRCPPlugin.getDefault().getReqEngineDescriptorRegistry() + .getHighestRankingDescriptor())); + setEnginePreferences(EMFComparePreferences.CONFLICTS_DETECTOR, conflictsDetectorData.getData(), + Collections.singleton(EMFCompareRCPPlugin.getDefault() + .getConflictDetectorDescriptorRegistry().getHighestRankingDescriptor())); // Set match engine to disable Set<IItemDescriptor<Factory>> matchEngineRegsitry = Sets.newHashSet(EMFCompareRCPPlugin.getDefault() .getMatchEngineFactoryDescriptorRegistry().getItemDescriptors()); Set<IItemDescriptor<Factory>> matchingEngineToDisable = Sets.difference(matchEngineRegsitry, - matchEnginesData.getCurrentSelection()); + matchEnginesData.getData()); setEnginePreferences(EMFComparePreferences.MATCH_ENGINE_DISABLE_ENGINES, matchingEngineToDisable, - new ArrayList<IItemDescriptor<IMatchEngine.Factory>>()); + Collections.<IItemDescriptor<Factory>> emptyList()); } /** @@ -632,13 +430,13 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP * @param preferenceKey */ private <T> void resetDefaultPreferencesToHighestRank(IItemRegistry<T> registry, String preferenceKey, - SingleValueHolder<T> dataObject) { + DataHolder<T> dataObject) { InteractiveUIContent interactiveContent = interactiveUis.get(preferenceKey); if (interactiveContent != null) { IItemDescriptor<T> defaultEngine = registry.getHighestRankingDescriptor(); interactiveContent.select(defaultEngine); interactiveContent.checkElement(defaultEngine); - dataObject.setCurrentSelection(defaultEngine); + dataObject.setData(Collections.singleton(defaultEngine)); } } @@ -650,7 +448,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP * @param dataObject */ private <T> void resetDefaultPreferencesToAll(IItemRegistry<T> registry, String preferenceKey, - MultipleValueHolder<T> dataObject) { + DataHolder<T> dataObject) { InteractiveUIContent interactiveContent = interactiveUis.get(preferenceKey); if (interactiveContent != null) { IItemDescriptor<T> defaultEngine = registry.getHighestRankingDescriptor(); @@ -658,23 +456,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP List<IItemDescriptor<T>> itemDescriptors = registry.getItemDescriptors(); interactiveContent.checkElements(itemDescriptors.toArray(new IItemDescriptor[itemDescriptors .size()])); - dataObject.setCurrentSelection(Sets.newHashSet(itemDescriptors)); - } - } - - /** - * Set an engine preferences into the preferences. - * - * @param preferenceKey - * @param currentSelectedEngine - * @param defaultConf - */ - private <T> void setEnginePreferences(String preferenceKey, IItemDescriptor<T> currentSelectedEngine, - IItemDescriptor<T> defaultConf) { - if (currentSelectedEngine != null && !currentSelectedEngine.equals(defaultConf)) { - getPreferenceStore().setValue(preferenceKey, currentSelectedEngine.getID()); - } else { - getPreferenceStore().setToDefault(preferenceKey); + dataObject.setData(Sets.newHashSet(itemDescriptors)); } } @@ -693,7 +475,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP IItemDescriptor<T> iItemDescriptor = iterator.next(); descriptorsKey.append(iItemDescriptor.getID()); if (iterator.hasNext()) { - descriptorsKey.append(ItemUtil.PREFFERENCE_DELIMITER); + descriptorsKey.append(ItemUtil.PREFERENCE_DELIMITER); } } getPreferenceStore().setValue(preferenceKey, descriptorsKey.toString()); @@ -702,249 +484,4 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP } } - /** - * Label provider for {@link ILabeledItemDescriptor} - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private static final class EngineDescriptorLabelProvider extends LabelProvider { - /** - * {@inheritDoc} - */ - @Override - public String getText(Object element) { - if (element instanceof IItemDescriptor<?>) { - IItemDescriptor<?> desc = (IItemDescriptor<?>)element; - return desc.getLabel(); - } - return super.getText(element); - } - } - - /** - * Data object use to store a simple value data - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private static class SingleValueHolder<T> { - - /** Current value */ - public IItemDescriptor<T> currentSelection; - - public IItemDescriptor<T> getCurrentSelection() { - return currentSelection; - } - - public void setCurrentSelection(IItemDescriptor<T> currentSelection) { - this.currentSelection = currentSelection; - } - - } - - /** - * Data object use to store multiple values data - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - * @param <T> - */ - private class MultipleValueHolder<T> { - - private static final String DATA_FIELD_NAME = "currentSelection"; //$NON-NLS-1$ - - public Set<IItemDescriptor<T>> currentSelection = new HashSet<IItemDescriptor<T>>(); - - public Set<IItemDescriptor<T>> getCurrentSelection() { - return currentSelection; - } - - public void setCurrentSelection(Set<IItemDescriptor<T>> currentSelection) { - this.currentSelection = currentSelection; - } - } - - /** - * Structure that handle UI interactive content (Description, configuration and viewer). - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private static class InteractiveUIContent { - /** Text that shall be update with the description of the viewer. */ - private final Text descriptionText; - - /** Composite holding the viewer. */ - private final Composite viewerCompsite; - - /** - * Composite holding the configuration. This shall react to a selection in the viewer. - */ - private final Composite configurationComposite; - - /** Composite that is used when the selection has no registered configuration. */ - private final Composite defaultComposite; - - /** Viewer of {@link IItemDescriptor}. */ - private CheckboxTableViewer viewer; - - /** List of all {@link AbstractConfigurationUI} that is linked to this viewer. */ - private final Map<String, AbstractConfigurationUI> configurators = new HashMap<String, AbstractConfigurationUI>(); - - /** - * Constructor. - * - * @param descriptionText - * {@link InteractiveUIContent#descriptionText} - * @param viewerCompsite - * {@link InteractiveUIContent#viewerCompsite} - * @param configurationComposite - * {@link InteractiveUIContent#configurationComposite} - */ - public InteractiveUIContent(Text descriptionText, Composite viewerCompsite, - Composite configurationComposite) { - super(); - this.descriptionText = descriptionText; - this.viewerCompsite = viewerCompsite; - this.configurationComposite = configurationComposite; - // Init default composite. - defaultComposite = new Composite(configurationComposite, SWT.NONE); - defaultComposite.setLayout(new GridLayout(1, true)); - Label text = new Label(defaultComposite, SWT.WRAP); - text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1)); - text.setText(EMFCompareRCPUIMessages - .getString("InteractiveUIContent.DEFAULT_CONFIGURATION_LABEL")); //$NON-NLS-1$ - } - - /** - * Add a configuration to this Interactive content. - * - * @param id - * Id of the item to configure - * @param configuratorfactory - * Factory for the configuration - */ - public void addConfigurator(String id, IConfigurationUIFactory configuratorfactory, Preferences pref) { - AbstractConfigurationUI configurator = configuratorfactory.createUI(configurationComposite, - SWT.NONE, pref); - configurators.put(id, configurator); - } - - /** - * Check one element in the viewer - * - * @param descriptor - */ - public void checkElement(IItemDescriptor<?> descriptor) { - viewer.setCheckedElements(new Object[] {descriptor }); - } - - /** - * Check multiple element in the viewer. (Only use if multiple selection is allowed) - * - * @param descriptors - */ - public void checkElements(IItemDescriptor<?>[] descriptors) { - viewer.setCheckedElements(descriptors); - } - - /** - * @param viewer - * A {@link StructuredViewer} of {@link IItemDescriptor} - */ - public void setViewer(CheckboxTableViewer inputViewer) { - this.viewer = inputViewer; - viewer.addSelectionChangedListener(new ConfigurationListener()); - viewer.addSelectionChangedListener(new DescriptionListener()); - } - - /** - * @return A map of all configuration. - */ - public Map<String, AbstractConfigurationUI> getConfigurators() { - return ImmutableMap.copyOf(configurators); - } - - /** - * Handle a selection in the viewer. Update related components. - * - * @param descriptor - */ - public void select(IItemDescriptor<?> descriptor) { - // Update viewer - viewer.setSelection(new StructuredSelection(descriptor), true); - updateLinkedElements(descriptor); - } - - /** - * Update linked element in - * - * @param descriptor - */ - private void updateLinkedElements(IItemDescriptor<?> descriptor) { - // Update description - descriptionText.setText(descriptor.getDescription()); - - StackLayout stackLayout = (StackLayout)configurationComposite.getLayout(); - if (configurators.containsKey(descriptor.getID())) { - stackLayout.topControl = configurators.get(descriptor.getID()); - } else { - stackLayout.topControl = defaultComposite; - } - configurationComposite.layout(); - } - - /** - * @return The composite holding the viewer. - */ - public Composite getViewerComposite() { - return viewerCompsite; - } - - /** - * @return The viewer. - */ - public CheckboxTableViewer getViewer() { - return viewer; - } - - /** - * Listener in charge of updating the the configuration composite. - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private final class ConfigurationListener implements ISelectionChangedListener { - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection structSelection = (IStructuredSelection)selection; - Object selected = structSelection.getFirstElement(); - if (selected instanceof IItemDescriptor<?>) { - updateLinkedElements(((IItemDescriptor<?>)selected)); - } - } - } - } - - /** - * Listener to update description text - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private final class DescriptionListener implements ISelectionChangedListener { - - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - IStructuredSelection structSelection = (IStructuredSelection)selection; - Object selected = structSelection.getFirstElement(); - if (selected instanceof IItemDescriptor<?>) { - IItemDescriptor<?> desc = (IItemDescriptor<?>)selected; - String description = desc.getDescription(); - descriptionText.setText(description); - } - } - - } - } - - } - } diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/InteractiveUIContent.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/InteractiveUIContent.java new file mode 100644 index 000000000..ad4a6ea19 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/InteractiveUIContent.java @@ -0,0 +1,616 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.PojoProperties; +import org.eclipse.core.databinding.observable.set.IObservableSet; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.AbstractConfigurationUI; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.IConfigurationUIFactory; +import org.eclipse.jface.databinding.viewers.IViewerObservableSet; +import org.eclipse.jface.databinding.viewers.ViewersObservables; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.osgi.service.prefs.Preferences; + +/** + * A User interface that holds a viewer and satellites elements. + * <p> + * This viewer can have a satellite configuration composite reacting on selection. It displays a configuration + * UI for the current selection. It's requires a configuration UI registry. + * </p> + * <p> + * This viewer can have a satellite text field holding the description of the current selection. This field + * display the description for the current element. + * </p> + * <p> + * This class allows a user to select and check elements. + * </p> + * <p> + * It can also synchronize the state of checked element into a {@link DataHolder} + * </p> + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class InteractiveUIContent { + + /** Text that will be updated with the description of the viewer. */ + private final Text descriptionText; + + /** Composite holding the viewer. */ + private final Composite viewerCompsite; + + /** Composite holding the configuration. This will react to the selection in the viewer. */ + private final Composite configurationComposite; + + /** Composite that is used when the selection has no registered configuration. */ + private final Composite defaultComposite; + + /** Viewer of {@link IItemDescriptor}. */ + private CheckboxTableViewer viewer; + + /** List of all {@link AbstractConfigurationUI} that are linked to this viewer. */ + private final Map<String, AbstractConfigurationUI> configurators = new HashMap<String, AbstractConfigurationUI>(); + + private InteractiveUIContent(Composite parent, boolean hasDescription, boolean hasConfiguration) { + super(); + Composite contentComposite = new Composite(parent, SWT.NONE); + final int numberOfColumns; + if (hasConfiguration) { + numberOfColumns = 2; + } else { + numberOfColumns = 1; + } + contentComposite.setLayout(new GridLayout(numberOfColumns, true)); + contentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + // Engine chooser composite + this.viewerCompsite = new Composite(contentComposite, SWT.NONE); + viewerCompsite.setLayout(new GridLayout(1, true)); + viewerCompsite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + if (hasConfiguration) { + // Config composite + this.configurationComposite = createConfigComposite(contentComposite); + // Init default composite. + defaultComposite = new Composite(configurationComposite, SWT.NONE); + defaultComposite.setLayout(new GridLayout(1, true)); + Label text = new Label(defaultComposite, SWT.WRAP); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1)); + text.setText(EMFCompareRCPUIMessages + .getString("InteractiveUIContent.DEFAULT_CONFIGURATION_LABEL")); //$NON-NLS-1$ + } else { + this.configurationComposite = null; + this.defaultComposite = null; + } + if (hasDescription) { + // Descriptor engine Text + this.descriptionText = createDescriptionComposite(parent); + } else { + this.descriptionText = null; + } + } + + /** + * Add a configuration to this Interactive content. + * + * @param id + * Id of the item to configure + * @param configuratorfactory + * Factory for the configuration + */ + public void addConfigurator(String id, IConfigurationUIFactory configuratorfactory, Preferences pref) { + AbstractConfigurationUI configurator = configuratorfactory.createUI(configurationComposite, SWT.NONE, + pref); + configurators.put(id, configurator); + } + + /** + * Check one element in the viewer + * + * @param descriptor + */ + public void checkElement(IItemDescriptor<?> descriptor) { + viewer.setCheckedElements(new Object[] {descriptor }); + } + + /** + * Check multiple element in the viewer. (Only use if multiple selection is allowed) + * + * @param descriptors + */ + public void checkElements(IItemDescriptor<?>[] descriptors) { + viewer.setCheckedElements(descriptors); + } + + /** + * Create the composite that will hold all configurations for a tab. + * + * @param composite + * @return + */ + private Group createConfigComposite(Composite composite) { + Group confComposite = new Group(composite, SWT.BORDER); + confComposite.setText(EMFCompareRCPUIMessages + .getString("InteractiveUIContent.CONFIGURATION_COMPOSITE_LABEL")); //$NON-NLS-1$ + StackLayout layout = new StackLayout(); + layout.marginHeight = 10; + layout.marginWidth = 10; + confComposite.setLayout(layout); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + confComposite.setLayoutData(layoutData); + return confComposite; + } + + /** + * Composite for description. This composite hold the text widget that will update with the current + * selection + * + * @param composite + * @return + */ + private Text createDescriptionComposite(Composite composite) { + Group descriptionComposite = new Group(composite, SWT.BORDER); + descriptionComposite.setText(EMFCompareRCPUIMessages + .getString("InteractiveUIContent.DESCRIPTION_COMPOSITE_LABEL")); //$NON-NLS-1$ + descriptionComposite.setLayout(new GridLayout(1, false)); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + Text engineDescriptionText = new Text(descriptionComposite, SWT.WRAP | SWT.MULTI); + engineDescriptionText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1); + layoutData.heightHint = 50; + engineDescriptionText.setLayoutData(layoutData); + engineDescriptionText.setEditable(false); + return engineDescriptionText; + } + + /** + * @return A map of all configuration. + */ + public Map<String, AbstractConfigurationUI> getConfigurators() { + return ImmutableMap.copyOf(configurators); + } + + /** + * @return The viewer. + */ + private CheckboxTableViewer getViewer() { + return viewer; + } + + /** + * @return The composite holding the viewer. + */ + private Composite getViewerComposite() { + return viewerCompsite; + } + + /** + * Handle a selection in the viewer. Update related components. + * + * @param descriptor + */ + public void select(IItemDescriptor<?> descriptor) { + // Update viewer + viewer.setSelection(new StructuredSelection(descriptor), true); + updateLinkedElements(descriptor); + } + + /** + * @param viewer + * A {@link StructuredViewer} of {@link IItemDescriptor} + */ + public void setViewer(CheckboxTableViewer inputViewer) { + this.viewer = inputViewer; + if (configurationComposite != null) { + viewer.addSelectionChangedListener(new ConfigurationListener()); + } + viewer.addSelectionChangedListener(new DescriptionListener()); + } + + /** + * Update linked element in + * + * @param descriptor + */ + private void updateLinkedElements(IItemDescriptor<?> descriptor) { + // Update description + descriptionText.setText(descriptor.getDescription()); + if (configurationComposite != null) { + updateConfigurationComposite(descriptor); + } + } + + private void updateConfigurationComposite(IItemDescriptor<?> descriptor) { + StackLayout stackLayout = (StackLayout)configurationComposite.getLayout(); + if (configurators.containsKey(descriptor.getID())) { + stackLayout.topControl = configurators.get(descriptor.getID()); + } else { + stackLayout.topControl = defaultComposite; + } + configurationComposite.layout(); + } + + /** + * This listener updates the Data Holder and for that only one element can be checked at a time. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + * @param <T> + */ + private static final class SingleCheckListener<T> implements ICheckStateListener { + private final DataHolder<T> dataObject; + + private final CheckboxTableViewer descriptorViewer; + + private final Shell shell; + + private SingleCheckListener(DataHolder<T> dataObject, CheckboxTableViewer descriptorViewer, + Shell shell) { + this.dataObject = dataObject; + this.descriptorViewer = descriptorViewer; + this.shell = shell; + } + + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (event.getChecked()) { + if (element instanceof IItemDescriptor<?>) { + @SuppressWarnings("unchecked") + IItemDescriptor<T> descriptor = (IItemDescriptor<T>)element; + dataObject.setData(Collections.singleton(descriptor)); + } + descriptorViewer.setCheckedElements(new Object[] {element }); + } else { + // Prevent from nothing checked + if (descriptorViewer.getCheckedElements().length == 0) { + descriptorViewer.setCheckedElements(new Object[] {element }); + MessageDialog.openWarning(shell, EMFCompareRCPUIMessages + .getString("InteractiveUIContent.INCORRECT_SELECTION_TITLE"), //$NON-NLS-1$ + EMFCompareRCPUIMessages + .getString("InteractiveUIContent.INCORRECT_SELECTION_MESSAGE")); //$NON-NLS-1$ + } + } + + } + } + + /** + * Listener in charge of updating the configuration composite. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ + private final class ConfigurationListener implements ISelectionChangedListener { + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structSelection = (IStructuredSelection)selection; + Object selected = structSelection.getFirstElement(); + if (selected instanceof IItemDescriptor<?>) { + updateLinkedElements(((IItemDescriptor<?>)selected)); + } + } + } + } + + /** + * Listener to update description text + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ + private final class DescriptionListener implements ISelectionChangedListener { + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structSelection = (IStructuredSelection)selection; + Object selected = structSelection.getFirstElement(); + if (selected instanceof IItemDescriptor<?>) { + IItemDescriptor<?> desc = (IItemDescriptor<?>)selected; + String description = desc.getDescription(); + descriptionText.setText(description); + } + } + + } + } + + /** + * Label provider for {@link ILabeledItemDescriptor} + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ + private static final class EngineDescriptorLabelProvider extends LabelProvider { + /** + * {@inheritDoc} + */ + @Override + public String getText(Object element) { + if (element instanceof IItemDescriptor<?>) { + IItemDescriptor<?> desc = (IItemDescriptor<?>)element; + return desc.getLabel(); + } + return super.getText(element); + } + } + + /** + * Builder for an Interactive UI. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + * @param <T> + * type of item in the viewer. + */ + public static class InteractiveUIBuilder<T> { + + /** Holding composite of all the structure. */ + private Composite parent; + + /** Item registry holding input of the viewer. */ + private IItemRegistry<T> registry; + + /** Key of the preference node where the configuration for an item is stored. */ + private String configurationNodeKey; + + /** Configuration UI registry. */ + private Map<String, IConfigurationUIFactory> configurationUIRegistry; + + /** Set of elements to check by default. */ + private Set<IItemDescriptor<T>> defaultCheck = null; + + /** Element to select by default. */ + private IItemDescriptor<T> defaultSelection = null; + + /** Object holding data representing the current status of the interactive content. */ + private DataHolder<T> dataHolder; + + /** Set to true if the interactive content has a description field. */ + private boolean hasDescription = true; + + /** Set to true if this interactive content is synchronized with only one element at a time. */ + private boolean isSimple = false; + + /** + * Constructor. + * + * @param parent + * Holding composite of all the structure. + * @param registry + * Item registry holding input of the viewer. + * @param dataHolder + * Object holding data representing the current status of the interactive content. + */ + public InteractiveUIBuilder(Composite parent, IItemRegistry<T> registry) { + super(); + this.parent = parent; + this.registry = registry; + } + + /** + * Set a dataHolder that will be synchronized with the checked element. If this isSimple then + * {@link DataHolder#simpleData} is filled. else {@link DataHolder#data} is filled + * + * @param dataHolder + * @return + */ + public InteractiveUIBuilder<T> setHoldingData(DataHolder<T> dataHolder) { + this.dataHolder = dataHolder; + return this; + } + + /** + * Key of the node to get the {@link Preferences} to retrieve {@link IConfigurationUIFactory}. See + * {@link ItemUtil#getConfigurationPreferenceNode(String, String)} (needed is ConfigurationUIRegistry + * is provided) + * + * @param key + * @return + */ + public InteractiveUIBuilder<T> setConfigurationNodeKey(String key) { + this.configurationNodeKey = key; + return this; + } + + /** + * Registry of of {@link IConfigurationUIFactory} to filled the configuraiton composite. + * + * @param configuratorUIRegistry + * @return + */ + public InteractiveUIBuilder<T> setConfiguratorUIRegistry( + Map<String, IConfigurationUIFactory> configuratorUIRegistry) { + this.configurationUIRegistry = configuratorUIRegistry; + return this; + } + + /** + * Set the default element to check. (A singleton is this is set to simple + * {@link InteractiveUIBuilder#setSimple(boolean)} + * + * @param defaultCheck + * @return + */ + public InteractiveUIBuilder<T> setDefaultCheck(Set<IItemDescriptor<T>> defaultCheck) { + this.defaultCheck = defaultCheck; + return this; + } + + /** + * Set the default element to select. + * + * @param defaultSelection + * @return + */ + public InteractiveUIBuilder<T> setDefaultSelection(IItemDescriptor<T> defaultSelection) { + this.defaultSelection = defaultSelection; + return this; + } + + /** + * Set to true if this need to create a description field. + * + * @param hasDescription + * @return + */ + public InteractiveUIBuilder<T> setHasDescription(boolean hasDescription) { + this.hasDescription = hasDescription; + return this; + } + + /** + * Set to true if the viewer can only have only one element check at a time. + * + * @param isSimple + * @return + */ + public InteractiveUIBuilder<T> setSimple(boolean isSimple) { + this.isSimple = isSimple; + return this; + } + + /** + * Build a new {@link InteractiveUI} + * + * @return + */ + public InteractiveUIContent build() { + // If simple only one element check at a time + Preconditions.checkArgument(!isSimple || defaultCheck == null || defaultCheck.size() == 1); + + boolean hasConfiguration = configurationUIRegistry != null; + // If has a configuration composite then the key to retrieve the preference must be set up. + Preconditions.checkArgument(!hasConfiguration || configurationNodeKey != null); + + final InteractiveUIContent interactiveUI = new InteractiveUIContent(parent, hasDescription, + hasConfiguration); + + CheckboxTableViewer descriptorViewer = createViewer(interactiveUI); + + if (hasConfiguration) { + createConfigurationComposite(interactiveUI); + } + setViewerInput(descriptorViewer); + // Init and bind data + bindAndInit(interactiveUI, descriptorViewer); + return interactiveUI; + } + + private CheckboxTableViewer createViewer(final InteractiveUIContent interactiveUI) { + int style = SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION; + if (isSimple) { + style = style | SWT.SINGLE; + } + CheckboxTableViewer descriptorViewer = CheckboxTableViewer.newCheckList(interactiveUI + .getViewerComposite(), style); + interactiveUI.setViewer(descriptorViewer); + descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); + descriptorViewer.setLabelProvider(new EngineDescriptorLabelProvider()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + descriptorViewer.getControl().setLayoutData(gd); + return descriptorViewer; + } + + private void createConfigurationComposite(final InteractiveUIContent interactiveUI) { + // Init configuration elements + for (IItemDescriptor<T> item : registry.getItemDescriptors()) { + String itemId = item.getID(); + IConfigurationUIFactory configuratorFactory = configurationUIRegistry.get(itemId); + if (configuratorFactory != null) { + Preferences pref = ItemUtil.getConfigurationPreferenceNode(configurationNodeKey, itemId); + interactiveUI.addConfigurator(itemId, configuratorFactory, pref); + } + } + } + + private void bindAndInit(final InteractiveUIContent interactiveUI, + CheckboxTableViewer descriptorViewer) { + if (defaultSelection != null) { + interactiveUI.select(defaultSelection); + } + if (isSimple) { + if (defaultCheck != null) { + IItemDescriptor<T> defaultCheckedElement = defaultCheck.iterator().next(); + interactiveUI.checkElement(defaultCheckedElement); + if (dataHolder != null) { + dataHolder.setData(Collections.singleton(defaultCheckedElement)); + } + } + descriptorViewer.addCheckStateListener(new SingleCheckListener<T>(dataHolder, + descriptorViewer, Display.getDefault().getActiveShell())); + } else { + if (dataHolder != null) { + if (defaultCheck != null) { + dataHolder.setData(defaultCheck); + } + // Bind data + bindMultipleData(DataHolder.DATA_FIELD_NAME, interactiveUI.getViewer(), dataHolder); + } + } + } + + private void setViewerInput(CheckboxTableViewer descriptorViewer) { + List<IItemDescriptor<T>> itemDescriptors = registry.getItemDescriptors(); + Collections.sort(itemDescriptors, Collections.reverseOrder()); + descriptorViewer.setInput(itemDescriptors); + } + + /** + * Bind UI to data object. + * + * @param engineBindingProperty + * @param descriptorViewer + * @param dataObject + */ + private void bindMultipleData(String engineBindingProperty, CheckboxTableViewer descriptorViewer, + final DataHolder<T> dataObject) { + DataBindingContext ctx = new DataBindingContext(); + // Bind the button with the corresponding field in data + IViewerObservableSet target = ViewersObservables.observeCheckedElements(descriptorViewer, + IItemDescriptor.class); + IObservableSet model = PojoProperties.set(DataHolder.class, engineBindingProperty).observe( + dataObject); + + ctx.bindSet(target, model); + } + + } + +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java new file mode 100644 index 000000000..878a81848 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import java.util.Set; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.postprocessor.IPostProcessor; +import org.eclipse.emf.compare.postprocessor.IPostProcessor.Descriptor; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; +import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences; +import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.InteractiveUIContent.InteractiveUIBuilder; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Preference page used to enable/disable post processor. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class PostProcessorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** Data holder. */ + private DataHolder<IPostProcessor.Descriptor> dataHolder = new DataHolder<IPostProcessor.Descriptor>(); + + /** {@link InteractiveUIContent} */ + private InteractiveUIContent interactiveUI = null; + + public PostProcessorPreferencePage() { + super(); + } + + public PostProcessorPreferencePage(String title, ImageDescriptor image) { + super(title, image); + } + + public PostProcessorPreferencePage(String title) { + super(title); + } + + public void init(IWorkbench workbench) { + // Do not use InstanceScope.Instance to be compatible with Helios. + @SuppressWarnings("deprecation") + ScopedPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(), + EMFCompareRCPPlugin.PLUGIN_ID); + setPreferenceStore(store); + } + + @Override + protected Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + container.setLayout(new GridLayout(1, true)); + Label introductionText = new Label(container, SWT.WRAP); + introductionText.setText(EMFCompareRCPUIMessages + .getString("PostProcessorPreferencePage.PREFERENCE_PAGE_DESCRIPTION")); //$NON-NLS-1$ + + IItemRegistry<IPostProcessor.Descriptor> postProcessorRegistryDescriptor = EMFCompareRCPPlugin + .getDefault().getPostProcessorDescriptorRegistry(); + Set<IItemDescriptor<Descriptor>> activesPostProcessor = ItemUtil.getActiveItems( + postProcessorRegistryDescriptor, EMFComparePreferences.DISABLED_POST_PROCESSOR); + InteractiveUIBuilder<Descriptor> postProcessorUIBuilder = new InteractiveUIBuilder<IPostProcessor.Descriptor>( + container, postProcessorRegistryDescriptor); + Set<IItemDescriptor<Descriptor>> descriptors = Sets.newLinkedHashSet(postProcessorRegistryDescriptor + .getItemDescriptors()); + postProcessorUIBuilder.setConfigurationNodeKey(EMFComparePreferences.DISABLED_POST_PROCESSOR) + .setDefaultCheck(descriptors).setDefaultSelection( + postProcessorRegistryDescriptor.getHighestRankingDescriptor()).setHoldingData( + dataHolder).setDefaultCheck(activesPostProcessor); + interactiveUI = postProcessorUIBuilder.build(); + + return container; + } + + @Override + public boolean performOk() { + Set<IItemDescriptor<Descriptor>> postProcessorDescriptors = Sets.newLinkedHashSet(EMFCompareRCPPlugin + .getDefault().getPostProcessorDescriptorRegistry().getItemDescriptors()); + SetView<IItemDescriptor<Descriptor>> postProcessorToDisable = Sets.difference( + postProcessorDescriptors, dataHolder.getData()); + setEnginePreferences(EMFComparePreferences.DISABLED_POST_PROCESSOR, postProcessorToDisable); + + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder traceMessage = new StringBuilder("Post processor preference serialization:\n"); //$NON-NLS-1$ + String prefDelimiter = " :\n"; //$NON-NLS-1$ + String new_line = "\n"; //$NON-NLS-1$ + traceMessage.append(EMFComparePreferences.DISABLED_POST_PROCESSOR).append(prefDelimiter).append( + getPreferenceStore().getString(EMFComparePreferences.DISABLED_POST_PROCESSOR)).append( + new_line); + EMFCompareRCPPlugin.getDefault().log(IStatus.INFO, traceMessage.toString()); + } + + return super.performOk(); + } + + @Override + protected void performDefaults() { + Set<IItemDescriptor<Descriptor>> descriptors = Sets.newLinkedHashSet(EMFCompareRCPPlugin.getDefault() + .getPostProcessorDescriptorRegistry().getItemDescriptors()); + interactiveUI.checkElements(descriptors.toArray(new IItemDescriptor[descriptors.size()])); + dataHolder.setData(descriptors); + super.performDefaults(); + } + + /** + * Store engines preferences into the preference store. + * + * @param preferenceKey + * Key used in the preference store. + * @param currentSelectedEngines + * Engines to store. + * @param defaultConf + * Default configuration for this type of engines. + */ + private <T> void setEnginePreferences(String preferenceKey, Set<IItemDescriptor<T>> currentSelectedEngines) { + if (currentSelectedEngines != null && currentSelectedEngines.size() > 0) { + Iterable<String> identifiers = Iterables.transform(currentSelectedEngines, + new Function<IItemDescriptor<?>, String>() { + public String apply(IItemDescriptor<?> desc) { + return desc.getID(); + } + }); + String descriptorsKey = Joiner.on(ItemUtil.PREFERENCE_DELIMITER).join(identifiers); + getPreferenceStore().setValue(preferenceKey, descriptorsKey.toString()); + } else { + getPreferenceStore().setToDefault(preferenceKey); + } + } + +} diff --git a/plugins/org.eclipse.emf.compare.rcp/schema/postProcessor.exsd b/plugins/org.eclipse.emf.compare.rcp/schema/postProcessor.exsd index 08b253c0d..f73ba952a 100644 --- a/plugins/org.eclipse.emf.compare.rcp/schema/postProcessor.exsd +++ b/plugins/org.eclipse.emf.compare.rcp/schema/postProcessor.exsd @@ -75,6 +75,20 @@ </documentation> </annotation> </attribute> + <attribute name="label" type="string"> + <annotation> + <documentation> + Label of the post processor. Used for UI. + </documentation> + </annotation> + </attribute> + <attribute name="description" type="string"> + <annotation> + <documentation> + Description of post processor. Used for UI. + </documentation> + </annotation> + </attribute> </complexType> </element> diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/EMFCompareRCPPlugin.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/EMFCompareRCPPlugin.java index 5ea3f0c4b..7d7e53b88 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/EMFCompareRCPPlugin.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/EMFCompareRCPPlugin.java @@ -26,7 +26,6 @@ import org.eclipse.emf.compare.match.eobject.WeightProvider; import org.eclipse.emf.compare.match.eobject.WeightProviderDescriptorRegistryImpl; import org.eclipse.emf.compare.merge.IMerger; import org.eclipse.emf.compare.postprocessor.IPostProcessor; -import org.eclipse.emf.compare.postprocessor.PostProcessorDescriptorRegistryImpl; import org.eclipse.emf.compare.provider.EMFCompareEditPlugin; import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; import org.eclipse.emf.compare.rcp.internal.adapterfactory.AdapterFactoryDescriptorRegistryListener; @@ -40,6 +39,7 @@ import org.eclipse.emf.compare.rcp.internal.merger.MergerExtensionRegistryListen import org.eclipse.emf.compare.rcp.internal.policy.LoadOnDemandPolicyRegistryImpl; import org.eclipse.emf.compare.rcp.internal.policy.LoadOnDemandPolicyRegistryListener; import org.eclipse.emf.compare.rcp.internal.postprocessor.PostProcessorFactoryRegistryListener; +import org.eclipse.emf.compare.rcp.internal.postprocessor.PostProcessorRegistryImpl; import org.eclipse.emf.compare.rcp.policy.ILoadOnDemandPolicy; import org.eclipse.emf.compare.req.IReqEngine; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; @@ -118,6 +118,9 @@ public class EMFCompareRCPPlugin extends Plugin { /** The registry that will hold references to all post processors. */ private IPostProcessor.Descriptor.Registry<String> postProcessorDescriptorsRegistry; + /** The registry that will hold reference to all post processors descriptors. */ + private IItemRegistry<IPostProcessor.Descriptor> postProcessorItemDescriptorsRegistry; + /** The registry listener that will be used to react to post processor changes. */ private AbstractRegistryEventListener postProcessorFactoryRegistryListener; @@ -152,8 +155,12 @@ public class EMFCompareRCPPlugin extends Plugin { private WeightProviderDescriptorRegistryListener weightProviderListener; /** - * Instance scope for preferences. Do not use singleton to respect Helios compatibility. See - * {@link InstanceScope} + * Instance scope for preferences. + * <p> + * Do not use singleton to respect Helios compatibility + * </p> + * + * @see org.eclipse.core.runtime.preferences.InstanceScope#INSTANCE */ @SuppressWarnings("deprecation") private InstanceScope instanceScope = new InstanceScope(); @@ -241,11 +248,14 @@ public class EMFCompareRCPPlugin extends Plugin { * {@link IExtensionRegistry} to listen in order to fill the registry */ private void setUpPostProcessorRegisty(final IExtensionRegistry registry) { - postProcessorDescriptorsRegistry = new PostProcessorDescriptorRegistryImpl<String>(); + postProcessorItemDescriptorsRegistry = new ItemRegistry<IPostProcessor.Descriptor>(); + postProcessorFactoryRegistryListener = new PostProcessorFactoryRegistryListener(PLUGIN_ID, - POST_PROCESSOR_PPID, getLog(), postProcessorDescriptorsRegistry); + POST_PROCESSOR_PPID, getLog(), postProcessorItemDescriptorsRegistry); registry.addListener(postProcessorFactoryRegistryListener, PLUGIN_ID + '.' + POST_PROCESSOR_PPID); postProcessorFactoryRegistryListener.readRegistry(registry); + postProcessorDescriptorsRegistry = new PostProcessorRegistryImpl( + postProcessorItemDescriptorsRegistry); } /** @@ -472,6 +482,7 @@ public class EMFCompareRCPPlugin extends Plugin { registry.removeListener(postProcessorFactoryRegistryListener); postProcessorFactoryRegistryListener = null; postProcessorDescriptorsRegistry = null; + postProcessorItemDescriptorsRegistry = null; } /** @@ -516,6 +527,16 @@ public class EMFCompareRCPPlugin extends Plugin { } /** + * Get the {@link IItemRegistry} of {@link IPostProcessor.Descriptor}. + * + * @return {@link IItemRegistry} of {@link IPostProcessor.Descriptor}. + * @since 2.2.0 + */ + public IItemRegistry<IPostProcessor.Descriptor> getPostProcessorDescriptorRegistry() { + return postProcessorItemDescriptorsRegistry; + } + + /** * Returns the registry of load on demand policies. * * @return the registry of load on demand policies. diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/DescriptorRegistryEventListener.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/DescriptorRegistryEventListener.java index a66edbbc1..e5aa9bcb4 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/DescriptorRegistryEventListener.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/DescriptorRegistryEventListener.java @@ -128,7 +128,7 @@ public class DescriptorRegistryEventListener<T> extends AbstractRegistryEventLis String label = element.getAttribute(DescriptorRegistryEventListener.LABEL_DESCRIPTOR_ATTR); String description = element.getAttribute(DESCRITPION_DESCRIPTOR_ATTR); String id = element.getAttribute(ID_DESCRIPTOR_ATTR); - ItemDescriptor<T> descriptor = new ItemDescriptor<T>(label, description, rank, element, id); + LazyItemDescriptor<T> descriptor = new LazyItemDescriptor<T>(label, description, rank, element, id); IItemDescriptor<T> previous = registry.add(descriptor); if (previous != null) { log(IStatus.WARNING, element, EMFCompareRCPMessages.getString( diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemUtil.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemUtil.java index 1d8507e3d..63c7493d8 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemUtil.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemUtil.java @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.emf.compare.rcp.internal.extension.impl; +import com.google.common.collect.Sets; + import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; @@ -27,7 +30,7 @@ import org.osgi.service.prefs.Preferences; public final class ItemUtil { /** Delimiter character used to serialize a list into preferences. */ - public static final String PREFFERENCE_DELIMITER = ";"; //$NON-NLS-1$ + public static final String PREFERENCE_DELIMITER = ";"; //$NON-NLS-1$ /** * Private Constructor. @@ -128,7 +131,7 @@ public final class ItemUtil { String diffEngineKey = itemPreferences.get(preferenceKey, null); List<IItemDescriptor<T>> result = null; if (diffEngineKey != null) { - String[] diffEngineKeys = diffEngineKey.split(PREFFERENCE_DELIMITER); + String[] diffEngineKeys = diffEngineKey.split(PREFERENCE_DELIMITER); for (String nonTrimedKey : diffEngineKeys) { String key = nonTrimedKey.trim(); IItemDescriptor<T> descritpor = registry.getItemDescriptor(key); @@ -156,4 +159,33 @@ public final class ItemUtil { public static Preferences getConfigurationPreferenceNode(String type, String itemId) { return EMFCompareRCPPlugin.getDefault().getEMFComparePreferences().node(type).node(itemId); } + + /** + * Get all active item from a registry. + * <p> + * (Filter out all disable element stored in preferences) + * </p> + * + * @param registry + * Registry holding all items of this kind + * @param disabledItemPreferenceKey + * Preference key where are stored disabled items. + * @return {@link Set} of active items + * @param <T> + * Item type + */ + public static <T> Set<IItemDescriptor<T>> getActiveItems(IItemRegistry<T> registry, + String disabledItemPreferenceKey) { + List<IItemDescriptor<T>> itemsDescriptor = ItemUtil.getItemsDescriptor(registry, + disabledItemPreferenceKey, EMFCompareRCPPlugin.getDefault().getEMFComparePreferences()); + + if (itemsDescriptor == null) { + return Sets.newLinkedHashSet(registry.getItemDescriptors()); + } + Set<IItemDescriptor<T>> disableFactories = Sets.newHashSet(itemsDescriptor); + Set<IItemDescriptor<T>> allFactories = Sets.newHashSet(registry.getItemDescriptors()); + Set<IItemDescriptor<T>> activeFactory = Sets.difference(allFactories, disableFactories); + + return activeFactory; + } } diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemDescriptor.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/LazyItemDescriptor.java index 82c98ad4f..d95e40734 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/ItemDescriptor.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/LazyItemDescriptor.java @@ -22,32 +22,33 @@ import org.eclipse.core.runtime.IConfigurationElement; * @param <T> * an item type */ -public class ItemDescriptor<T> extends AbstractItemDescriptor<T> { +public class LazyItemDescriptor<T> extends AbstractItemDescriptor<T> { - /** IConfig element of the item. */ + /** {@link IConfigurationElement} used to instantiate the item. */ private final IConfigurationElement config; /** * Constructor. * * @param label - * {@link ItemDescriptor#label} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getLabel()} * @param description - * {@link ItemDescriptor#description} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getDescription()} * @param rank - * {@link ItemDescriptor#rank} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getRank()} * @param config - * {@link ItemDescriptor#config} + * {@link IConfigurationElement} used to instantiate the item. * @param id - * {@link ItemDescriptor#id} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getID()} */ - public ItemDescriptor(String label, String description, int rank, IConfigurationElement config, String id) { + public LazyItemDescriptor(String label, String description, int rank, IConfigurationElement config, + String id) { super(label, description, rank, id); this.config = config; } /** - * {@link ItemDescriptor#config}. + * {@link IConfigurationElement} used to instantiate the item. * * @return IConfigurationElement. */ diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/FactoryDescriptor.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/WrapperItemDescriptor.java index 10954af5d..d474187b5 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/FactoryDescriptor.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/extension/impl/WrapperItemDescriptor.java @@ -10,14 +10,16 @@ *******************************************************************************/ package org.eclipse.emf.compare.rcp.internal.extension.impl; + /** - * IItemDescriptor used for factories. The will be only one instance of each item. + * A {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor} that wrap one instance of an item + * and return the same item each time. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> * @param <T> * On factory */ -public class FactoryDescriptor<T> extends AbstractItemDescriptor<T> { +public class WrapperItemDescriptor<T> extends AbstractItemDescriptor<T> { /** Instance of a factory. */ private T instance; @@ -26,17 +28,17 @@ public class FactoryDescriptor<T> extends AbstractItemDescriptor<T> { * Constructor. * * @param label - * {@link ItemDescriptor#label} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getLabel()} * @param description - * {@link ItemDescriptor#description} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getDescription()} * @param rank - * {@link ItemDescriptor#rank} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getRank()} * @param id - * {@link ItemDescriptor#id} + * {@link org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor<T>#getID()} * @param instance * Instance of the factory */ - public FactoryDescriptor(String label, String description, int rank, String id, T instance) { + public WrapperItemDescriptor(String label, String description, int rank, String id, T instance) { super(label, description, rank, id); this.instance = instance; } diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryDescriptor.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryDescriptor.java index 2f4ceb637..ca0a9daf2 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryDescriptor.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryDescriptor.java @@ -17,8 +17,8 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.emf.compare.match.IMatchEngine;
import org.eclipse.emf.compare.match.IMatchEngine.Factory;
import org.eclipse.emf.compare.rcp.internal.extension.IConfigurableItem;
-import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemDescriptor;
import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.LazyItemDescriptor;
import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences;
import org.osgi.service.prefs.Preferences;
@@ -27,21 +27,21 @@ import org.osgi.service.prefs.Preferences; *
* @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
*/
-public class MatchEngineFactoryDescriptor extends ItemDescriptor<IMatchEngine.Factory> {
+public class MatchEngineFactoryDescriptor extends LazyItemDescriptor<IMatchEngine.Factory> {
/**
* Constructor.
*
* @param label
- * {@link ItemDescriptor#getLabel()}
+ * {@link LazyItemDescriptor#getLabel()}
* @param description
- * {@link ItemDescriptor#getDescription()}
+ * {@link LazyItemDescriptor#getDescription()}
* @param rank
- * {@link ItemDescriptor#getRank()}
+ * {@link LazyItemDescriptor#getRank()}
* @param config
* {@link IConfigurableItem} element used to create this item.
* @param id
- * {@link ItemDescriptor#getID()}
+ * {@link LazyItemDescriptor#getID()}
*/
public MatchEngineFactoryDescriptor(String label, String description, int rank,
IConfigurationElement config, String id) {
diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryRegistryWrapper.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryRegistryWrapper.java index 80b16e1bc..10a7bdc07 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryRegistryWrapper.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/match/MatchEngineFactoryRegistryWrapper.java @@ -30,8 +30,8 @@ import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; import org.eclipse.emf.compare.rcp.internal.extension.impl.AbstractItemDescriptor; -import org.eclipse.emf.compare.rcp.internal.extension.impl.FactoryDescriptor; import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; +import org.eclipse.emf.compare.rcp.internal.extension.impl.WrapperItemDescriptor; import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences; import org.eclipse.emf.compare.scope.IComparisonScope; @@ -129,7 +129,7 @@ public class MatchEngineFactoryRegistryWrapper implements IMatchEngine.Factory.R */ public IMatchEngine.Factory add(IMatchEngine.Factory filter) { Preconditions.checkNotNull(filter); - IItemDescriptor<Factory> factory = registry.add(new FactoryDescriptor<IMatchEngine.Factory>( + IItemDescriptor<Factory> factory = registry.add(new WrapperItemDescriptor<IMatchEngine.Factory>( EMPTY_STRING, EMPTY_STRING, filter.getRanking(), filter.getMatchEngine().getClass() .getCanonicalName(), filter)); if (factory != null) { diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorFactoryRegistryListener.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorFactoryRegistryListener.java index c4d12b654..bcf91523e 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorFactoryRegistryListener.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorFactoryRegistryListener.java @@ -16,9 +16,13 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.compare.postprocessor.IPostProcessor; +import org.eclipse.emf.compare.postprocessor.IPostProcessor.Descriptor; import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; import org.eclipse.emf.compare.rcp.internal.EMFCompareRCPMessages; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.internal.extension.impl.WrapperItemDescriptor; /** * This listener will allow us to be aware of contribution changes against the model resolver extension point. @@ -45,8 +49,14 @@ public class PostProcessorFactoryRegistryListener extends AbstractRegistryEventL /** ATT_ORDINAL. */ static final String ATT_ORDINAL = "ordinal"; //$NON-NLS-1$ + /** ATT_LABEL. */ + static final String ATT_LABEL = "label"; //$NON-NLS-1$ + + /** ATT_DESCRIPTION. */ + static final String ATT_DESCRIPTION = "description"; //$NON-NLS-1$ + /** The post processor registry to which extension will be registered. */ - private final IPostProcessor.Descriptor.Registry<String> registry; + private final IItemRegistry<IPostProcessor.Descriptor> registry; /** * Creates a new registry listener with the given post processor registry to which extension will be @@ -62,7 +72,7 @@ public class PostProcessorFactoryRegistryListener extends AbstractRegistryEventL * the post processor registry to which extension will be registered. */ public PostProcessorFactoryRegistryListener(String pluginID, String extensionPointID, ILog log, - IPostProcessor.Descriptor.Registry<String> registry) { + IItemRegistry<IPostProcessor.Descriptor> registry) { super(pluginID, extensionPointID, log); this.registry = registry; } @@ -139,9 +149,14 @@ public class PostProcessorFactoryRegistryListener extends AbstractRegistryEventL } String className = element.getAttribute(ATT_CLASS); - IPostProcessor.Descriptor descriptor = new PostProcessorDescriptor(element, nsURI, resourceURI); - descriptor.setOrdinal(Integer.parseInt(element.getAttribute(ATT_ORDINAL))); - IPostProcessor.Descriptor previous = registry.put(className, descriptor); + IPostProcessor.Descriptor postProcessorDescriptor = new PostProcessorDescriptor(element, nsURI, + resourceURI); + postProcessorDescriptor.setOrdinal(Integer.parseInt(element.getAttribute(ATT_ORDINAL))); + + WrapperItemDescriptor<IPostProcessor.Descriptor> postProcessorItemDescriptor = new WrapperItemDescriptor<IPostProcessor.Descriptor>( + element.getAttribute(ATT_LABEL), element.getAttribute(ATT_DESCRIPTION), + postProcessorDescriptor.getOrdinal(), className, postProcessorDescriptor); + IItemDescriptor<Descriptor> previous = registry.add(postProcessorItemDescriptor); if (previous != null) { EMFCompareRCPPlugin.getDefault().log(IStatus.WARNING, "The post processor factory '" + className + "' is registered twice."); //$NON-NLS-1$//$NON-NLS-2$ diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorRegistryImpl.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorRegistryImpl.java new file mode 100644 index 000000000..96ce11ef7 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/postprocessor/PostProcessorRegistryImpl.java @@ -0,0 +1,152 @@ +/*******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.internal.postprocessor;
+
+import static com.google.common.base.Predicates.in;
+import static com.google.common.base.Predicates.not;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.compare.postprocessor.IPostProcessor;
+import org.eclipse.emf.compare.postprocessor.IPostProcessor.Descriptor;
+import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
+import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor;
+import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.AbstractItemDescriptor;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.WrapperItemDescriptor;
+import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * IPostProcessor.Descriptor.Registry implementation based on wrapping a {@link IItemRegistry}.
+ *
+ * @see IItemRegistry
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class PostProcessorRegistryImpl implements IPostProcessor.Descriptor.Registry<String> {
+
+ /** EMPTY_STRING. */
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ /** {@link IItemRegistry} of descriptor of {@link IItemDescriptor}. */
+ private final IItemRegistry<IPostProcessor.Descriptor> baseRegisty;
+
+ /**
+ * Constructor.
+ *
+ * @param baseRegisty
+ * {@link IItemDescriptor} filled with {@link IItemDescriptor} of
+ * {@link IPostProcessor.Descriptor}.
+ */
+ public PostProcessorRegistryImpl(IItemRegistry<IPostProcessor.Descriptor> baseRegisty) {
+ super();
+ this.baseRegisty = baseRegisty;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPostProcessor.Descriptor put(String key, IPostProcessor.Descriptor descriptor) {
+ WrapperItemDescriptor<IPostProcessor.Descriptor> newDescriptor = new WrapperItemDescriptor<IPostProcessor.Descriptor>(
+ EMPTY_STRING, EMPTY_STRING, descriptor.getOrdinal(), descriptor.getInstanceClassName(),
+ descriptor);
+ IItemDescriptor<IPostProcessor.Descriptor> oldDescriptor = baseRegisty.add(newDescriptor);
+ if (oldDescriptor != null) {
+ return oldDescriptor.getItem();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clear() {
+ baseRegisty.clear();
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IPostProcessor.Descriptor> getDescriptors() {
+ Collection<IItemDescriptor<IPostProcessor.Descriptor>> activeDescriptor = Collections2.filter(
+ baseRegisty.getItemDescriptors(), not(in(getDisabledEngines())));
+ Collection<IPostProcessor.Descriptor> descriptors = Collections2.transform(activeDescriptor,
+ AbstractItemDescriptor.<IPostProcessor.Descriptor> getItemFunction());
+ return Lists.newArrayList(descriptors);
+ }
+
+ /**
+ * Return a collection of disabled {@link IItemDescriptor<IPostProcessor.Descriptor>}.
+ *
+ * @return Collection<IItemDescriptor<IPostProcessor.Descriptor>>
+ */
+ private Collection<IItemDescriptor<IPostProcessor.Descriptor>> getDisabledEngines() {
+ List<IItemDescriptor<IPostProcessor.Descriptor>> result = ItemUtil.getItemsDescriptor(baseRegisty,
+ EMFComparePreferences.DISABLED_POST_PROCESSOR, EMFCompareRCPPlugin.getDefault()
+ .getEMFComparePreferences());
+ if (result == null) {
+ result = Collections.emptyList();
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Descriptor remove(String key) {
+ IItemDescriptor<IPostProcessor.Descriptor> oldDescriptor = baseRegisty.remove(key);
+ if (oldDescriptor != null) {
+ return oldDescriptor.getItem();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.postprocessor.IPostProcessor.Descriptor.Registry#getPostProcessors(org.eclipse.emf.compare.scope.IComparisonScope)
+ */
+ public List<IPostProcessor> getPostProcessors(IComparisonScope scope) {
+ final ImmutableList.Builder<IPostProcessor> processors = ImmutableList.builder();
+ for (IPostProcessor.Descriptor factory : getDescriptors()) {
+ Pattern nsURIPattern = factory.getNsURI();
+ if (nsURIPattern != null) {
+ for (String nsURI : scope.getNsURIs()) {
+ if (nsURIPattern.matcher(nsURI).matches()) {
+ processors.add(factory.getPostProcessor());
+ break;
+ }
+ }
+ }
+ // Should probably use two loops here to prioritize NsURI matching
+ Pattern resourceURIPattern = factory.getResourceURI();
+ if (resourceURIPattern != null) {
+ for (String resourceURI : scope.getResourceURIs()) {
+ if (resourceURIPattern.matcher(resourceURI).matches()) {
+ processors.add(factory.getPostProcessor());
+ break;
+ }
+ }
+ }
+ }
+ return processors.build();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/preferences/EMFComparePreferences.java b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/preferences/EMFComparePreferences.java index c51707ac5..b3a82e1ef 100644 --- a/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/preferences/EMFComparePreferences.java +++ b/plugins/org.eclipse.emf.compare.rcp/src/org/eclipse/emf/compare/rcp/internal/preferences/EMFComparePreferences.java @@ -29,14 +29,17 @@ public final class EMFComparePreferences { /** Conflicts detector preference. (Key to use in the registry to retrieve the engine descriptor). */
public static final String CONFLICTS_DETECTOR = "org.eclipse.emf.compare.preference.conflict.detector"; //$NON-NLS-1$
- /** Match engine preference. (Key to use in the registry to retrieve the engine descriptor). */
+ /** Disabled match engine preference. (Key to use in the registry to retrieve the engine descriptor). */
public static final String MATCH_ENGINE_DISABLE_ENGINES = "org.eclipse.emf.compare.preference.match.engine"; //$NON-NLS-1$
+ /** Disabled post processors preference. */
+ public static final String DISABLED_POST_PROCESSOR = "org.eclipse.emf.compare.preference.postprocessor.disabled"; //$NON-NLS-1$
+
/**
* Private constructor. Not to be called.
*/
private EMFComparePreferences() {
- throw new AssertionError("Not to be called"); //$NON-NLS-1$
+ // Hide default constructor.
}
}
|