From b7260dfcd8dcfa971786da7a181a29ea3cce387e Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Tue, 30 Apr 2024 18:28:59 -0400 Subject: [PATCH 1/6] Issue #443: Imported o.e.emf.compare.rcp.ui sources Signed-off-by: Ernesto Posse --- .../.checkstyle | 10 + .../org.eclipse.emf.compare.rcp.ui/.classpath | 7 + .../org.eclipse.emf.compare.rcp.ui/.project | 40 + .../.settings/edu.umd.cs.findbugs.core.prefs | 132 ++ .../edu.umd.cs.findbugs.plugin.eclipse.prefs | 3 + .../org.eclipse.core.resources.prefs | 2 + .../.settings/org.eclipse.core.runtime.prefs | 2 + .../.settings/org.eclipse.jdt.core.prefs | 389 ++++++ .../.settings/org.eclipse.jdt.ui.prefs | 66 + .../.settings/org.eclipse.pde.api.tools.prefs | 97 ++ .../META-INF/MANIFEST.MF | 64 + .../org.eclipse.emf.compare.rcp.ui/about.html | 106 ++ .../org.eclipse.emf.compare.rcp.ui/about.ini | 14 + .../about.properties | 26 + .../build.properties | 18 + .../icons/full/pref16/down.gif | Bin 0 -> 332 bytes .../icons/full/pref16/up.gif | Bin 0 -> 322 bytes .../icons/full/toolb16/filter.gif | Bin 0 -> 219 bytes .../icons/full/toolb16/group.gif | Bin 0 -> 307 bytes .../modeling32.png | Bin 0 -> 2414 bytes .../plugin.properties | 45 + .../org.eclipse.emf.compare.rcp.ui/plugin.xml | 227 ++++ .../schema/accessorFactory.exsd | 127 ++ .../contentMergeViewerCustomization.exsd | 213 ++++ .../schema/differenceGroupExtender.exsd | 121 ++ .../schema/filters.exsd | 144 +++ .../schema/groups.exsd | 178 +++ .../matchEngineFactoryConfigurationUI.exsd | 102 ++ .../compare/rcp/ui/EMFCompareRCPUIPlugin.java | 390 ++++++ .../rcp/ui/configuration/ICompareEvent.java | 21 + .../accessor/ICompareAccessor.java | 47 + .../accessor/IResourceContentsAccessor.java | 34 + .../accessor/IStructuralFeatureAccessor.java | 41 + .../accessor/factory/IAccessorFactory.java | 136 ++ .../legacy/IStreamContentAccessor.java | 43 + .../accessor/legacy/ITypedElement.java | 66 + .../impl/AbstractTypedElementAdapter.java | 73 ++ .../rcp/ui/internal/EMFCompareConstants.java | 41 + .../ui/internal/EMFCompareRCPUIMessages.java | 83 ++ .../configuration/IAdapterFactoryChange.java | 24 + .../ICompareEditingDomainChange.java | 24 + .../IComparisonAndScopeChange.java | 29 + .../IDiffRelationshipComputerChange.java | 36 + .../configuration/IEMFComparatorChange.java | 24 + .../IEMFCompareConfiguration.java | 70 + .../IMergePreviewModeChange.java | 24 + .../configuration/SideLabelProvider.java | 76 ++ .../impl/AdapterFactoryChange.java | 20 + .../impl/CompareEditingDomainChange.java | 21 + .../configuration/impl/CompareEvent.java | 36 + .../impl/ComparisonAndScopeChange.java | 71 ++ .../impl/DiffRelationshipComputerChange.java | 26 + .../impl/EMFComparatorChange.java | 20 + .../impl/MergePreviewModeChange.java | 20 + .../ui/AbstractConfigurationUI.java | 69 + .../ConfigurationUIRegistryEventListener.java | 134 ++ .../ui/IConfigurationUIFactory.java | 36 + ...efaultMatchEngineConfiguatorUIFactory.java | 33 + .../DefaultMatchEngineConfiguratorUI.java | 168 +++ .../IModelUpdateStrategy.java | 49 + .../IModelUpdateStrategyProvider.java | 27 + ...gleValuedAttributeModelUpdateStrategy.java | 150 +++ .../contentmergeviewer/TypeConstants.java | 47 + .../factory/impl/AbstractAccessorFactory.java | 44 + ...essorFactoryExtensionRegistryListener.java | 120 ++ .../impl/AccessorFactoryRegistryImpl.java | 130 ++ .../impl/ComparisonAccessorFactory.java | 76 ++ ...ainmentReferenceChangeAccessorFactory.java | 104 ++ .../FeatureMapChangeMoveAccessorFactory.java | 77 ++ .../FeatureMapKeyChangeAccessorFactory.java | 74 ++ .../ManyStructuralFeatureAccessorFactory.java | 97 ++ .../factory/impl/MatchAccessorFactory.java | 98 ++ .../impl/MatchResourceAccessorFactory.java | 82 ++ .../impl/ResourceContentsAccessorFactory.java | 68 + ...ingleStructuralFeatureAccessorFactory.java | 87 ++ .../StringAttributeChangeAccessorFactory.java | 102 ++ .../AbstractStructuralFeatureAccessor.java | 199 +++ ...ontainmentReferenceChangeAccessorImpl.java | 155 +++ .../impl/FeatureMapKeyChangeAccessorImpl.java | 140 ++ .../ManyStructuralFeatureAccessorImpl.java | 330 +++++ .../accessor/impl/MatchAccessor.java | 200 +++ .../impl/ResourceContentsAccessorImpl.java | 210 +++ .../impl/ResourceStreamAccessorImpl.java | 99 ++ .../SingleStructuralFeatureAccessorImpl.java | 84 ++ .../impl/StringAttributeChangeAccessor.java | 123 ++ .../accessor/legacy/impl/TypedNotifier.java | 99 ++ ...entMergeViewerCustomizationDescriptor.java | 171 +++ ...ntentMergeViewerCustomizationRegistry.java | 159 +++ ...geViewerCustomizationRegistryListener.java | 158 +++ .../emfcomparercpuimessages.properties | 109 ++ .../mergeviewer/ColorChangeEvent.java | 41 + .../mergeviewer/CompareColorImpl.java | 346 +++++ .../mergeviewer/IColorChangeEvent.java | 29 + .../mergeviewer/impl/AbstractMergeViewer.java | 155 +++ .../impl/AbstractStructuredMergeViewer.java | 251 ++++ .../impl/AbstractTableOrTreeItemWrapper.java | 414 ++++++ .../impl/AbstractTableOrTreeMergeViewer.java | 527 ++++++++ .../mergeviewer/impl/TableMergeViewer.java | 363 ++++++ .../mergeviewer/impl/TreeMergeViewer.java | 162 +++ .../item/impl/MergeViewerItem.java | 1135 +++++++++++++++++ ...sourceAttachmentChangeMergeViewerItem.java | 312 +++++ .../ResourceAttachmentChangeProvider.java | 53 + .../AdapterFactoriesPreferencePage.java | 233 ++++ .../ui/internal/preferences/DataHolder.java | 52 + .../preferences/EMFComparePreferencePage.java | 59 + .../preferences/EnginesPreferencePage.java | 590 +++++++++ .../preferences/FiltersPreferencePage.java | 557 ++++++++ .../preferences/GroupsPreferencePage.java | 360 ++++++ .../preferences/LoggingPreferencePage.java | 251 ++++ .../PostProcessorPreferencePage.java | 180 +++ .../impl/GroupsInteractiveContent.java | 336 +++++ .../impl/InteractiveUIContent.java | 728 +++++++++++ .../impl/ItemDescriptorLabelProvider.java | 33 + .../actions/FilterAction.java | 164 +++ .../actions/FilterActionMenu.java | 113 ++ .../actions/GroupAction.java | 183 +++ .../actions/GroupActionMenu.java | 120 ++ .../actions/ui/SynchronizerDialog.java | 99 ++ .../filters/StructureMergeViewerFilter.java | 304 +++++ .../impl/CascadingDifferencesFilter.java | 155 +++ .../filters/impl/DifferenceFilterChange.java | 92 ++ ...erenceFilterExtensionRegistryListener.java | 133 ++ .../filters/impl/DifferenceFilterManager.java | 365 ++++++ .../impl/DifferenceFilterRegistryImpl.java | 126 ++ .../filters/impl/TechnicalitiesFilter.java | 132 ++ .../groups/StructureMergeViewerGrouper.java | 175 +++ .../DifferenceGroupExtenderRegistryImpl.java | 86 ++ ...fferenceGroupExtenderRegistryListener.java | 111 ++ .../groups/impl/BasicDifferenceGroupImpl.java | 585 +++++++++ .../groups/impl/ByResourceGroupProvider.java | 169 +++ .../groups/impl/ConflictNodeBuilder.java | 90 ++ .../groups/impl/DefaultGroupProvider.java | 46 + .../DifferenceGroupDescriptorWrapper.java | 88 ++ .../groups/impl/DifferenceGroupManager.java | 258 ++++ .../impl/DifferenceGroupProviderChange.java | 46 + ...roupProviderExtensionRegistryListener.java | 157 +++ .../impl/DifferenceGroupRegistryImpl.java | 158 +++ .../impl/EmptyDifferenceGroupProvider.java | 23 + .../groups/impl/KindGroupProvider.java | 79 ++ .../impl/ThreeWayComparisonGroupProvider.java | 432 +++++++ .../provider/GroupItemProviderAdapter.java | 156 +++ .../TreeItemProviderAdapterFactorySpec.java | 58 + .../provider/TreeNodeItemProviderSpec.java | 303 +++++ ...OfContainmentReferenceChangeProcessor.java | 56 + .../nodes/ConflictNode.java | 75 ++ .../structuremergeviewer/nodes/DiffNode.java | 77 ++ .../structuremergeviewer/nodes/MatchNode.java | 106 ++ .../nodes/MatchResourceNode.java | 97 ++ .../nodes/TreeNodeImpl.java | 327 +++++ .../rcp/ui/internal/util/MergeViewerUtil.java | 447 +++++++ .../rcp/ui/internal/util/ResourceUIUtil.java | 698 ++++++++++ .../compare/rcp/ui/internal/util/SWTUtil.java | 112 ++ .../rcp/ui/mergeviewer/ICompareColor.java | 104 ++ .../rcp/ui/mergeviewer/IMergeViewer.java | 132 ++ .../ui/mergeviewer/item/IMergeViewerItem.java | 133 ++ .../IMergeViewerItemContentProvider.java | 56 + .../provider/IMergeViewerItemProvider.java | 48 + ...IMergeViewerItemProviderConfiguration.java | 63 + .../item/provider/IOptionalProvider.java | 28 + .../filters/AbstractDifferenceFilter.java | 143 +++ .../filters/IDeactivableDiffFilter.java | 35 + .../filters/IDifferenceFilter.java | 148 +++ .../filters/IDifferenceFilterChange.java | 54 + .../AbstractDifferenceGroupProvider.java | 227 ++++ .../groups/IDifferenceGroup.java | 82 ++ .../groups/IDifferenceGroupProvider.java | 186 +++ .../groups/IDifferenceGroupProvider2.java | 29 + .../IDifferenceGroupProviderChange.java | 29 + .../extender/IDifferenceGroupExtender.java | 81 ++ .../org.eclipse.emf.compare.rcp.ui/xpom.xml | 15 + 170 files changed, 23498 insertions(+) create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.checkstyle create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.classpath create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.project create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.core.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.resources.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.runtime.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.ui.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.pde.api.tools.prefs create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.html create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.ini create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.properties create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/build.properties create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/down.gif create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/up.gif create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/modeling32.png create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/plugin.properties create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/plugin.xml create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/accessorFactory.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/contentMergeViewerCustomization.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/differenceGroupExtender.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/matchEngineFactoryConfigurationUI.exsd create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/configuration/ICompareEvent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/ICompareAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IResourceContentsAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IStructuralFeatureAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/factory/IAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/IStreamContentAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/ITypedElement.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/impl/AbstractTypedElementAdapter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareConstants.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareRCPUIMessages.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IAdapterFactoryChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ICompareEditingDomainChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IComparisonAndScopeChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFComparatorChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IMergePreviewModeChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/SideLabelProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/AdapterFactoryChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEditingDomainChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEvent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/ComparisonAndScopeChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/EMFComparatorChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/MergePreviewModeChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/AbstractConfigurationUI.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/IConfigurationUIFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguatorUIFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguratorUI.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategy.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategyProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/SingleValuedAttributeModelUpdateStrategy.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/TypeConstants.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AbstractAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryExtensionRegistryListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryRegistryImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ComparisonAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ContainmentReferenceChangeAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapChangeMoveAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapKeyChangeAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ManyStructuralFeatureAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchResourceAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ResourceContentsAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/SingleStructuralFeatureAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/StringAttributeChangeAccessorFactory.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/AbstractStructuralFeatureAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ContainmentReferenceChangeAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/FeatureMapKeyChangeAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceContentsAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceStreamAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/StringAttributeChangeAccessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/legacy/impl/TypedNotifier.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationDescriptor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistry.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistryListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/ColorChangeEvent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/IColorChangeEvent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractStructuredMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeItemWrapper.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TableMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TreeMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/MergeViewerItem.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeMergeViewerItem.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/AdapterFactoriesPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EMFComparePreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/FiltersPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/LoggingPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterAction.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterActionMenu.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupAction.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupActionMenu.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/ui/SynchronizerDialog.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/StructureMergeViewerFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterExtensionRegistryListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterManager.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterRegistryImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/TechnicalitiesFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/StructureMergeViewerGrouper.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/BasicDifferenceGroupImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ByResourceGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ConflictNodeBuilder.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DefaultGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupDescriptorWrapper.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderExtensionRegistryListener.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/EmptyDifferenceGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/KindGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ThreeWayComparisonGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/GroupItemProviderAdapter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeItemProviderAdapterFactorySpec.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeNodeItemProviderSpec.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/match/MatchOfContainmentReferenceChangeProcessor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/ConflictNode.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/DiffNode.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchNode.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchResourceNode.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/TreeNodeImpl.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/MergeViewerUtil.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/ResourceUIUtil.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/SWTUtil.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/ICompareColor.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/IMergeViewer.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/IMergeViewerItem.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemContentProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProviderConfiguration.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IOptionalProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AbstractDifferenceFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDeactivableDiffFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/AbstractDifferenceGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroup.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider2.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProviderChange.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/extender/IDifferenceGroupExtender.java create mode 100644 papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/xpom.xml diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.checkstyle b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.checkstyle new file mode 100644 index 000000000..2684ff12f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.checkstyle @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.classpath b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.classpath new file mode 100644 index 000000000..098194ca4 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.project b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.project new file mode 100644 index 000000000..f60cd2ac3 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.project @@ -0,0 +1,40 @@ + + + org.eclipse.emf.compare.rcp.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + edu.umd.cs.findbugs.plugin.eclipse.findbugsNature + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.core.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.core.prefs new file mode 100644 index 000000000..1fab65578 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.core.prefs @@ -0,0 +1,132 @@ +#FindBugs User Preferences +#Tue Mar 12 08:11:54 CET 2013 +cloud_id=edu.umd.cs.findbugs.cloud.doNothingCloud +detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true +detectorAtomicityProblem=AtomicityProblem|true +detectorBadAppletConstructor=BadAppletConstructor|false +detectorBadResultSetAccess=BadResultSetAccess|true +detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true +detectorBadUseOfReturnValue=BadUseOfReturnValue|true +detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true +detectorBooleanReturnNull=BooleanReturnNull|true +detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false +detectorCheckExpectedWarnings=CheckExpectedWarnings|false +detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true +detectorCheckTypeQualifiers=CheckTypeQualifiers|true +detectorCloneIdiom=CloneIdiom|true +detectorComparatorIdiom=ComparatorIdiom|true +detectorConfusedInheritance=ConfusedInheritance|true +detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true +detectorCrossSiteScripting=CrossSiteScripting|true +detectorDefaultEncodingDetector=DefaultEncodingDetector|true +detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true +detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true +detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true +detectorDontUseEnum=DontUseEnum|true +detectorDroppedException=DroppedException|true +detectorDumbMethodInvocations=DumbMethodInvocations|true +detectorDumbMethods=DumbMethods|true +detectorDuplicateBranches=DuplicateBranches|true +detectorEmptyZipFileEntry=EmptyZipFileEntry|true +detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true +detectorExplicitSerialization=ExplicitSerialization|true +detectorFinalizerNullsFields=FinalizerNullsFields|true +detectorFindBadCast2=FindBadCast2|true +detectorFindBadForLoop=FindBadForLoop|true +detectorFindCircularDependencies=FindCircularDependencies|false +detectorFindDeadLocalStores=FindDeadLocalStores|true +detectorFindDoubleCheck=FindDoubleCheck|true +detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true +detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true +detectorFindFinalizeInvocations=FindFinalizeInvocations|true +detectorFindFloatEquality=FindFloatEquality|true +detectorFindHEmismatch=FindHEmismatch|true +detectorFindInconsistentSync2=FindInconsistentSync2|true +detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true +detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true +detectorFindMaskedFields=FindMaskedFields|true +detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true +detectorFindNakedNotify=FindNakedNotify|true +detectorFindNonShortCircuit=FindNonShortCircuit|true +detectorFindNullDeref=FindNullDeref|true +detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true +detectorFindOpenStream=FindOpenStream|true +detectorFindPuzzlers=FindPuzzlers|true +detectorFindRefComparison=FindRefComparison|true +detectorFindReturnRef=FindReturnRef|true +detectorFindRunInvocations=FindRunInvocations|true +detectorFindSelfComparison=FindSelfComparison|true +detectorFindSelfComparison2=FindSelfComparison2|true +detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true +detectorFindSpinLoop=FindSpinLoop|true +detectorFindSqlInjection=FindSqlInjection|true +detectorFindTwoLockWait=FindTwoLockWait|true +detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true +detectorFindUnconditionalWait=FindUnconditionalWait|true +detectorFindUninitializedGet=FindUninitializedGet|true +detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true +detectorFindUnreleasedLock=FindUnreleasedLock|true +detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true +detectorFindUnsyncGet=FindUnsyncGet|true +detectorFindUseOfNonSerializableValue=FindUseOfNonSerializableValue|true +detectorFindUselessControlFlow=FindUselessControlFlow|true +detectorFormatStringChecker=FormatStringChecker|true +detectorHugeSharedStringConstants=HugeSharedStringConstants|true +detectorIDivResultCastToDouble=IDivResultCastToDouble|true +detectorIncompatMask=IncompatMask|true +detectorInconsistentAnnotations=InconsistentAnnotations|true +detectorInefficientMemberAccess=InefficientMemberAccess|false +detectorInefficientToArray=InefficientToArray|true +detectorInfiniteLoop=InfiniteLoop|true +detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true +detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true +detectorInitializationChain=InitializationChain|true +detectorInitializeNonnullFieldsInConstructor=InitializeNonnullFieldsInConstructor|true +detectorInstantiateStaticClass=InstantiateStaticClass|true +detectorIntCast2LongAsInstant=IntCast2LongAsInstant|true +detectorInvalidJUnitTest=InvalidJUnitTest|true +detectorIteratorIdioms=IteratorIdioms|true +detectorLazyInit=LazyInit|true +detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true +detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true +detectorMethodReturnCheck=MethodReturnCheck|true +detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true +detectorMutableLock=MutableLock|true +detectorMutableStaticFields=MutableStaticFields|true +detectorNaming=Naming|true +detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true +detectorNumberConstructor=NumberConstructor|true +detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true +detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true +detectorPublicSemaphores=PublicSemaphores|false +detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true +detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true +detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true +detectorRedundantInterfaces=RedundantInterfaces|true +detectorRepeatedConditionals=RepeatedConditionals|true +detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true +detectorSerializableIdiom=SerializableIdiom|true +detectorStartInConstructor=StartInConstructor|true +detectorStaticCalendarDetector=StaticCalendarDetector|true +detectorStringConcatenation=StringConcatenation|true +detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true +detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true +detectorSwitchFallthrough=SwitchFallthrough|true +detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true +detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true +detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true +detectorURLProblems=URLProblems|true +detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true +detectorUnnecessaryMath=UnnecessaryMath|true +detectorUnreadFields=UnreadFields|true +detectorUselessSubclassMethod=UselessSubclassMethod|false +detectorVarArgsProblems=VarArgsProblems|true +detectorVolatileUsage=VolatileUsage|true +detectorWaitInLoop=WaitInLoop|true +detectorWrongMapIterator=WrongMapIterator|true +detectorXMLFactoryBypass=XMLFactoryBypass|true +detector_threshold=2 +effort=default +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false|15 +filter_settings_neg=NOISE,I18N,EXPERIMENTAL| +run_at_full_build=true diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs new file mode 100644 index 000000000..4235f7661 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/edu.umd.cs.findbugs.plugin.eclipse.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScariest=Error +edu.umd.cs.findbugs.plugin.eclipse.findbugsMarkerScary=Error diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.resources.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..99f26c020 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.runtime.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 000000000..5a0ad22d2 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.core.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..79ea86fdb --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,389 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=warning +org.eclipse.jdt.core.compiler.problem.comparingIdentical=error +org.eclipse.jdt.core.compiler.problem.deadCode=error +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error +org.eclipse.jdt.core.compiler.problem.includeFieldsInNullAnalysis=disabled +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=error +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=disabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=1 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=true +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=110 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true +org.eclipse.jdt.core.formatter.indentation.size=8 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=110 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=false +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.ui.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..57660252a --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,66 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_EMF Compare +formatter_settings_version=12 +org.eclipse.jdt.ui.ignorelowercasenames=true +org.eclipse.jdt.ui.importorder=fr;com;java;javax;org; +org.eclipse.jdt.ui.ondemandthreshold=99 +org.eclipse.jdt.ui.staticondemandthreshold=99 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=false +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_type_arguments=false +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=false +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_blocks=true +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.pde.api.tools.prefs b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.pde.api.tools.prefs new file mode 100644 index 000000000..01461e0e0 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/.settings/org.eclipse.pde.api.tools.prefs @@ -0,0 +1,97 @@ +ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Warning +ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning +ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Warning +ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Warning +ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning +API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Warning +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Warning +API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Warning +API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Warning +API_USE_SCAN_FIELD_SEVERITY=Error +API_USE_SCAN_METHOD_SEVERITY=Error +API_USE_SCAN_TYPE_SEVERITY=Error +CLASS_ELEMENT_TYPE_ADDED_METHOD=Warning +CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning +CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning +CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning +CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning +CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning +CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning +CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning +CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Warning +CLASS_ELEMENT_TYPE_REMOVED_FIELD=Warning +CLASS_ELEMENT_TYPE_REMOVED_METHOD=Warning +CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Warning +CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning +CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning +CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning +CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning +CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning +ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning +ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning +ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Warning +ENUM_ELEMENT_TYPE_REMOVED_FIELD=Warning +ENUM_ELEMENT_TYPE_REMOVED_METHOD=Warning +ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning +FIELD_ELEMENT_TYPE_ADDED_VALUE=Warning +FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning +FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Warning +FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning +FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning +FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning +FIELD_ELEMENT_TYPE_CHANGED_TYPE=Warning +FIELD_ELEMENT_TYPE_CHANGED_VALUE=Warning +FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Warning +FIELD_ELEMENT_TYPE_REMOVED_VALUE=Warning +ILLEGAL_EXTEND=Warning +ILLEGAL_IMPLEMENT=Warning +ILLEGAL_INSTANTIATE=Warning +ILLEGAL_OVERRIDE=Warning +ILLEGAL_REFERENCE=Warning +INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Warning +INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Warning +INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning +INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Warning +INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning +INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Warning +INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Warning +INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Warning +INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Warning +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Warning +INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning +INVALID_JAVADOC_TAG=Ignore +INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error +LEAK_EXTEND=Warning +LEAK_FIELD_DECL=Warning +LEAK_IMPLEMENT=Warning +LEAK_METHOD_PARAM=Warning +LEAK_METHOD_RETURN_TYPE=Warning +METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Warning +METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Warning +METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Warning +METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Warning +METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Warning +METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Warning +METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Warning +METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Warning +METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Warning +METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Warning +MISSING_EE_DESCRIPTIONS=Error +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Warning +TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Warning +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Warning +TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Warning +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Warning +TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Warning +UNUSED_PROBLEM_FILTERS=Warning +automatically_removed_unused_problem_filters=false +eclipse.preferences.version=1 +incompatible_api_component_version=Warning +incompatible_api_component_version_include_major_without_breaking_change=Disabled +incompatible_api_component_version_include_minor_without_api_change=Disabled +invalid_since_tag_version=Warning +malformed_since_tag=Warning +missing_since_tag=Warning +report_api_breakage_when_major_version_incremented=Disabled +report_resolution_errors_api_component=Warning diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..aa955c2c8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF @@ -0,0 +1,64 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.emf.compare.rcp.ui;singleton:=true +Bundle-Version: 4.4.2.qualifier +Bundle-Activator: org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-ActivationPolicy: lazy +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", + org.eclipse.emf.edit.ui;bundle-version="2.10.0", + org.eclipse.emf.compare;bundle-version="2.0.1", + org.eclipse.emf.compare.edit;bundle-version="2.0.1", + org.eclipse.emf.ecore.xmi;bundle-version="2.5.0", + org.eclipse.emf.compare.rcp;bundle-version="2.5.0", + org.eclipse.jface.databinding;bundle-version="1.4.0", + org.eclipse.core.databinding;bundle-version="1.3.100", + org.eclipse.core.databinding.property;bundle-version="1.3.0", + org.eclipse.core.databinding.beans;bundle-version="1.2.100" +Export-Package: org.eclipse.emf.compare.rcp.ui, + org.eclipse.emf.compare.rcp.ui.configuration, + org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor, + org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory, + org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy, + org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl, + org.eclipse.emf.compare.rcp.ui.internal;x-friends:="org.eclipse.emf.compare.diagram.ide.ui,org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.configuration;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.configuration.impl;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.configuration.ui;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.match;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.legacy.impl;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.mergeviewer;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.preferences;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.preferences.impl;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions.ui;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters;x-friends:="org.eclipse.emf.compare.uml2.rcp.ui.tests", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl;x-friends:="org.eclipse.emf.compare.uml2.rcp.ui.tests", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.extender;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl;x-friends:="org.eclipse.emf.compare.uml2.rcp.ui.tests", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.provider;x-friends:="org.eclipse.emf.compare.uml2.rcp.ui.tests", + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes;x-internal:=true, + org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.match, + org.eclipse.emf.compare.rcp.ui.internal.util;x-friends:="org.eclipse.emf.compare.ide.ui", + org.eclipse.emf.compare.rcp.ui.mergeviewer, + org.eclipse.emf.compare.rcp.ui.mergeviewer.item, + org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider, + org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters, + org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups, + org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender +Import-Package: com.google.common.base;version="[27.0.0,28.0.0)", + com.google.common.cache;version="[27.0.0,28.0.0)", + com.google.common.collect;version="[27.0.0,28.0.0)", + com.google.common.eventbus;version="[27.0.0,28.0.0)", + com.google.common.io;version="[27.0.0,28.0.0)", + org.apache.log4j;version="[1.2.15,2.0.0)" diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.html b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.html new file mode 100644 index 000000000..670d10856 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.html @@ -0,0 +1,106 @@ + + + + +Eclipse Foundation Software User Agreement + + + +

Eclipse Foundation Software User Agreement

+

April 14, 2010

+ +

Usage Of Content

+ +

THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS + (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND + CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE + OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR + NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND + CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.

+ +

Applicable Licenses

+ +

Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 + ("EPL"). A copy of the EPL is provided with this Content and is also available at http://www.eclipse.org/legal/epl-v10.html. + For purposes of the EPL, "Program" will mean the Content.

+ +

Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code + repository ("Repository") in software modules ("Modules") and made available as downloadable archives ("Downloads").

+ +
    +
  • Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content. Typical modules may include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and features ("Features").
  • +
  • Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java™ ARchive) in a directory named "plugins".
  • +
  • A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material. Each Feature may be packaged as a sub-directory in a directory named "features". Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of the Plug-ins + and/or Fragments associated with that Feature.
  • +
  • Features may also include other Features ("Included Features"). Within a Feature, files named "feature.xml" may contain a list of the names and version numbers of Included Features.
  • +
+ +

The terms and conditions governing Plug-ins and Fragments should be contained in files named "about.html" ("Abouts"). The terms and conditions governing Features and +Included Features should be contained in files named "license.html" ("Feature Licenses"). Abouts and Feature Licenses may be located in any directory of a Download or Module +including, but not limited to the following locations:

+ +
    +
  • The top-level (root) directory
  • +
  • Plug-in and Fragment directories
  • +
  • Inside Plug-ins and Fragments packaged as JARs
  • +
  • Sub-directories of the directory named "src" of certain Plug-ins
  • +
  • Feature directories
  • +
+ +

Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license ("Feature Update License") during the +installation process. If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or +inform you where you can locate them. Feature Update Licenses may be found in the "license" property of files named "feature.properties" found within a Feature. +Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in +that directory.

+ +

THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE +OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):

+ + + +

IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, or Feature Update License is provided, please +contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.

+ + +

Use of Provisioning Technology

+ +

The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse + Update Manager ("Provisioning Technology") for the purpose of allowing users to install software, documentation, information and/or + other materials (collectively "Installable Software"). This capability is provided with the intent of allowing such users to + install, extend and update Eclipse-based products. Information about packaging Installable Software is available at http://eclipse.org/equinox/p2/repository_packaging.html + ("Specification").

+ +

You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the + applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology + in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the + Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:

+ +
    +
  1. A series of actions may occur ("Provisioning Process") in which a user may execute the Provisioning Technology + on a machine ("Target Machine") with the intent of installing, extending or updating the functionality of an Eclipse-based + product.
  2. +
  3. During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be + accessed and copied to the Target Machine.
  4. +
  5. Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable + Software ("Installable Software Agreement") and such Installable Software Agreement shall be accessed from the Target + Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern + the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such + indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.
  6. +
+ +

Cryptography

+ +

Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to + another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import, + possession, or use, and re-export of encryption software, to see if this is permitted.

+ +

Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.

+ + \ No newline at end of file diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.ini b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.ini new file mode 100644 index 000000000..eec22440e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.ini @@ -0,0 +1,14 @@ +# about.ini +# contains information about a feature +# java.io.Properties file (ISO 8859-1 with "\" escapes) +# "%key" are externalized strings defined in about.properties +# This file does not need to be translated. + +# Property "aboutText" contains blurb for "About" dialog (translated) +aboutText=%featureText + +# Property "featureImage" contains path to feature image (32x32) +featureImage=modeling32.png + +# Property "appName" contains name of the application (translated) +appName=%featureName diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.properties b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.properties new file mode 100644 index 000000000..0fc1ee74a --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/about.properties @@ -0,0 +1,26 @@ +# /** +# * +# * +# * Copyright (c) 2006, 2012 Obeo and others. +# * 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 +# * +# * +# */ + +# NLS_MESSAGEFORMAT_VAR + +featureName=EMF Compare RCP UI + +featureText=EMF Compare - RCP UI\n\ +Version: {featureVersion}\n\ +\n\ +(c) Copyright Obeo and others. 2006, 2012. All rights reserved.\n\ +\n\ +EMF Compare brings comparison to the Eclipse Modeling Framework\n\ +Visit http://www.eclipse.org/emf/compare diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/build.properties b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/build.properties new file mode 100644 index 000000000..002d2e06f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/build.properties @@ -0,0 +1,18 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + plugin.properties,\ + .,\ + about.html,\ + plugin.xml,\ + icons/,\ + schema/,\ + about.ini,\ + about.properties,\ + modeling32.png +src.includes = about.html,\ + icons/,\ + schema/,\ + about.ini,\ + about.properties,\ + modeling32.png diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/down.gif b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/down.gif new file mode 100644 index 0000000000000000000000000000000000000000..072b1844572646fdb57124b6e938a465daac8d58 GIT binary patch literal 332 zcmZ?wbhEHb6krfwxXQrr@Ar$pzh3s)RRH2yZMG-dG{LyHRvkqv*C;prFW}Cb1QH0&9u|R~HDbFBMu_B(%Cf zXj8fH`cmQLIReYF1^)m4&p+|z+lLr1JVKV69Zf3ff)rJI#S8AmOS&g!objY zXp*F{?P9eo9}@`oK{Iw9&}i^SBU4D}c3FLN?5SiQ`V!5RSYo{04T literal 0 HcmV?d00001 diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/up.gif b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/pref16/up.gif new file mode 100644 index 0000000000000000000000000000000000000000..091e8840064e174a9769d317152b8c580ddecea7 GIT binary patch literal 322 zcmZ?wbhEHb6krfwxXQrr@9+D6zn=X4cJ<${r+>d*`SB+G3&QIReYF z1^)m4&p;MX{K>+|z@W>Z1JVuh69ZfPfoTOEI#R9EPhYHHWSHW;aA^Psk4|8qlR|(1 z$6V!S4sH@WPXY{$C%UM-<#c(c*km`W|M16*J0IO;M0vPHr2};}M7l*ZJ5+l_v^vx$ Ys&yz&RO!&3sNJEfvq)#b0!IdG05JoA2LJ#7 literal 0 HcmV?d00001 diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif new file mode 100644 index 0000000000000000000000000000000000000000..6fe6f0e10a11203f4297dcdff4288ae6f2698fe7 GIT binary patch literal 219 zcmZ?wbhEHb6krfwIKseS;S!r)))JmlQ{FNwwRTEO>(Y?!&Aw5w|Ng%J`{~%WbLPKw)$;B Og`P}9k*1m=gEav5gIBTu literal 0 HcmV?d00001 diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif new file mode 100644 index 0000000000000000000000000000000000000000..2e1e2b93870ffdf19a7f9d0169f539f557e3ae4d GIT binary patch literal 307 zcmZ?wbhEHb6krfwxXQq=@5qJN>h-+~kF48sEv0EoYU9T8$%kWWR+mmWTr&A!>6Ame zk6wKE>f^&#?>C*hwdul*LmPAce7*7a+pV25)OXKN+C5!$?+mpIyDQeTDgM0GesO2z z#ohHQ>ZI1T$^W|5zOr8S|Ns9Cv;>MjSr{1@6c}_smVo@kz!u;zp}<3jkCF4}p$r!T zDYmqY4=Mzf9C3W0z`(lU%zBZPGIjc*U1={`#B>Eurg&@>Go0s>zT)XDM`?K(fruoZ X6z?{l+`t5d((u08*uJSwjttfSxo~5H literal 0 HcmV?d00001 diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/modeling32.png b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/modeling32.png new file mode 100644 index 0000000000000000000000000000000000000000..6b08de2ada775b81a7d93d35ecdbc8bbed6da81f GIT binary patch literal 2414 zcmV-!36b`RP)mG85FUz8YqR{-rnBN_xo$VbKdjbHiRY1wv+qh zy!SolJ-_GU_dMquMrc70)S+vDBxRp~#32gAhd2-uVnB4>GsbMXM(ghBrT{$?KOu^g z7~U&*p~!K*uBQTAm7vX#CMjHz`gsai61d72l1lqf!krH+8{?=!I4_20H8h6BnKVk_ zp938KZB<&El)x>JlzeWGV4k#`gR2sRzw@Ak1|@`aarAYNghH$VBMD4M zFhz-T?eX72UuAe+D1mu@o$QxLk1z?YL5jw#rj{=imRV(^#nGJQ6FIH1P_+tgowzh& z7!I>-tz_u=qs7^`KfR7*iefRnE=TGi^{`q09K&u2@ z1X&E}fP7vG4?|v?t|axDYLBB?>7r)Sg`7@flNHM5G%A%%(sYY7!zSC($+9#ujmkyK zC>(OV(cd#FD~iHewtahBcYlBXgRQNtE4jCFx!l^++im7#y6Fejxd{HH)P=INbm4XZ*$<-s0mR3fkb?Xf1I=g7&U|n0 z-aqJz7wh}m+S*z-Z{GY3+qU(cJ9oYw_<^H@D+;D_;i+Xhx}AjOuQs5DW7xOG6LBPIjC41kQpqF}%2<|5rU_429=WbZw(SXpUG+$Ko*oQbbg^<)-0;MAL0DOfHTP zODf<=aNqZYP!Kv484Bz`aAn7iEtH!nB_DtMiQlMdkjDoFOsYf*h&-SDWcr)1B}kc)BD1VNi$~XM($DDafKIn2()S#4g>!!+r=1wIk;z&?>e+}X+7QZrIob$j@uDa zgIZE4dgINvs9faWo{&nV@r#Ls^=r;OC1fhIUBkZ12eCYWeL7X4nY>2%ypCR{{H#v1 z1sz4lqEf}63Oo^l^9614Tw8j;p~gm)QmJN&*Tt#6zK)WONm{k4U4)Vw=m7)S)GLYa zN41?Z`3BBr8!n%ms*-{X0HZ{nb0Tsu3z@+CP+Y{`g2JZgxd#F-^hTwk(Zr=mkqNqP z(3Q&t0J|WoC$a@-OEKhun?X$hxS@-?f2wFwv1~@03oj|+BcAsT*B&uWg2ugUkp9R zQc+bxQ z4KEKK09Q(4;Lhc3)SO@fjDvEE-J10#b>5PuhqtbypYM5{W@ct;ZuccoYrsJm0%Ec( zht>~dvqvvP3dGve?adg%k%@gSUn%4=x2)O3C$=w2(O>^Q8patU3*gd*hB$56vJPIc z=)i$Lirz(j3xaw!&>#Y>G5_#%_Shp=-y?9|3X;n@I$EFHzI{hL9&dbM-@Xri`s$uHbLQ;n z>u*ofuAeIO9U%m8$ z)m>c=@fQ;l6QAK2>$SJH-!%GABYq(X=Qqp2+RcP=7APSWsj8 zJl4bQ$9B=bX)Ke;^bQXX|5;Vlrs(DL^z^yiyLay&K7Ra@73mJ|vHtIFT(n@}w-lzN z{xp1&4h;>{XOox3T(P;Zxg(e$TWB@kZl9UY_-iZBo4I4?y`kU1>eTr7_^H9c!J~uk zyz>#$9;e}vk!VjH!Tb?$cwlPk zNQwS~#=0|^4qV_;FrW!lkYA@94v7C66u`MC(2*rJEOQV?98t+<(ME}OO4juMw&8N> zm%Tt-GAp7qgF!)fLbmvk31GOB1g^ZzM&SQ5a7_UwZoPpcN-{T3+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %themeElementCategory.description + + + + + %incomingColor.desc + + + + + %conflictingColor.desc + + + + + %outgoingColor.desc + + + + + %requiredColor.desc + + + + + %mergeColor.desc + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/accessorFactory.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/accessorFactory.exsd new file mode 100644 index 000000000..29db6926c --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/accessorFactory.exsd @@ -0,0 +1,127 @@ + + + + + + + + + You can provide your own accessor factory by adding an extension of type <samp>org.eclipse.emf.compare.rcp.ui.accessorFactory</samp> to your plugin. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A class that implements <samp>org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory</samp>. + + + + + + + + + + The ranking of this accessor factory. + + + + + + + + + + + + 4.0 + + + + + + + + + The example below shows the extension point syntax: +<p> +<pre> +<extension point="org.eclipse.emf.compare.rcp.ui.accessorFactory"> + <factory + class="com.example.xyz.SampleAccessorFactory" + ranking="10"> + </factory> +</extension> +</pre> +</p> + + + + + + + + + Plugins using this extension point have to implement <samp>org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory</samp>. + + + + + + + + + There is no default implementation. + + + + + + + + + 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 + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/contentMergeViewerCustomization.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/contentMergeViewerCustomization.exsd new file mode 100644 index 000000000..53a1f1cae --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/contentMergeViewerCustomization.exsd @@ -0,0 +1,213 @@ + + + + + + + + + This extension point can be used to tell EMF Compare how to handle the content within the ContentMergeViewers. + +The "contentCustomization" element may be used by clients to filter the root elements which are provided by the "EMFCompareAccessor"s and displayed in the Content Merge Viewers. Another use case would be to wrap the given objects within an own special object type which provides additional information for a specialized LabelProvider. + +The "treeContentCustomization" element may be used by clients to add, move or filter elements within the Tree Content Merge Viewers (Containment Tree). The added elements don't have to be EObjects. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Allows to customize the root and selected elements of the default ContentMergeViewers. + + + + + + + The ContentProvider which is responsible of determining the root and selected IMergeViewerItems by examining the input of the ContentMergeViewer. + +If this attribute is not specified a default implementation will be used. + + + + + + + + + + The IContextTester inidicates whether the customization should be applied for the current comparison. + +If no IContextTester is specified the customization will be applied to all contexts. + + + + + + + + + + If multiple content customizations are applicable to the current context, the one with the highest ranking will be chosen. + +If no ranking is specified a default ranking of "-1" will be assumed. + + + + + + + + + + Allows to customize the structure of the TreeContentMergeViewer. + + + + + + + The content provider which is responsible of determining the children and parent elements of IMergeViewerItems. + + + + + + + + + + The IContextTester indicates whether the customization should be applied for the current comparison. + +If no IContextTester is specified the customization will be applied to all contexts. + + + + + + + + + + If multiple content customizations are applicable to the current context, the one with the highest ranking will be chosen. + +If no ranking is specified a default ranking of "-1" will be assumed. + + + + + + + + + + + + 4.3.0 + + + + + + + + + The example below shows the extension point syntax: +<p> +<pre> + <extension + point="org.eclipse.emf.compare.rcp.ui.contentMergeViewerCustomization"> + <treeContentCustomization + contentProvider="org.example.MyMergeViewerItemContentProvider" + context="org.example.MyContextTester" + ranking="20"> + </treeContentCustomization> + <contentCustomization + mergeViewerItemProvider="org.example.MyCompareAccessorMergeViewerItemProvider" + context="org.example.MyContextTester" + ranking="10"> + </contentCustomization> + </extension> +</pre> +</p> + + + + + + + + + Plug-ins using this extension point have to implement: +<ul> +<li><samp>org.eclipse.emf.compare.ide.ui.contentmergeviewer.tree.provider.IMergeViewerItemProvider</samp> when using the "contentCustomization" element.</li> +<li><samp>IMergeViewerItemContentProvider</samp> when using the "treeContentCustomization" element.</li> +</ul> +Optionally <samp>org.eclipse.emf.compare.adapterfactory.context.IContextTester</samp> may be implemented to check for a certain context (recommended). + + + + + + + + + There is no provided default implementation. + + + + + + + + + Copyright (c) 2016 EclipseSource Muenchen GmbH and others. +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: + Stefan Dirix - initial API and implementation + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/differenceGroupExtender.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/differenceGroupExtender.exsd new file mode 100644 index 000000000..229a9b41e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/differenceGroupExtender.exsd @@ -0,0 +1,121 @@ + + + + + + + + + A difference group extender allows you to modify the display of an existing group's differences tree node of the EMF Commpare structural view. + +You can provide your own extender by adding an extension of type <samp>org.eclipse.emf.compare.rcp.ui.differenceGroupExtender</samp> to your plugin. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A class that implements <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender</samp>. + + + + + + + + + + + + + + + 4.0 + + + + + + + + + The example below shows the extension point syntax: +<p> +<pre> +<extension point="org.eclipse.emf.compare.rcp.ui.differenceGroupExtender"> + <differenceGroupExtender + class="com.example.xyz.SampleExtender"> + </differenceGroupExtender> +</extension> +</pre> +</p> + + + + + + + + + Plugins using this extension point have to implement <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender</samp>. + + + + + + + + + There is no default implementation. + + + + + + + + + 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 + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd new file mode 100644 index 000000000..5afac97c9 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd @@ -0,0 +1,144 @@ + + + + + + + + + A filter allows you to filter differences out of the EMF Commpare structural view according to a set predicate. + +You can provide your own filters by adding an extension of type <samp>org.eclipse.emf.compare.rcp.ui.filters</samp> to your plugin. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A class that implements <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter</samp>. + + + + + + + + + + A human-readable label for this filter This will be displayed in the EMF Compare UI. + + + + + + + The initial activation state of the filter. + + + + + + + A human-readable description for this filter. It will be displayed in the EMF Compare UI. + + + + + + + + + + + + 4.0 + + + + + + + + + The example below shows the extension point syntax: +<p> +<pre> +<extension point="org.eclipse.emf.compare.rcp.ui.filters"> + <filter + activeByDefault="true" + class="com.example.xyz.SampleFilter" + label="My own filter"> + </filter> +</extension> +</pre> +</p> + + + + + + + + + Plugins using this extension point have to implement <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter</samp>. + + + + + + + + + A default abstract implementation named <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.impl.AbstractDifferenceFilter</samp> is available in the <samp>org.eclipse.emf.compare.rcp.ui</samp> plugin. + + + + + + + + + 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 + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd new file mode 100644 index 000000000..ba49fc6ab --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd @@ -0,0 +1,178 @@ + + + + + + + + + A group provider allows you to group differences together in the structural view according to a set predicate. + +You can provide your own groups by adding an extension of type <samp>org.eclipse.emf.compare.rcp.ui.groups</samp> to your plugin. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A class that implements <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider</samp>. + + + + + + + + + + A human-readable label for this group. This will be displayed in the EMF Compare UI. + + + + + + + The initial activation state of the group. (Deprecated use rank instead) + + + + + + + + + + A description of the group. (Used in interface) + + + + + + + The rank of the group. The highest rank enabled for a comparison is used. + + Default value : 0 + + + + + + + Type of comparison this group can handle. + THREE_WAY: This group can only handle three way comparison. + TWO_WAY: This group can handle two way comparison + BOTH: This group can handle two and three way comparison. + + Default value: BOTH + + + + + + + + + + + + + + + + + + + + + + 3.0.0 + + + + + + + + + The example below shows the extension point syntax: +<p> +<pre> +<extension point="org.eclipse.emf.compare.rcp.ui.groups"> + <group + activeByDefault="false" + class="com.example.xyz.SampleGroupProvider" + label="My own group provider"> + </group> +</extension> +</pre> +</p> + + + + + + + + + Plugins using this extension point have to implement <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider</samp>. + + + + + + + + + A default abstract implementation named <samp>org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.impl.AbstractDifferenceGroupProvider</samp> is available in the <samp>org.eclipse.emf.compare.rcp.ui</samp> plugin. + + + + + + + + + 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 + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/matchEngineFactoryConfigurationUI.exsd b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/matchEngineFactoryConfigurationUI.exsd new file mode 100644 index 000000000..80a97b713 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/schema/matchEngineFactoryConfigurationUI.exsd @@ -0,0 +1,102 @@ + + + + + + + + + This extension point is use to register UI component to configure Matching engine factories. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Id of the item to configure. It is the qualified named of the factory class. This factory shall implement org.eclipse.emf.compare.rcp.internal.extension.IConfigurableItem. + + + + + + + + + + A class that provide a Configuration UI. + + + + + + + + + + + + + + + 4.0.0 + + + + + + + + + <extension + point="org.eclipse.emf.compare.rcp.ui.matchEngineFactoryConfiguratorUI"> + <configurator + itemToConfigure="org.eclipse.emf.compare.rcp.internal.match.RCPMatchEngineFactory" + uiProvider="org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.match.DefaultMatchEngineConfiguatorUIFactory"> + </configurator> + </extension> + + + + + + + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java new file mode 100644 index 000000000..bbfef3e6d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java @@ -0,0 +1,390 @@ +/****************************************************************************** + * Copyright (c) 2012, 2016 Obeo and others. + * 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 + * Mathias Schaefer - preferences refactoring + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.DefaultScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemRegistry; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.ConfigurationUIRegistryEventListener; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.IConfigurationUIFactory; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl.AccessorFactoryExtensionRegistryListener; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl.AccessorFactoryRegistryImpl; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization.ContentMergeViewerCustomizationRegistry; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization.ContentMergeViewerCustomizationRegistryListener; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterExtensionRegistryListener; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterManager; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterRegistryImpl; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.extender.DifferenceGroupExtenderRegistryImpl; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.extender.DifferenceGroupExtenderRegistryListener; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupManager; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupProviderExtensionRegistryListener; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupRegistryImpl; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle. + * + * @since 3.0 + */ +public class EMFCompareRCPUIPlugin extends AbstractUIPlugin { + + /** + * The plug-in ID. + */ + public static final String PLUGIN_ID = "org.eclipse.emf.compare.rcp.ui"; //$NON-NLS-1$ + + public static final String GROUP_PROVIDER_PPID = "groups"; //$NON-NLS-1$ + + public static final String FILTER_PROVIDER_PPID = "filters"; //$NON-NLS-1$ + + public static final String ACCESSOR_FACTORY_PPID = "accessorFactory"; //$NON-NLS-1$ + + /** + * @since 4.0 + */ + public static final String DIFFERENCE_GROUP_EXTENDER_PPID = "differenceGroupExtender"; //$NON-NLS-1$ + + /** + * @since 4.0 + */ + private static final String MATCH_ENGINE_FACTORY_CONFIGURATION_UI_PPID = "matchEngineFactoryConfigurationUI";//$NON-NLS-1$ + + /** + * @since 4.4 + */ + private static final String CONTENT_CUSTOMIZATION_PPID = "contentMergeViewerCustomization"; //$NON-NLS-1$ + + /** + * the shared instance. + */ + private static EMFCompareRCPUIPlugin plugin; + + /** keep track of resources that should be freed when exiting. */ + private static Map resourcesMapper = new HashMap(); + + private AbstractRegistryEventListener groupProviderRegistryListener; + + private IItemRegistry groupItemRegistry; + + private IDifferenceGroupProvider.Descriptor.Registry groupProviderRegistry; + + private AbstractRegistryEventListener filterRegistryListener; + + private IDifferenceFilter.Registry filterRegistry; + + private DifferenceFilterManager filterManager; + + private AbstractRegistryEventListener accessorFactoryRegistryListener; + + private IAccessorFactory.Registry accessorFactoryRegistry; + + private AbstractRegistryEventListener differenceGroupExtenderRegistryListener; + + private IDifferenceGroupExtender.Registry differenceGroupExtenderRegistry; + + private Map matchEngineConfiguratorRegistry; + + private ConfigurationUIRegistryEventListener matchEngineConfiguratorRegistryListener; + + private AbstractRegistryEventListener contentMergeViewerCustomizationRegistryListener; + + private ContentMergeViewerCustomizationRegistry contentMergeViewerCustomizationRegistry; + + /** + * The constructor. + */ + public EMFCompareRCPUIPlugin() { + + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + + IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); + + groupItemRegistry = new ItemRegistry(); + DifferenceGroupManager groupManager = new DifferenceGroupManager(groupItemRegistry, + getPreferenceStore()); + groupProviderRegistry = new DifferenceGroupRegistryImpl(groupManager, groupItemRegistry); + groupProviderRegistryListener = new DifferenceGroupProviderExtensionRegistryListener(PLUGIN_ID, + GROUP_PROVIDER_PPID, getLog(), groupItemRegistry); + + extensionRegistry.addListener(groupProviderRegistryListener, PLUGIN_ID + "." + GROUP_PROVIDER_PPID); //$NON-NLS-1$ + groupProviderRegistryListener.readRegistry(extensionRegistry); + + filterManager = new DifferenceFilterManager(getPreferenceStore()); + filterRegistry = new DifferenceFilterRegistryImpl(filterManager); + filterRegistryListener = new DifferenceFilterExtensionRegistryListener(PLUGIN_ID, + FILTER_PROVIDER_PPID, getLog(), filterManager); + extensionRegistry.addListener(filterRegistryListener, PLUGIN_ID + "." + FILTER_PROVIDER_PPID); //$NON-NLS-1$ + filterRegistryListener.readRegistry(extensionRegistry); + + accessorFactoryRegistry = new AccessorFactoryRegistryImpl(); + accessorFactoryRegistryListener = new AccessorFactoryExtensionRegistryListener(PLUGIN_ID, + ACCESSOR_FACTORY_PPID, getLog(), accessorFactoryRegistry); + extensionRegistry.addListener(accessorFactoryRegistryListener, + PLUGIN_ID + "." + ACCESSOR_FACTORY_PPID); //$NON-NLS-1$ + accessorFactoryRegistryListener.readRegistry(extensionRegistry); + + differenceGroupExtenderRegistry = new DifferenceGroupExtenderRegistryImpl(); + differenceGroupExtenderRegistryListener = new DifferenceGroupExtenderRegistryListener(PLUGIN_ID, + DIFFERENCE_GROUP_EXTENDER_PPID, getLog(), differenceGroupExtenderRegistry); + extensionRegistry.addListener(differenceGroupExtenderRegistryListener, + PLUGIN_ID + "." + DIFFERENCE_GROUP_EXTENDER_PPID); //$NON-NLS-1$ + differenceGroupExtenderRegistryListener.readRegistry(extensionRegistry); + + matchEngineConfiguratorRegistry = new ConcurrentHashMap(); + matchEngineConfiguratorRegistryListener = new ConfigurationUIRegistryEventListener(PLUGIN_ID, + MATCH_ENGINE_FACTORY_CONFIGURATION_UI_PPID, getLog(), matchEngineConfiguratorRegistry, + EMFCompareRCPPlugin.getDefault().getMatchEngineFactoryDescriptorRegistry()); + extensionRegistry.addListener(matchEngineConfiguratorRegistryListener, + PLUGIN_ID + '.' + MATCH_ENGINE_FACTORY_CONFIGURATION_UI_PPID); + matchEngineConfiguratorRegistryListener.readRegistry(extensionRegistry); + + contentMergeViewerCustomizationRegistry = new ContentMergeViewerCustomizationRegistry(); + contentMergeViewerCustomizationRegistryListener = new ContentMergeViewerCustomizationRegistryListener( + PLUGIN_ID, CONTENT_CUSTOMIZATION_PPID, getLog(), contentMergeViewerCustomizationRegistry); + extensionRegistry.addListener(contentMergeViewerCustomizationRegistryListener, + PLUGIN_ID + '.' + CONTENT_CUSTOMIZATION_PPID); + contentMergeViewerCustomizationRegistryListener.readRegistry(extensionRegistry); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); + + extensionRegistry.removeListener(matchEngineConfiguratorRegistryListener); + matchEngineConfiguratorRegistry = null; + matchEngineConfiguratorRegistryListener = null; + + extensionRegistry.removeListener(differenceGroupExtenderRegistryListener); + differenceGroupExtenderRegistryListener = null; + differenceGroupExtenderRegistry = null; + + extensionRegistry.removeListener(accessorFactoryRegistryListener); + accessorFactoryRegistryListener = null; + accessorFactoryRegistry = null; + + extensionRegistry.removeListener(filterRegistryListener); + filterRegistryListener = null; + filterRegistry = null; + filterManager = null; + + extensionRegistry.removeListener(groupProviderRegistryListener); + groupProviderRegistryListener = null; + groupItemRegistry = null; + groupProviderRegistry = null; + + plugin = null; + disposeCachedImages(); + super.stop(context); + } + + /** + * Returns the shared instance. + * + * @return the shared instance + */ + public static EMFCompareRCPUIPlugin getDefault() { + return plugin; + } + + /** + * Log an {@link Exception} in the {@link #getLog() current logger}. + * + * @param e + * the exception to be logged. + */ + public void log(Throwable e) { + getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e)); + } + + /** + * Log the given message with the give severity level. Severity is one of {@link IStatus#INFO}, + * {@link IStatus#WARNING} and {@link IStatus#ERROR}. + * + * @param severity + * the severity of the message + * @param message + * the message + */ + public void log(int severity, String message) { + getLog().log(new Status(severity, PLUGIN_ID, message)); + } + + /** + * @return the groupProviderRegistry + * @since 4.0 + */ + public IDifferenceGroupProvider.Descriptor.Registry getDifferenceGroupProviderRegistry() { + return groupProviderRegistry; + } + + /** + * @return the item registry for group providers. + * @since 4.0 + */ + public IItemRegistry getItemDifferenceGroupProviderRegistry() { + return groupItemRegistry; + } + + /** + * @since 4.0 + */ + public IDifferenceFilter.Registry getDifferenceFilterRegistry() { + return filterRegistry; + } + + /** + * @return The Difference Filter manager. + * @since 4.0 + */ + public DifferenceFilterManager getDifferenceFilterManager() { + return filterManager; + } + + /** + * @return the registry + */ + public IAccessorFactory.Registry getAccessorFactoryRegistry() { + return accessorFactoryRegistry; + } + + /** + * @return the sub tree registry + * @since 4.0 + */ + public IDifferenceGroupExtender.Registry getDifferenceGroupExtenderRegistry() { + return differenceGroupExtenderRegistry; + } + + /** + * Returns the registry containing all known content merge viewer customizations. + * + * @return the {@link ContentMergeViewerCustomizationRegistry} containing all known content merge viewer + * customizations. + * @since 4.4 + */ + public ContentMergeViewerCustomizationRegistry getContentMergeViewerCustomizationRegistry() { + return contentMergeViewerCustomizationRegistry; + } + + /** + *

+ * returns a plugin image. The returned image does not need to be explicitly disposed. + *

+ * + * @param imagePath + * : plugin relative path to the image + * @return Image : plugin hosted image + */ + public static Image getImage(String imagePath) { + Image image = resourcesMapper.get(imagePath); + if (image == null) { + ImageDescriptor imageDescriptor = imageDescriptorFromPlugin(PLUGIN_ID, imagePath); + image = imageDescriptor.createImage(); + resourcesMapper.put(imagePath, image); + } + return image; + } + + /** + *

+ * returns a plugin image descriptor. + *

+ * + * @param imagePath + * : plugin relative path to the image + * @return ImageDescriptor : image descriptor. + */ + public static ImageDescriptor getImageDescriptor(String imagePath) { + return imageDescriptorFromPlugin(PLUGIN_ID, imagePath); + } + + /** + * Dispose image with the given id. + * + * @param id + * : dispose system resources associated with the image with the given id. + */ + public static void disposeImage(String id) { + Image image = resourcesMapper.remove(id); + if (image != null) { + image.dispose(); + } + } + + /** + * dispose system resources associated with cached images. + */ + public static void disposeCachedImages() { + Iterator iterator = resourcesMapper.values().iterator(); + while (iterator.hasNext()) { + iterator.next().dispose(); + } + resourcesMapper.clear(); + } + + /** + * Get the Match Engine Configurator Registry + * + * @return Map + * @since 4.0 + */ + public Map getMatchEngineConfiguratorRegistry() { + return matchEngineConfiguratorRegistry; + } + + /** + * Provide this plug-in's preference store, which searches values in {@link InstanceScope}, then + * {@link ConfigurationScope}, and then {@link DefaultScope}. + */ + @Override + public IPreferenceStore getPreferenceStore() { + ScopedPreferenceStore store = (ScopedPreferenceStore)super.getPreferenceStore(); + store.setSearchContexts(new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + return store; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/configuration/ICompareEvent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/configuration/ICompareEvent.java new file mode 100644 index 000000000..dc7ed6a69 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/configuration/ICompareEvent.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.configuration; + +/** + * Marker interface for all events related to EMF Compare. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface ICompareEvent { + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/ICompareAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/ICompareAccessor.java new file mode 100644 index 000000000..fe93d4cc8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/ICompareAccessor.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor; + +import com.google.common.collect.ImmutableList; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; + +/** + * An ICompareAccessor is an {@link ITypedElement} used to present an input object in the EMF Compare UI. + * + * @author Axel Richard + * @since 4.0 + */ +public interface ICompareAccessor extends ITypedElement { + + /** + * Returns the comparison object used by this accessor. + * + * @return the comparison object used by this accessor. + */ + Comparison getComparison(); + + /** + * Returns the initial item of this accessor. + * + * @return the initial item of this accessor. + */ + IMergeViewerItem getInitialItem(); + + /** + * Returns the list of items known by this accessor. + * + * @return the list of items known by this accessor. + */ + ImmutableList getItems(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IResourceContentsAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IResourceContentsAccessor.java new file mode 100644 index 000000000..de3da45a7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IResourceContentsAccessor.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor; + +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.ecore.resource.Resource; + +/** + * A specific {@link ICompareAccessor} for resource contents. This compare accessor known the resource where + * it comes from. + * + * @author Axel Richard + * @since 4.0 + */ +public interface IResourceContentsAccessor extends ICompareAccessor { + + /** + * Returns the resource of the model involved with the accessor given the side of the content merge viewer + * for which we want to know the resource. + * + * @param side + * the side of the content merge viewer for which we want the resource. + * @return the resource of the model involved with the accessor. + */ + Resource getResource(MergeViewerSide side); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IStructuralFeatureAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IStructuralFeatureAccessor.java new file mode 100644 index 000000000..80962c7df --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/IStructuralFeatureAccessor.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor; + +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * A specific {@link ICompareAccessor} for structural features. + * + * @author Mikael Barbero + */ +public interface IStructuralFeatureAccessor extends ICompareAccessor { + + /** + * Returns the structural feature for which an accessor is needed. + * + * @return the structural feature for which an accessor is needed. + */ + EStructuralFeature getStructuralFeature(); + + /** + * Returns the EObject associated with the structural feature. + * + * @param side + * the side of the content merge viewer for which we want the EObject associated with the + * structural feature. + * @return the EObject associated with the structural feature. + */ + EObject getEObject(MergeViewerSide side); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/factory/IAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/factory/IAccessorFactory.java new file mode 100644 index 000000000..70c53aad6 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/factory/IAccessorFactory.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; + +/** + * A factory of {@link ITypedElement}s. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface IAccessorFactory { + + /** + * Checks if the target object is applicable to the factory. + * + * @param target + * the object for which we want to know if it is applicable to the factory. + * @return true if the object is applicable to the factory, false otherwise. + */ + boolean isFactoryFor(Object target); + + /** + * The ranking of the factory. + * + * @return the ranking of the factory. + */ + int getRanking(); + + /** + * Set the ranking of the factory. + * + * @param value + * the ranking value. + */ + void setRanking(int value); + + /** + * Creates an {@link ITypedElement} from an {@link AdapterFactory} and a given object. This accessor is + * specific for the left side of the comparison. + * + * @param adapterFactory + * the given adapter factory. + * @param target + * the given object. + * @return an ITypedElement. + */ + ITypedElement createLeft(AdapterFactory adapterFactory, Object target); + + /** + * Creates an {@link ITypedElement} from an {@link AdapterFactory} and a given object. This accessor is + * specific for the right side of the comparison. + * + * @param adapterFactory + * the given adapter factory. + * @param target + * the given object. + * @return an ITypedElement. + */ + ITypedElement createRight(AdapterFactory adapterFactory, Object target); + + /** + * Creates an {@link ITypedElement} from an {@link AdapterFactory} and a given object. This accessor is + * specific for the ancestor side of the comparison. + * + * @param adapterFactory + * the given adapter factory. + * @param target + * the given object. + * @return an ITypedElement. + */ + ITypedElement createAncestor(AdapterFactory adapterFactory, Object target); + + /** + * The registry of {@link IAccessorFactory}. + * + * @author Mikael Barbero + * @since 4.0 + */ + interface Registry { + + /** + * Returns the highest ranking factory available for the given object. + * + * @param target + * the given object. + * @return the highest ranking factory available for the given object. + */ + IAccessorFactory getHighestRankingFactory(Object target); + + /** + * Returns all the factories available in the registry for the given object. + * + * @param target + * the given object. + * @return all the factories available in the registry for the given object. + */ + Collection getFactories(Object target); + + /** + * Add the given factory to the registry. + * + * @param factory + * the given factory. + * @return the given factory. + */ + IAccessorFactory add(IAccessorFactory factory); + + /** + * Remove the factory represented by the given class name. + * + * @param className + * the class name of the factory to removed. + * @return the factory removed. + */ + IAccessorFactory remove(String className); + + /** + * Clear the registry. + */ + void clear(); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/IStreamContentAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/IStreamContentAccessor.java new file mode 100644 index 000000000..fe68fe63d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/IStreamContentAccessor.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2000, 2013 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Mikael Barbero (mikael.barbero@obeo.fr) - Adapted for EMF Compare + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy; + +import java.io.InputStream; + +import org.eclipse.core.runtime.CoreException; + +/** + * An IStreamContentAccessor object represents a set of bytes which can be accessed by means of a + * stream. + *

+ * Clients may implement this interface, or use the standard implementation, BufferedContent. + *

+ *

+ * This was initially copy pasted from org.eclipse.compare.IStreamContentAccessor + *

+ * + * @see BufferedContent + * @author Ibm Corporation + * @since 4.0 + */ +public interface IStreamContentAccessor { + /** + * Returns an open InputStream for this object which can be used to retrieve the object's + * content. The client is responsible for closing the stream when finished. Returns null if + * this object has no streamable contents. + * + * @return an input stream containing the contents of this object + * @exception CoreException + * if the contents of this object could not be accessed + */ + InputStream getContents() throws CoreException; +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/ITypedElement.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/ITypedElement.java new file mode 100644 index 000000000..8cb4bcbf2 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/ITypedElement.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy; + +import org.eclipse.swt.graphics.Image; + +/** + * Interface for getting the name, image, and type for an object. + *

+ * These methods are typically used to present an input object in the compare UI (getName and + * getImage) and for finding a viewer for a given input type (getType). + *

+ * Clients may implement this interface. + * + * @author Ibm Corporation + * @since 4.0 + */ +public interface ITypedElement { + + /** + * Type for a folder input (value "FOLDER"). Folders are comparison elements that have no + * contents, only a name and children. + */ + String FOLDER_TYPE = "FOLDER"; //$NON-NLS-1$ + + /** + * Type for an element whose actual type is text (value "txt"). + */ + String TEXT_TYPE = "txt"; //$NON-NLS-1$ + + /** + * Type for an element whose actual type could not be determined. (value "???"). + */ + String UNKNOWN_TYPE = "???"; //$NON-NLS-1$ + + /** + * Returns the name of this object. The name is used when displaying this object in the UI. + * + * @return the name of this object + */ + String getName(); + + /** + * Returns an image for this object. This image is used when displaying this object in the UI. + * + * @return the image of this object or null if this type of input has no image + */ + Image getImage(); + + /** + * Returns the type of this object. For objects with a file name this is typically the file extension. For + * folders its the constant FOLDER_TYPE. The type is used for determining a suitable viewer + * for this object. + * + * @return the type of this object + */ + String getType(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/impl/AbstractTypedElementAdapter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/impl/AbstractTypedElementAdapter.java new file mode 100644 index 000000000..ee540caea --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/contentmergeviewer/accessor/legacy/impl/AbstractTypedElementAdapter.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor.legacy.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.provider.ExtendedAdapterFactoryItemDelegator; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory; + +/** + * An abstract implementation of {@link ITypedElement}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractTypedElementAdapter implements ITypedElement { + + /** The adapter factory to use to retrieve item. */ + private final AdapterFactory fAdapterFactory; + + /** The item delegator to use to retrieve item. */ + private final ExtendedAdapterFactoryItemDelegator itemDelegator; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapter factory used to create accessor. + */ + public AbstractTypedElementAdapter(AdapterFactory adapterFactory) { + fAdapterFactory = adapterFactory; + itemDelegator = new ExtendedAdapterFactoryItemDelegator(getRootAdapterFactory()); + } + + /** + * Gets the root factory if this local adapter factory is composed, otherwise just the local one. + * + * @return the root factory if this local adapter factory is composed, otherwise just the local one. + */ + protected AdapterFactory getRootAdapterFactory() { + if (fAdapterFactory instanceof ComposeableAdapterFactory) { + return ((ComposeableAdapterFactory)fAdapterFactory).getRootAdapterFactory(); + } + + return fAdapterFactory; + } + + /** + * Returns the adapter factory to use to retrieve item. + * + * @return the adapter factory to use to retrieve item. + */ + protected AdapterFactory getAdapterFactory() { + return fAdapterFactory; + } + + /** + * Returns the item delegator to use to retrieve item. + * + * @return the item delegator to use to retrieve item.. + */ + protected ExtendedAdapterFactoryItemDelegator getItemDelegator() { + return itemDelegator; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareConstants.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareConstants.java new file mode 100644 index 000000000..f5546d535 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareConstants.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 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; + +/** + * @author Mikael Barbero + */ +public final class EMFCompareConstants { + + private EMFCompareConstants() { + // prevents instantiation + } + + // ITypedElement#getType() + + public static final String NODE_TYPE__EMF_RESOURCESET = "NODE_TYPE__EMF_RESOURCESET"; //$NON-NLS-1$ + + public static final String NODE_TYPE__EMF_RESOURCE = "NODE_TYPE__EMF_RESOURCE"; //$NON-NLS-1$ + + public static final String NODE_TYPE__EMF_EOBJECT = "NODE_TYPE__EMF_EOBJECT"; //$NON-NLS-1$ + + /** + * If the list on any one of the sides we're trying to display in the UI contains more elements than the + * given threshold, don't try and compute the insertion index for differences merging. On the one hand, + * showing insertion points in lists with so many elements wouldn't really be human readable, on the other + * hand, trying to compute insertion indices for too large lists will easily result in OutOfMemoryErrors. + * For example, if the left and right sides contain 60000 elements, we'll end up trying to instantiate an + * array with the following signature: "int[60000][60000]" to compute the LCS (see DiffUtils). Such an + * array would cost 13GB of memory as a conservative estimate. + */ + public static final short LIST_SIZE_INSERTION_POINT_THRESHOLD = 10000; + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareRCPUIMessages.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareRCPUIMessages.java new file mode 100644 index 000000000..f9cd20aec --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/EMFCompareRCPUIMessages.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2006, 2013 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; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * Utility class to access externalized Strings for EMF Compare's rcp ui integration. + * + * @author Laurent Goubet + */ +public final class EMFCompareRCPUIMessages { + /** Full qualified path to the properties file in which to seek the keys. */ + private static final String BUNDLE_NAME = "org.eclipse.emf.compare.rcp.ui.internal.emfcomparercpuimessages"; //$NON-NLS-1$ + + /** Contains the locale specific {@link String}s needed by this plug-in. */ + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + /** + * Utility classes don't need to (and shouldn't) be instantiated. + */ + private EMFCompareRCPUIMessages() { + // prevents instantiation + } + + /** + * This will return an unformatted String from the resource bundle. + * + * @param key + * Key of the String we seek. + * @return An unformatted String from the bundle. + */ + private static String internalGetString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + /** + * Returns the specified {@link String} from the resource bundle. + * + * @param key + * Key of the String we seek. + * @return The String from the resource bundle associated with key. + * '!' + key + '!' will be returned in case we didn't find it in the bundle. + */ + public static String getString(String key) { + // Pass through MessageFormat so that we're consistent in the handling + // of special chars such as the + // apostrophe + return MessageFormat.format(internalGetString(key), new Object[] {}); + } + + /** + * Returns a String from the resource bundle bound with the given arguments. + * + * @param key + * Key of the String we seek. + * @param arguments + * Arguments for the String formatting. + * @return formatted {@link String}. + * @see MessageFormat#format(String, Object[]) + */ + public static String getString(String key, Object... arguments) { + if (arguments == null) { + return getString(key); + } + return MessageFormat.format(internalGetString(key), arguments); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IAdapterFactoryChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IAdapterFactoryChange.java new file mode 100644 index 000000000..c48b0bed1 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IAdapterFactoryChange.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * @author Mikael Barbero + */ +public interface IAdapterFactoryChange extends ICompareEvent { + + AdapterFactory getOldValue(); + + AdapterFactory getNewValue(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ICompareEditingDomainChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ICompareEditingDomainChange.java new file mode 100644 index 000000000..9c3148907 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ICompareEditingDomainChange.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration; + +import org.eclipse.emf.compare.domain.ICompareEditingDomain; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * @author Mikael Barbero + */ +public interface ICompareEditingDomainChange extends ICompareEvent { + + ICompareEditingDomain getOldValue(); + + ICompareEditingDomain getNewValue(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IComparisonAndScopeChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IComparisonAndScopeChange.java new file mode 100644 index 000000000..af277d119 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IComparisonAndScopeChange.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.scope.IComparisonScope; + +/** + * @author Mikael Barbero + */ +public interface IComparisonAndScopeChange { + + Comparison getOldComparison(); + + Comparison getNewComparison(); + + IComparisonScope getOldScope(); + + IComparisonScope getNewScope(); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java new file mode 100644 index 000000000..05ea62926 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IDiffRelationshipComputerChange.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2017 EclipseSource Services GmbH and others. + * 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: + * Martin Fleck - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.configuration; + +import org.eclipse.emf.compare.merge.IDiffRelationshipComputer; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * Event indicating a change in {@link IDiffRelationshipComputer}. + * + * @author Martin Fleck + */ +public interface IDiffRelationshipComputerChange extends ICompareEvent { + + /** + * Previous value of the {@link IDiffRelationshipComputer}. + * + * @return previous value of the {@link IDiffRelationshipComputer}. + */ + IDiffRelationshipComputer getOldValue(); + + /** + * New value of the {@link IDiffRelationshipComputer}. + * + * @return new value of the {@link IDiffRelationshipComputer}. + */ + IDiffRelationshipComputer getNewValue(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFComparatorChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFComparatorChange.java new file mode 100644 index 000000000..2e85fbfdd --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFComparatorChange.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration; + +import org.eclipse.emf.compare.EMFCompare; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * @author Mikael Barbero + */ +public interface IEMFComparatorChange extends ICompareEvent { + + EMFCompare getOldValue(); + + EMFCompare getNewValue(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java new file mode 100644 index 000000000..c3c661494 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IEMFCompareConfiguration.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013, 2018 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 + * Philip Langer - bug 514079 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.configuration; + +import com.google.common.eventbus.EventBus; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.EMFCompare; +import org.eclipse.emf.compare.domain.ICompareEditingDomain; +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.merge.IDiffRelationshipComputer; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.StructureMergeViewerGrouper; +import org.eclipse.emf.compare.scope.IComparisonScope; + +/** + * @author Mikael Barbero + */ +public interface IEMFCompareConfiguration { + + EventBus getEventBus(); + + ICompareEditingDomain getEditingDomain(); + + void setEditingDomain(ICompareEditingDomain editingDomain); + + StructureMergeViewerGrouper getStructureMergeViewerGrouper(); + + StructureMergeViewerFilter getStructureMergeViewerFilter(); + + AdapterFactory getAdapterFactory(); + + void setAdapterFactory(AdapterFactory adapterFactory); + + boolean isLeftEditable(); + + boolean isRightEditable(); + + Comparison getComparison(); + + void setComparisonAndScope(Comparison comparison, IComparisonScope comparisonScope); + + IComparisonScope getComparisonScope(); + + EMFCompare getEMFComparator(); + + void setEMFComparator(EMFCompare comparator); + + MergeMode getMergePreviewMode(); + + void setMergePreviewMode(MergeMode mergePreviewMode); + + IDiffRelationshipComputer getDiffRelationshipComputer(); + + void setDiffRelationshipComputer(IDiffRelationshipComputer diffRelationshipComputer); + + boolean getBooleanProperty(String key, boolean dflt); + + boolean isMirrored(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IMergePreviewModeChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IMergePreviewModeChange.java new file mode 100644 index 000000000..ede6b90e1 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/IMergePreviewModeChange.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration; + +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * @author Mikael Barbero + */ +public interface IMergePreviewModeChange extends ICompareEvent { + + MergeMode getOldValue(); + + MergeMode getNewValue(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/SideLabelProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/SideLabelProvider.java new file mode 100644 index 000000000..25afa60f4 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/SideLabelProvider.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * 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.configuration; + +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.swt.graphics.Image; + +/** + * @author Mikael Barbero + */ +public class SideLabelProvider extends AdapterImpl { + + private final String ancestorLabel; + + private final String leftLabel; + + private final String rightLabel; + + private final Image ancestorImage; + + private final Image leftImage; + + private final Image rightImage; + + public SideLabelProvider(String ancestorLabel, String leftLabel, String rightLabel, Image ancestorImage, + Image leftImage, Image rightImage) { + this.ancestorLabel = ancestorLabel; + this.leftLabel = leftLabel; + this.rightLabel = rightLabel; + this.ancestorImage = ancestorImage; + this.leftImage = leftImage; + this.rightImage = rightImage; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + */ + @Override + public boolean isAdapterForType(Object type) { + return type == SideLabelProvider.class; + } + + public String getAncestorLabel() { + return ancestorLabel; + } + + public String getLeftLabel() { + return leftLabel; + } + + public String getRightLabel() { + return rightLabel; + } + + public Image getAncestorImage() { + return ancestorImage; + } + + public Image getLeftImage() { + return leftImage; + } + + public Image getRightImage() { + return rightImage; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/AdapterFactoryChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/AdapterFactoryChange.java new file mode 100644 index 000000000..adcf23ad8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/AdapterFactoryChange.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IAdapterFactoryChange; + +public class AdapterFactoryChange extends CompareEvent implements IAdapterFactoryChange { + public AdapterFactoryChange(AdapterFactory oldValue, AdapterFactory newValue) { + super(oldValue, newValue); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEditingDomainChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEditingDomainChange.java new file mode 100644 index 000000000..dd5c19881 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEditingDomainChange.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.compare.domain.ICompareEditingDomain; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.ICompareEditingDomainChange; + +public class CompareEditingDomainChange extends CompareEvent implements ICompareEditingDomainChange { + + public CompareEditingDomainChange(ICompareEditingDomain oldValue, ICompareEditingDomain newValue) { + super(oldValue, newValue); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEvent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEvent.java new file mode 100644 index 000000000..97a984a24 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/CompareEvent.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * @author Mikael Barbero + */ +public class CompareEvent implements ICompareEvent { + + private final T oldValue; + + private final T newValue; + + protected CompareEvent(T oldValue, T newValue) { + this.oldValue = oldValue; + this.newValue = newValue; + } + + public T getOldValue() { + return oldValue; + } + + public T getNewValue() { + return newValue; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/ComparisonAndScopeChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/ComparisonAndScopeChange.java new file mode 100644 index 000000000..8f19e30eb --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/ComparisonAndScopeChange.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IComparisonAndScopeChange; +import org.eclipse.emf.compare.scope.IComparisonScope; + +public class ComparisonAndScopeChange implements ICompareEvent, IComparisonAndScopeChange { + private Comparison oldComparison; + + private Comparison newComparison; + + private IComparisonScope oldScope; + + private IComparisonScope newScope; + + public ComparisonAndScopeChange(Comparison oldComparison, Comparison newComparison, + IComparisonScope oldPredicate, IComparisonScope newScope) { + this.oldComparison = oldComparison; + this.newComparison = newComparison; + this.oldScope = oldPredicate; + this.newScope = newScope; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.configuration.IComparisonAndScopeChange#getOldComparison() + */ + public Comparison getOldComparison() { + return oldComparison; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.configuration.IComparisonAndScopeChange#getNewComparison() + */ + public Comparison getNewComparison() { + return newComparison; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.configuration.IComparisonAndScopeChange#getOldScope() + */ + public IComparisonScope getOldScope() { + return oldScope; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.configuration.IComparisonAndScopeChange#getNewScope() + */ + public IComparisonScope getNewScope() { + return newScope; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java new file mode 100644 index 000000000..302f47da3 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/DiffRelationshipComputerChange.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2017 EclipseSource Services GmbH and others. + * 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: + * Martin Fleck - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.configuration.impl; + +import org.eclipse.emf.compare.merge.IDiffRelationshipComputer; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IDiffRelationshipComputerChange; + +/** + * A change for {@link IDiffRelationshipComputer}. + * + * @author Martin Fleck + */ +public class DiffRelationshipComputerChange extends CompareEvent implements IDiffRelationshipComputerChange { + public DiffRelationshipComputerChange(IDiffRelationshipComputer oldValue, + IDiffRelationshipComputer newValue) { + super(oldValue, newValue); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/EMFComparatorChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/EMFComparatorChange.java new file mode 100644 index 000000000..fbd3e3b24 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/EMFComparatorChange.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.compare.EMFCompare; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFComparatorChange; + +public class EMFComparatorChange extends CompareEvent implements IEMFComparatorChange { + public EMFComparatorChange(EMFCompare oldValue, EMFCompare newValue) { + super(oldValue, newValue); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/MergePreviewModeChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/MergePreviewModeChange.java new file mode 100644 index 000000000..cdfdd4b28 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/impl/MergePreviewModeChange.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 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.configuration.impl; + +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IMergePreviewModeChange; + +public class MergePreviewModeChange extends CompareEvent implements IMergePreviewModeChange { + public MergePreviewModeChange(MergeMode oldValue, MergeMode newValue) { + super(oldValue, newValue); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/AbstractConfigurationUI.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/AbstractConfigurationUI.java new file mode 100644 index 000000000..f08b0eb26 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/AbstractConfigurationUI.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2014, 2017 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.configuration.ui; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Composite; +import org.osgi.service.prefs.Preferences; + +/** + * Abstract composite that is used to configure an item. The configuration will be stored in the + * {@link Preferences} passed in parameter. + * + * @author Arthur Daussy + */ +public abstract class AbstractConfigurationUI extends Composite { + /** The preference store. */ + private final IPreferenceStore store; + + /** + * Constructor. + * + * @param parent + * Parent {@link Composite}. + * @param style + * Style of this {@link Composite} + * @param store + * The {@link IPreferenceStore} to use for preferences, cannot be null + */ + public AbstractConfigurationUI(Composite parent, int style, IPreferenceStore store) { + super(parent, style); + this.store = checkNotNull(store); + } + + /** + * Content of this composite. This should be overriden by clients. + */ + public abstract void createContent(); + + /** + * Used to store the configuration. Implementation should store all the configuration in the + * {@link Preferences}. + */ + public abstract void storeConfiguration(); + + /** + * Called to restore default preferences. This should be used to reset the configuration in the store. + */ + public abstract void resetDefault(); + + /** + * Get the preference store used by this object. + * + * @return The preference store used by this object. + */ + protected IPreferenceStore getPreferenceStore() { + return store; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java new file mode 100644 index 000000000..70df1071b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/ConfigurationUIRegistryEventListener.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * 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.configuration.ui; + +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; + +/** + * Registry event listener used for {@link IConfiguratorUIRegistry} + * + * @author Arthur Daussy + */ +public class ConfigurationUIRegistryEventListener extends AbstractRegistryEventListener { + + private static final String ELEMENT_TAG = "configurator"; //$NON-NLS-1$ + + private static final String ITEM_TO_CONFIGURE_ATTR = "itemToConfigure"; //$NON-NLS-1$ + + private static final String UI_PROVIDER_ATTR = "uiProvider"; //$NON-NLS-1$ + + /** Storage for {@link IConfiguratorUIRegistry}. */ + private final Map registry; + + /** Mirror registry holding item to configure. */ + private final IItemRegistry registryOfConfiguredItem; + + /** + * Constructor. + * + * @param namespace + * The namespace of the extension point to be monitored. + * @param extensionPointID + * The extension point ID to be monitored + * @param log + * The log object to be used to log error and/or warning. + * @param registry + * that will be filled + * @param registryOfConfiguredItem + * Mirror registry holding item to configure. + */ + public ConfigurationUIRegistryEventListener(String namespace, String extensionPointID, ILog log, + Map registry, IItemRegistry registryOfConfiguredItem) { + super(namespace, extensionPointID, log); + this.registry = registry; + this.registryOfConfiguredItem = registryOfConfiguredItem; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + final boolean ret; + if (ELEMENT_TAG.equals(element.getName())) { + if (element.getAttribute(ITEM_TO_CONFIGURE_ATTR) == null) { + logMissingAttribute(element, ITEM_TO_CONFIGURE_ATTR); + ret = false; + } else if (element.getAttribute(ITEM_TO_CONFIGURE_ATTR) != null) { + Object itemToConfigure = registryOfConfiguredItem + .getItemDescriptor(element.getAttribute(ITEM_TO_CONFIGURE_ATTR)); + if (itemToConfigure == null) { + log(IStatus.WARNING, element, EMFCompareRCPUIMessages + .getString("ConfigurationUIRegistryEventListener.incorrectIdParameter.message")); //$NON-NLS-1$ + ret = false; + } else { + ret = true; + } + } else if (element.getAttribute(UI_PROVIDER_ATTR) == null) { + logMissingAttribute(element, UI_PROVIDER_ATTR); + ret = false; + } else { + ret = true; + } + } else { + ret = false; + } + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#addedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean addedValid(IConfigurationElement element) { + try { + Object configurator = element.createExecutableExtension(UI_PROVIDER_ATTR); + if (configurator instanceof IConfigurationUIFactory) { + IConfigurationUIFactory configurationFactory = (IConfigurationUIFactory)configurator; + String itemToConfigureID = element.getAttribute(ITEM_TO_CONFIGURE_ATTR); + IConfigurationUIFactory previous = registry.put(itemToConfigureID, configurationFactory); + if (previous != null) { + log(IStatus.WARNING, element, EMFCompareRCPUIMessages.getString("duplicate.extension", //$NON-NLS-1$ + registry.getClass().getName())); + } + } else { + log(IStatus.WARNING, element, EMFCompareRCPUIMessages.getString( + "ConfigurationUIRegistryEventListener.incorrectConfiguratorParameter.message")); //$NON-NLS-1$ + } + } catch (CoreException e) { + log(element, e); + } + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + return registry.remove(element.getAttribute(ITEM_TO_CONFIGURE_ATTR)) != null; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/IConfigurationUIFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/IConfigurationUIFactory.java new file mode 100644 index 000000000..3f0070681 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/IConfigurationUIFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.configuration.ui; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Composite; + +/** + * Factory for {@link AbstractConfigurationUI}. + * + * @author Arthur Daussy + */ +public interface IConfigurationUIFactory { + + /** + * Create an {@link AbstractConfigurationUI} + * + * @param parent + * Parent composite. + * @param style + * Style of the new {@link AbstractConfigurationUI} + * @param store + * {@link IPreferenceStore} to store configuration. + * @return Configuration UI + */ + AbstractConfigurationUI createUI(Composite parent, int style, IPreferenceStore store); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguatorUIFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguatorUIFactory.java new file mode 100644 index 000000000..66898f343 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguatorUIFactory.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.configuration.ui.match; + +import org.eclipse.emf.compare.rcp.internal.match.DefaultRCPMatchEngineFactory; +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.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Composite; + +/** + * IConfiguratorUIFactory for {@link DefaultRCPMatchEngineFactory} + * + * @author Arthur Daussy + */ +public class DefaultMatchEngineConfiguatorUIFactory implements IConfigurationUIFactory { + + public AbstractConfigurationUI createUI(Composite parent, int style, IPreferenceStore store) { + DefaultMatchEngineConfiguratorUI composite = new DefaultMatchEngineConfiguratorUI(parent, style, + store); + composite.createContent(); + return composite; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguratorUI.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguratorUI.java new file mode 100644 index 000000000..6c7683ea9 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/configuration/ui/match/DefaultMatchEngineConfiguratorUI.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * 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.configuration.ui.match; + +import com.google.common.base.Throwables; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.PojoObservables; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.SelectObservableValue; +import org.eclipse.emf.compare.rcp.internal.match.DefaultRCPMatchEngineFactory; +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.utils.UseIdentifiers; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * {@link AbstractConfigurationUI} for {@link DefaultRCPMatchEngineFactory}. + * + * @author Arthur Daussy + */ +public class DefaultMatchEngineConfiguratorUI extends AbstractConfigurationUI { + + /** Spacing between each element in the configuration composite. */ + private static final int COMPOSITE_VERTICAL_SPACING = 10; + + private static final int COMPOSITE_MARGIN = 5; + + private Button whenAvailableButton; + + private Button neverButton; + + private Button onlyButton; + + private DataHolder dataHolder; + + public DefaultMatchEngineConfiguratorUI(Composite parent, int style, IPreferenceStore store) { + super(parent, style, store); + } + + @Override + public void createContent() { + GridLayout gridLayout = new GridLayout(1, false); + gridLayout.marginWidth = COMPOSITE_MARGIN; + gridLayout.marginHeight = COMPOSITE_MARGIN; + gridLayout.verticalSpacing = COMPOSITE_VERTICAL_SPACING; + this.setLayout(gridLayout); + + Label text = new Label(this, SWT.WRAP); + text.setText( + EMFCompareRCPUIMessages.getString("DefaultMatchEngineConfiguratorUI.useIdentifier.label")); //$NON-NLS-1$ + text.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, true, false)); + + whenAvailableButton = new Button(this, SWT.RADIO | SWT.WRAP); + whenAvailableButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, true, false)); + whenAvailableButton.setText( + EMFCompareRCPUIMessages.getString("DefaultMatchEngineConfiguratorUI.whenAvailable.label")); //$NON-NLS-1$ + + onlyButton = new Button(this, SWT.RADIO | SWT.WRAP); + onlyButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, true, false)); + onlyButton.setText(EMFCompareRCPUIMessages.getString("DefaultMatchEngineConfiguratorUI.only.label")); //$NON-NLS-1$ + + neverButton = new Button(this, SWT.RADIO | SWT.WRAP); + neverButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, true, false)); + neverButton + .setText(EMFCompareRCPUIMessages.getString("DefaultMatchEngineConfiguratorUI.never.label")); //$NON-NLS-1$ + + UseIdentifiers defaultValue = DefaultRCPMatchEngineFactory.getUseIdentifierValue(); + dataHolder = new DataHolder(defaultValue); + + bindData(); + + } + + /** + * Bind radio button with data object + */ + private void bindData() { + DataBindingContext ctx = new DataBindingContext(); + IObservableValue whenAvailableBtnSelection = SWTObservables.observeSelection(whenAvailableButton); + IObservableValue onlyButtonSelection = SWTObservables.observeSelection(onlyButton); + IObservableValue neverButtonSelection = SWTObservables.observeSelection(neverButton); + SelectObservableValue featureRepoPolicyObservable = new SelectObservableValue(DataHolder.class); + featureRepoPolicyObservable.addOption(UseIdentifiers.WHEN_AVAILABLE, whenAvailableBtnSelection); + featureRepoPolicyObservable.addOption(UseIdentifiers.ONLY, onlyButtonSelection); + featureRepoPolicyObservable.addOption(UseIdentifiers.NEVER, neverButtonSelection); + ctx.bindValue(featureRepoPolicyObservable, PojoObservables.observeValue(dataHolder, "value")); //$NON-NLS-1$ + } + + /** + * {@inheritDoc} + */ + @Override + public void storeConfiguration() { + UseIdentifiers value = dataHolder.getValue(); + if (value != DefaultRCPMatchEngineFactory.DEFAULT_USE_IDENTIFIER_ATRIBUTE) { + getPreferenceStore().setValue(DefaultRCPMatchEngineFactory.USE_IDENTIFIER_ATTR, value.toString()); + } else { + getPreferenceStore().setToDefault(DefaultRCPMatchEngineFactory.USE_IDENTIFIER_ATTR); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void resetDefault() { + // Set default + if (whenAvailableButton != null && !whenAvailableButton.isDisposed()) { + whenAvailableButton.setSelection( + DefaultRCPMatchEngineFactory.DEFAULT_USE_IDENTIFIER_ATRIBUTE == UseIdentifiers.WHEN_AVAILABLE); + } + if (onlyButton != null && !onlyButton.isDisposed()) { + onlyButton.setSelection( + DefaultRCPMatchEngineFactory.DEFAULT_USE_IDENTIFIER_ATRIBUTE == UseIdentifiers.ONLY); + } + if (neverButton != null && !neverButton.isDisposed()) { + neverButton.setSelection( + DefaultRCPMatchEngineFactory.DEFAULT_USE_IDENTIFIER_ATRIBUTE == UseIdentifiers.NEVER); + } + dataHolder.setValue(DefaultRCPMatchEngineFactory.DEFAULT_USE_IDENTIFIER_ATRIBUTE); + try { + getPreferenceStore().setToDefault(DefaultRCPMatchEngineFactory.USE_IDENTIFIER_ATTR); + } catch (IllegalStateException e) { + Throwables.propagate(e); + } + } + + /** + * POJO holding data. + * + * @author Arthur Daussy + */ + private static final class DataHolder { + + private UseIdentifiers value; + + public DataHolder(UseIdentifiers value) { + super(); + this.value = value; + } + + public UseIdentifiers getValue() { + return value; + } + + public void setValue(UseIdentifiers value) { + this.value = value; + } + + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategy.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategy.java new file mode 100644 index 000000000..af652d88d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategy.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource Muenchen GmbH and others. + * 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: + * Philip Langer - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; + +/** + * A strategy for updating the model with changes made from within a content merge viewer. + * + * @author Philip Langer + */ +public interface IModelUpdateStrategy { + + /** + * Specifies whether the value in the model can to be updated on the given {@code side}. + * + * @param diff + * The diff acting as context of the potential model update. + * @param side + * The side to check. + * @return true if the value can be updated, false otherwise. + */ + public boolean canUpdate(Diff diff, MergeViewerSide side); + + /** + * Returns a command for updating the underlying model with the given {@code newValue} on the given + * {@code side}. + * + * @param diff + * The diff acting as context of the model update. + * @param newValue + * The new value to be set. + * @param side + * The side on which the update is to be performed. + * @return A command to perform the model update. + */ + public Command getModelUpdateCommand(Diff diff, Object newValue, MergeViewerSide side); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategyProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategyProvider.java new file mode 100644 index 000000000..e6adaeedb --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/IModelUpdateStrategyProvider.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource Muenchen GmbH and others. + * 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: + * Philip Langer - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer; + +/** + * Provider for {@link IModelUpdateStrategy model update strategies}. + * + * @author Philip Langer + */ +public interface IModelUpdateStrategyProvider { + + /** + * Returns the model update strategy to be used for updating the model. + * + * @return the model update strategy to be used for updating the model. + */ + public IModelUpdateStrategy getModelUpdateStrategy(); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/SingleValuedAttributeModelUpdateStrategy.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/SingleValuedAttributeModelUpdateStrategy.java new file mode 100644 index 000000000..0cf312667 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/SingleValuedAttributeModelUpdateStrategy.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource Muenchen GmbH and others. + * 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: + * Philip Langer - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer; + +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.internal.utils.ComparisonUtil; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.utils.IEqualityHelper; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.command.ChangeCommand; + +/** + * A {@link IModelUpdateStrategy} for single-valued {@link EAttribute EAttributes}. + *

+ * This strategy is tolerant in the sense that it will not throw exceptions if the input is not a supported + * {@link AttributeChange}. In this case, this strategy will return false on + * {@link #canUpdate(Diff, MergeViewerSide)} and return a command on + * {@link #getModelUpdateCommand(Diff, Object, MergeViewerSide)} that specifies false on + * {@link Command#canExecute()}. Therefore, it can be used as default strategy. + *

+ * + * @author Philip Langer + */ +public class SingleValuedAttributeModelUpdateStrategy implements IModelUpdateStrategy { + + /** + * {@inheritDoc} + * + * @see IModelUpdateStrategy#canUpdate(Diff, MergeViewerSide) + */ + public boolean canUpdate(Diff diff, MergeViewerSide side) { + return isSingleValuedAttributeChange(diff) && haveTargetObject(diff, side); + } + + /** + * Specifies whether the given {@code diff} is an {@link AttributeChange} of a single-valued attribute. + * + * @param diff + * The diff to check. + * @return true if it is a change of a single-valued attribute, false otherwise. + */ + private boolean isSingleValuedAttributeChange(Diff diff) { + return diff instanceof AttributeChange && !((AttributeChange)diff).getAttribute().isMany(); + } + + /** + * Specifies whether we have a target object based on the {@link Diff#getMatch() match} of the given + * {@code diff} on the given {@code side}. + * + * @param diff + * The diff to check. + * @param side + * The side to check on. + * @return true if we have a target object, false otherwise. + */ + private boolean haveTargetObject(Diff diff, MergeViewerSide side) { + return getTargetObject(diff, side) != null; + } + + /** + * Returns the target object for the {@link Diff#getMatch() match} of the given {@code diff} on the given + * {@code side}. + * + * @param diff + * The diff to get the target object for. + * @param side + * The side to get the target object from. + * @return The target object. + */ + private EObject getTargetObject(Diff diff, MergeViewerSide side) { + return MergeViewerUtil.getEObject(diff.getMatch(), side); + } + + /** + * {@inheritDoc} + * + * @see IModelUpdateStrategy#getModelUpdateCommand(Diff, Object, MergeViewerSide) + */ + public Command getModelUpdateCommand(final Diff diff, final Object newValue, final MergeViewerSide side) { + final EObject targetObject = getTargetObject(diff, side); + return new ChangeCommand(targetObject) { + @Override + public boolean canExecute() { + return canUpdate(diff, side) && needsUpdate(diff, newValue, side) && super.canExecute(); + } + + @Override + protected void doExecute() { + final EAttribute eAttribute = ((AttributeChange)diff).getAttribute(); + targetObject.eSet(eAttribute, newValue); + } + }; + } + + /** + * Specifies whether the value in the model needs to be updated with the given {@code newValue} on the + * given {@code side}. + * + * @param diff + * The diff acting as context of the potential model update. + * @param newValue + * The potentially changed new value to be checked against. + * @param side + * The side to check. + * @return true if an update is necessary, false otherwise. + */ + private boolean needsUpdate(Diff diff, Object newValue, MergeViewerSide side) { + final IEqualityHelper equalityHelper = ComparisonUtil.getComparison(diff).getEqualityHelper(); + final EObject eObject = getTargetObject(diff, side); + final EAttribute eAttribute = ((AttributeChange)diff).getAttribute(); + final Object oldValue = getStringValue(eObject, eAttribute); + return !equalityHelper.matchingAttributeValues(newValue, oldValue); + } + + /** + * Returns the value as String of the given {@code eAttribute} in the given {@code eObject}. + * + * @param eObject + * The EObject containing the attribute value. + * @param eAttribute + * The EAttribute to get its value. + * @return The String representation of the value. + */ + private String getStringValue(final EObject eObject, final EAttribute eAttribute) { + final EDataType eAttributeType = eAttribute.getEAttributeType(); + final Object value; + if (eObject == null) { + value = null; + } else { + value = ReferenceUtil.safeEGet(eObject, eAttribute); + } + return EcoreUtil.convertToString(eAttributeType, value); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/TypeConstants.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/TypeConstants.java new file mode 100644 index 000000000..1ec091914 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/TypeConstants.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer; + +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; + +/** + * Constants used by org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement + * implementations. + * + * @author Mikael Barbero + * @since 4.0 + */ +public final class TypeConstants { + + /** Used by accessors displaying diffs as a tree. */ + public static final String TYPE_ETREE_DIFF = EMFCompareRCPUIPlugin.PLUGIN_ID + ".eTreeDiff"; //$NON-NLS-1$ + + /** Used by accessors displaying diffs as a list. */ + public static final String TYPE_ELIST_DIFF = EMFCompareRCPUIPlugin.PLUGIN_ID + ".eListDiff"; //$NON-NLS-1$ + + /** Used by accessors displaying diffs as text. */ + public static final String TYPE_ETEXT_DIFF = EMFCompareRCPUIPlugin.PLUGIN_ID + ".eTextDiff"; //$NON-NLS-1$ + + /** Used by accessors displaying diffs as resource. */ + public static final String TYPE_ERESOURCE_DIFF = EMFCompareRCPUIPlugin.PLUGIN_ID + ".eResourceDiff"; //$NON-NLS-1$ + + /** Used by accessors displaying matches. */ + public static final String TYPE_EMATCH = EMFCompareRCPUIPlugin.PLUGIN_ID + ".eMatch"; //$NON-NLS-1$ + + /** Used when the comparison failed and we want to fallback to text merge. */ + public static final String TYPE_FALLBACK_TEXT = EMFCompareRCPUIPlugin.PLUGIN_ID + ".fallbackText"; //$NON-NLS-1$ + + /** + * Private constructor. + */ + private TypeConstants() { + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AbstractAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AbstractAccessorFactory.java new file mode 100644 index 000000000..ddbcba90f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AbstractAccessorFactory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory; + +/** + * An abstract implementation of {@link IAccessorFactory}. + * + * @author Axel Richard + * @since 4.0 + */ +public abstract class AbstractAccessorFactory implements IAccessorFactory { + + /** The ranking of this factory. */ + private int ranking; + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#getRanking() + */ + public int getRanking() { + return ranking; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#setRanking(int) + */ + public void setRanking(int r) { + ranking = r; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryExtensionRegistryListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryExtensionRegistryListener.java new file mode 100644 index 000000000..2536ac8a8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryExtensionRegistryListener.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory; + +/** + * The default concrete implementation of {@link AbstractRegistryEventListener}. + * + * @author Axel Richard + * @since 4.0 + */ +public class AccessorFactoryExtensionRegistryListener extends AbstractRegistryEventListener { + + /** TAG_FACTORY. */ + static final String TAG_FACTORY = "factory"; //$NON-NLS-1$ + + /** ATT_CLASS. */ + static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + /** ATT_RANKING. */ + static final String ATT_RANKING = "ranking"; //$NON-NLS-1$ + + /** The IAccessorFactory.Registry to listen. */ + private final IAccessorFactory.Registry registry; + + /** + * Default constructor. + * + * @param pluginID + * The namespace of the extension point to be monitored. + * @param extensionPointID + * The extension point ID to be monitored. + * @param log + * The log object to be used to log error and/or warning. + * @param registry + * The {@link IAccessorFactory.Registry} to listen. + */ + public AccessorFactoryExtensionRegistryListener(String pluginID, String extensionPointID, ILog log, + IAccessorFactory.Registry registry) { + super(pluginID, extensionPointID, log); + this.registry = registry; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + final boolean valid; + if (element.getName().equals(TAG_FACTORY)) { + if (element.getAttribute(ATT_CLASS) == null) { + logMissingAttribute(element, ATT_CLASS); + valid = false; + } else if (element.getAttribute(ATT_RANKING) == null) { + String rankingStr = element.getAttribute(ATT_RANKING); + try { + Integer.parseInt(rankingStr); + } catch (NumberFormatException nfe) { + log(IStatus.ERROR, element, "Attribute '" + ATT_RANKING //$NON-NLS-1$ + + "' is malformed, should be an integer."); //$NON-NLS-1$ + } + logMissingAttribute(element, ATT_RANKING); + valid = false; + } else { + valid = true; + } + } else { + valid = false; + } + return valid; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#addedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean addedValid(IConfigurationElement element) { + try { + IAccessorFactory factory = (IAccessorFactory)element.createExecutableExtension(ATT_CLASS); + factory.setRanking(Integer.parseInt(element.getAttribute(ATT_RANKING))); + IAccessorFactory previous = registry.add(factory); + if (previous != null) { + log(IStatus.WARNING, element, "The accessor factory '" + factory.getClass().getName() //$NON-NLS-1$ + + "' is registered twice."); //$NON-NLS-1$ + } + } catch (CoreException e) { + log(element, e); + } + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + registry.remove(element.getAttribute(ATT_CLASS)); + return true; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryRegistryImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryRegistryImpl.java new file mode 100644 index 000000000..345eb144b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/AccessorFactoryRegistryImpl.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Lists.newArrayList; + +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory; + +/** + * The default implementation of {@link IAccessorFactory.Registry}. + * + * @author Axel Richard + * @since 4.0 + */ +public class AccessorFactoryRegistryImpl implements IAccessorFactory.Registry { + + /** A map between IAccessorFactory and their class names. */ + private final Map map; + + /** + * Default constructor. + */ + public AccessorFactoryRegistryImpl() { + map = new ConcurrentHashMap(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory.Registry#getHighestRankingFactory(java.lang.Object) + */ + public IAccessorFactory getHighestRankingFactory(Object target) { + Iterator factories = getFactories(target).iterator(); + + IAccessorFactory ret = null; + + if (factories.hasNext()) { + IAccessorFactory highestRanking = factories.next(); + while (factories.hasNext()) { + IAccessorFactory factory = factories.next(); + if (factory.getRanking() > highestRanking.getRanking()) { + highestRanking = factory; + } + } + ret = highestRanking; + } + + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory.Registry#getFactories(java.lang.Object) + */ + // safe thanks to the isFactoryFor filter + public List getFactories(Object target) { + Iterable factories = filter(map.values(), isFactoryFor(target)); + List ret = newArrayList(); + for (IAccessorFactory factory : factories) { + ret.add(factory); + } + return ret; + } + + /** + * A predicate to know if the factory is applicable to the given object. + * + * @param target + * the given object. + * @return true, if the factory is applicable to the given object, false otherwise. + */ + static final Predicate isFactoryFor(final Object target) { + return new Predicate() { + /** + * {@inheritDoc} + * + * @see com.google.common.base.Predicate#apply(java.lang.Object) + */ + public boolean apply(IAccessorFactory d) { + return d.isFactoryFor(target); + } + }; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory.Registry#add(java.lang.Object) + */ + public IAccessorFactory add(IAccessorFactory factory) { + Preconditions.checkNotNull(factory); + return map.put(factory.getClass().getName(), factory); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory.Registry#remove(java.lang.Object) + */ + public IAccessorFactory remove(String className) { + return map.remove(className); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory.Registry#clear() + */ + public void clear() { + map.clear(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ComparisonAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ComparisonAccessorFactory.java new file mode 100644 index 000000000..cfd682343 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ComparisonAccessorFactory.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.legacy.impl.TypedNotifier; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * {@link Comparison} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ComparisonAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + return target instanceof Comparison; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + if (target instanceof Notifier) { + return new TypedNotifier(adapterFactory, (Notifier)target); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + if (target instanceof Notifier) { + return new TypedNotifier(adapterFactory, (Notifier)target); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + if (target instanceof Notifier) { + return new TypedNotifier(adapterFactory, (Notifier)target); + } + return null; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ContainmentReferenceChangeAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ContainmentReferenceChangeAccessorFactory.java new file mode 100644 index 000000000..7cdfe67a2 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ContainmentReferenceChangeAccessorFactory.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ContainmentReferenceChangeAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * containment {@link ReferenceChange} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ContainmentReferenceChangeAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + final boolean isFactoryFor; + if (target instanceof ReferenceChange) { + isFactoryFor = ((ReferenceChange)target).getReference().isContainment(); + } else if (target instanceof Diff) { + Diff primeRefining = ((Diff)target).getPrimeRefining(); + isFactoryFor = primeRefining instanceof ReferenceChange + && ((ReferenceChange)primeRefining).getReference().isContainment(); + } else { + isFactoryFor = false; + } + return isFactoryFor; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + ReferenceChange referenceChange = getAppropriateReferenceChange(target); + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, referenceChange, + MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + ReferenceChange referenceChange = getAppropriateReferenceChange(target); + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, referenceChange, + MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + ReferenceChange referenceChange = getAppropriateReferenceChange(target); + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, referenceChange, + MergeViewerSide.ANCESTOR); + } + + /** + * Returns the appropriate reference change. If the given object has a prime refining that is a reference + * change, returns this reference change. If the given object is a reference change, returns it. + * Otherwise, returns null. + * + * @param target + * the given object. + * @return the appropriate reference change. + */ + private ReferenceChange getAppropriateReferenceChange(Object target) { + final ReferenceChange referenceChange; + if (target instanceof ReferenceChange) { + referenceChange = (ReferenceChange)target; + } else if (((Diff)target).getPrimeRefining() instanceof ReferenceChange) { + referenceChange = (ReferenceChange)((Diff)target).getPrimeRefining(); + } else { + referenceChange = null; + } + return referenceChange; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapChangeMoveAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapChangeMoveAccessorFactory.java new file mode 100644 index 000000000..8a3ed2d78 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapChangeMoveAccessorFactory.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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.contentmergeviewer.accessor.factory.impl; + +import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isFeatureMapContainment; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ContainmentReferenceChangeAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * FeatureMapChanges of kind DifferenceKind.MOVE (represent an entry that moved from map to another). + * + * @author Axel Richard + * @since 4.0 + */ +public class FeatureMapChangeMoveAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + if (target instanceof FeatureMapChange) { + FeatureMapChange featureMapChange = (FeatureMapChange)target; + return featureMapChange.getKind() == DifferenceKind.MOVE + && isFeatureMapContainment(featureMapChange); + } + return false; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new ContainmentReferenceChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.ANCESTOR); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapKeyChangeAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapKeyChangeAccessorFactory.java new file mode 100644 index 000000000..d35579ae7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/FeatureMapKeyChangeAccessorFactory.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.FeatureMapKeyChangeAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * FeatureMapChanges of kind DifferenceKind.CHANGE (represent a value that changed his key). + * + * @author Axel Richard + * @since 4.0 + */ +public class FeatureMapKeyChangeAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + if (target instanceof FeatureMapChange) { + FeatureMapChange featureMapChange = (FeatureMapChange)target; + return featureMapChange.getKind() == DifferenceKind.CHANGE; + } + return false; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new FeatureMapKeyChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new FeatureMapKeyChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new FeatureMapKeyChangeAccessorImpl(adapterFactory, (FeatureMapChange)target, + MergeViewerSide.ANCESTOR); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ManyStructuralFeatureAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ManyStructuralFeatureAccessorFactory.java new file mode 100644 index 000000000..d18d03574 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ManyStructuralFeatureAccessorFactory.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import static org.eclipse.emf.compare.internal.utils.ComparisonUtil.isFeatureMapContainment; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ManyStructuralFeatureAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * multi-valued structural feature objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ManyStructuralFeatureAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + EStructuralFeature eStructuralFeature = null; + if (target instanceof ReferenceChange) { + eStructuralFeature = ((ReferenceChange)target).getReference(); + } else if (target instanceof AttributeChange) { + eStructuralFeature = ((AttributeChange)target).getAttribute(); + } else if (target instanceof FeatureMapChange) { + FeatureMapChange featureMapChange = (FeatureMapChange)target; + DifferenceKind kind = featureMapChange.getKind(); + if (kind != DifferenceKind.CHANGE && kind != DifferenceKind.MOVE + || (kind == DifferenceKind.MOVE && !isFeatureMapContainment(featureMapChange))) { + eStructuralFeature = featureMapChange.getAttribute(); + } + } else if (target instanceof Diff) { + Diff primeRefining = ((Diff)target).getPrimeRefining(); + if (primeRefining instanceof ReferenceChange) { + eStructuralFeature = ((ReferenceChange)primeRefining).getReference(); + } + } + + if (eStructuralFeature != null) { + return eStructuralFeature.isMany(); + } + + return false; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new ManyStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new ManyStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new ManyStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.ANCESTOR); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java new file mode 100644 index 000000000..562a1b337 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchAccessorFactory.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.MatchAccessor; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.utils.MatchUtil; +import org.eclipse.emf.ecore.EObject; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * {@link Match} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class MatchAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + return target instanceof Match; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new MatchAccessor(adapterFactory, (Match)target, getContainmentReferenceChange((Match)target), + MergeViewerSide.ANCESTOR); + } + + /** + * Some Matches are related to an object that has been either added or deleted. In these cases, this + * method returns the Diff representing this addition or deletion. In other cases, this method returns + * null. + * + * @param match + * the given Match. + * @return the Diff on the object related to the given Match if it exists, null otherwise. + */ + private Diff getContainmentReferenceChange(Match match) { + final Iterable addOrDeleteContainmentDiffs = MatchUtil.findAddOrDeleteContainmentDiffs(match); + if (addOrDeleteContainmentDiffs != null) { + final EObject left = match.getLeft(); + final EObject right = match.getRight(); + final EObject origin = match.getOrigin(); + for (Diff diff : addOrDeleteContainmentDiffs) { + final Object diffValue = MatchUtil.getValue(diff); + if (diffValue != null + && (diffValue.equals(left) || diffValue.equals(right) || diffValue.equals(origin))) { + return diff; + } + } + } + return null; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchResourceAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchResourceAccessorFactory.java new file mode 100644 index 000000000..aef550a08 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/MatchResourceAccessorFactory.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ResourceStreamAccessorImpl; +import org.eclipse.emf.ecore.resource.Resource; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * {@link MatchResource} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class MatchResourceAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + return target instanceof MatchResource; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + MatchResource matchResource = (MatchResource)target; + Resource resource = matchResource.getLeft(); + if (resource != null) { + return new ResourceStreamAccessorImpl(adapterFactory, resource); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + MatchResource matchResource = (MatchResource)target; + Resource resource = matchResource.getRight(); + if (resource != null) { + return new ResourceStreamAccessorImpl(adapterFactory, resource); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + MatchResource matchResource = (MatchResource)target; + Resource resource = matchResource.getOrigin(); + if (resource != null) { + return new ResourceStreamAccessorImpl(adapterFactory, resource); + } + return null; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ResourceContentsAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ResourceContentsAccessorFactory.java new file mode 100644 index 000000000..a317415bc --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/ResourceContentsAccessorFactory.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ResourceContentsAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * {@link ResourceAttachmentChange} objects. + * + * @author Axel Richard + * @since 4.0 + */ +public class ResourceContentsAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + return target instanceof ResourceAttachmentChange; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new ResourceContentsAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new ResourceContentsAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new ResourceContentsAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.ANCESTOR); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/SingleStructuralFeatureAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/SingleStructuralFeatureAccessorFactory.java new file mode 100644 index 000000000..52206f37d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/SingleStructuralFeatureAccessorFactory.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.SingleStructuralFeatureAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.ecore.EStructuralFeature; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * mono-valued structural feature objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class SingleStructuralFeatureAccessorFactory extends AbstractAccessorFactory { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + EStructuralFeature eStructuralFeature = null; + if (target instanceof ReferenceChange) { + eStructuralFeature = ((ReferenceChange)target).getReference(); + } else if (target instanceof AttributeChange) { + eStructuralFeature = ((AttributeChange)target).getAttribute(); + } else if (target instanceof Diff) { + Diff primeRefining = ((Diff)target).getPrimeRefining(); + if (primeRefining instanceof ReferenceChange) { + eStructuralFeature = ((ReferenceChange)primeRefining).getReference(); + } + } + + if (eStructuralFeature != null) { + return !eStructuralFeature.isMany(); + } + + return false; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + return new SingleStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.LEFT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + return new SingleStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, MergeViewerSide.RIGHT); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + return new SingleStructuralFeatureAccessorImpl(adapterFactory, (Diff)target, + MergeViewerSide.ANCESTOR); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/StringAttributeChangeAccessorFactory.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/StringAttributeChangeAccessorFactory.java new file mode 100644 index 000000000..d51c52674 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/factory/impl/StringAttributeChangeAccessorFactory.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2012, 2015 Obeo and others. + * 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 + * Philip Langer - introduced model update strategy provider (bug 457117) + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.factory.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.IModelUpdateStrategy; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.IModelUpdateStrategyProvider; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.SingleValuedAttributeModelUpdateStrategy; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.StringAttributeChangeAccessor; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory} for + * string-typed {@link AttributeChange} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class StringAttributeChangeAccessorFactory extends AbstractAccessorFactory implements IModelUpdateStrategyProvider { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#isFactoryFor(java.lang.Object) + */ + public boolean isFactoryFor(Object target) { + if (target instanceof AttributeChange) { + EAttribute attribute = ((AttributeChange)target).getAttribute(); + return attribute.getEAttributeType().getInstanceClass() == String.class && !attribute.isMany(); + } + + return false; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) { + AttributeChange attributeChange = (AttributeChange)target; + EObject left = attributeChange.getMatch().getLeft(); + if (left != null) { + return new StringAttributeChangeAccessor(left, (AttributeChange)target); + } else { + return null; + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createRight(AdapterFactory adapterFactory, Object target) { + AttributeChange attributeChange = (AttributeChange)target; + EObject right = attributeChange.getMatch().getRight(); + if (right != null) { + return new StringAttributeChangeAccessor(right, (AttributeChange)target); + } else { + return null; + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.factory.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory, + * java.lang.Object) + */ + public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) { + AttributeChange attributeChange = (AttributeChange)target; + EObject ancestor = attributeChange.getMatch().getOrigin(); + if (ancestor != null) { + return new StringAttributeChangeAccessor(ancestor, (AttributeChange)target); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see IModelUpdateStrategyProvider#getModelUpdateStrategy() + */ + public IModelUpdateStrategy getModelUpdateStrategy() { + return new SingleValuedAttributeModelUpdateStrategy(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/AbstractStructuralFeatureAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/AbstractStructuralFeatureAccessor.java new file mode 100644 index 000000000..79ae48025 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/AbstractStructuralFeatureAccessor.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - compute differences lazily + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl; + +import static com.google.common.collect.Iterables.filter; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl.AbstractTypedElementAdapter; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * An abstract implementation of {@link IStructuralFeatureAccessor}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractStructuralFeatureAccessor extends AbstractTypedElementAdapter implements IStructuralFeatureAccessor { + + /** The diff associated with this accessor. */ + private final Diff fDiff; + + /** The side of the accessor. */ + private final MergeViewerSide fSide; + + /** The match that owns the diff associated with this accessor. */ + private final Match fOwnerMatch; + + /** The structural feature associated with his accessor. */ + private final EStructuralFeature fStructuralFeature; + + /** The list of diff that apply on the structural feature. */ + private ImmutableList fDifferences; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapater factory used to create the accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of the accessor. + */ + public AbstractStructuralFeatureAccessor(AdapterFactory adapterFactory, Diff diff, MergeViewerSide side) { + super(adapterFactory); + fDiff = diff; + fSide = side; + fOwnerMatch = diff.getMatch(); + fStructuralFeature = getAffectedFeature(diff); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor#getComparison() + */ + public Comparison getComparison() { + return fOwnerMatch.getComparison(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem() + */ + public IMergeViewerItem getInitialItem() { + IMergeViewerItem ret = null; + ImmutableList items = getItems(); + for (IMergeViewerItem item : items) { + Diff diff = item.getDiff(); + if (diff == fDiff) { + ret = item; + } + } + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem() + */ + public EObject getEObject(MergeViewerSide side) { + return MergeViewerUtil.getEObject(fOwnerMatch, side); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor#getStructuralFeature() + */ + public EStructuralFeature getStructuralFeature() { + return fStructuralFeature; + } + + /** + * Returns the side of the accessor. + * + * @return the side of the accessor. + */ + protected final MergeViewerSide getSide() { + return fSide; + } + + /** + * Returns the list of diff that apply on the structural feature. + * + * @return the list of diff that apply on the structural feature. + */ + protected final ImmutableList getDifferences() { + if (fDifferences == null) { + fDifferences = computeDifferences(); + } + return fDifferences; + } + + /** + * Compute the differences that apply on the structural feature. + * + * @return the list of diff that apply on the structural feature. + */ + protected ImmutableList computeDifferences() { + List siblingDifferences = fOwnerMatch.getDifferences(); + // We'll display all diffs on the same reference, excluding the pseudo conflicts. + return ImmutableList.copyOf(filter(siblingDifferences, onFeature(fStructuralFeature.getName()))); + } + + /** + * Returns the structural feature affected by the given diff, if any. + * + * @param diff + * The diff from which we need to retrieve a feature. + * @return The feature affected by this {@code diff}, if any. null if none. + */ + protected EStructuralFeature getAffectedFeature(Diff diff) { + return MergeViewerUtil.getAffectedFeature(diff); + } + + /** + * Returns the initial diff associated with this accessor. + * + * @return the initial diff. + */ + protected final Diff getInitialDiff() { + return fDiff; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + return this.getClass().getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + return ExtendedImageRegistry.INSTANCE.getImage(getItemDelegator().getImage(fStructuralFeature)); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + return TypeConstants.TYPE_ELIST_DIFF; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ContainmentReferenceChangeAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ContainmentReferenceChangeAccessorImpl.java new file mode 100644 index 000000000..1840be822 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ContainmentReferenceChangeAccessorImpl.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2012, 2015 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.contentmergeviewer.accessor.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.getFirst; +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.internal.util.ResourceUIUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.ecore.EObject; + +/** + * A specific {@link AbstractStructuralFeatureAccessor} for containment + * {@link org.eclipse.emf.compare.ReferenceChange} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ContainmentReferenceChangeAccessorImpl extends AbstractStructuralFeatureAccessor { + + /** + * {@inheritDoc}. + * + * @see org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.AbstractStructuralFeatureAccessor#AbstractStructuralFeatureAccessor(org.eclipse.emf.common.notify.AdapterFactory, + * org.eclipse.emf.compare.Diff, + * org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide) + */ + public ContainmentReferenceChangeAccessorImpl(AdapterFactory adapterFactory, Diff diff, + MergeViewerSide side) { + super(adapterFactory, diff, side); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.AbstractStructuralFeatureAccessor# + * computeDifferences() + */ + @Override + protected ImmutableList computeDifferences() { + List allDifferences = getComparison().getDifferences(); + return ImmutableList. copyOf(filter(allDifferences, CONTAINMENT_REFERENCE_CHANGE)); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getInitialItem() + */ + @Override + public IMergeViewerItem getInitialItem() { + Diff initialDiff = getInitialDiff(); + EObject diffValue = (EObject)MergeViewerUtil.getDiffValue(initialDiff); + Match match = getComparison().getMatch(diffValue); + + if (match == null && isInTerminalState(initialDiff) && MergeViewerSide.ANCESTOR != getSide()) { + match = getMatchWithNullValues(initialDiff.getMatch()); + } + if (match != null) { + return new MergeViewerItem.Container(getComparison(), getInitialDiff(), match, getSide(), + getRootAdapterFactory()); + } + return null; + } + + /** + * After merging a diff which will lead to have an insertion point on both sides, the match associated + * with this diff will be unreacheable because its left and right sides will be null. This method will + * find this match. + * + * @param match + * the match of the merged diff. + * @return the match associated with the given merged diff. + */ + private Match getMatchWithNullValues(Match match) { + for (Match subMatch : match.getSubmatches()) { + if (subMatch.getLeft() == null && subMatch.getRight() == null) { + return subMatch; + } + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getItems() + */ + public ImmutableList getItems() { + final ImmutableList.Builder ret = ImmutableList.builder(); + final Collection items = Lists.newArrayList(); + final Collection matches = getComparison().getMatches(); + + for (Match match : matches) { + MergeViewerItem.Container container = null; + if (ResourceUIUtil.isFragment(match, getSide())) { + IMergeViewerItem item = ResourceUIUtil.createItemForNotLoadedFragmentMatch(match, getSide(), + getComparison(), getRootAdapterFactory()); + if (item != null) { + items.add(item); + } + } else if (getSide() != MergeViewerSide.ANCESTOR + || (getSide() == MergeViewerSide.ANCESTOR && match.getOrigin() != null)) { + ResourceAttachmentChange diff = getFirst( + filter(match.getDifferences(), ResourceAttachmentChange.class), null); + container = new MergeViewerItem.Container(getComparison(), diff, match.getLeft(), + match.getRight(), match.getOrigin(), getSide(), getRootAdapterFactory()); + items.add(container); + } + } + + final IMergeViewerItem newContainer = ResourceUIUtil.addNewContainerForNotLoadedFragmentMatches(items, + getSide(), getComparison(), getRootAdapterFactory()); + if (newContainer != null) { + ret.add(newContainer); + } else { + ret.addAll(items); + } + return ret.build(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + @Override + public String getType() { + return TypeConstants.TYPE_ETREE_DIFF; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/FeatureMapKeyChangeAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/FeatureMapKeyChangeAccessorImpl.java new file mode 100644 index 000000000..a26658afe --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/FeatureMapKeyChangeAccessorImpl.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * 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.contentmergeviewer.accessor.impl; + +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.internal.merge.IMergeData; +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.internal.utils.ComparisonUtil; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.utils.IEqualityHelper; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.FeatureMap; + +/** + * A specific {@link AbstractStructuralFeatureAccessor} for FeatureMapChanges of kind DifferenceKind.CHANGE + * (represent a value that changed his key). + * + * @author Axel Richard + * @since 4.0 + */ +public class FeatureMapKeyChangeAccessorImpl extends AbstractStructuralFeatureAccessor { + + /** + * Default constructor. + * + * @param adapterFactory + * the adapater factory used to create the accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of the accessor. + */ + public FeatureMapKeyChangeAccessorImpl(AdapterFactory adapterFactory, FeatureMapChange diff, + MergeViewerSide side) { + super(adapterFactory, diff, side); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getItems() + */ + public ImmutableList getItems() { + final EStructuralFeature leftKey = getKey(MergeViewerSide.LEFT); + final EStructuralFeature rightKey = getKey(MergeViewerSide.RIGHT); + final EStructuralFeature ancestorKey = getKey(MergeViewerSide.ANCESTOR); + final MergeViewerItem item = new MergeViewerItem(getComparison(), getInitialDiff(), leftKey, rightKey, + ancestorKey, getSide(), getRootAdapterFactory()); + + return ImmutableList.of(item); + } + + /** + * Returns the {@link FeatureMapChange} diff associated with this accessor. + * + * @return the {@link FeatureMapChange} diff associated with this accessor. + */ + public FeatureMapChange getFeatureMapChange() { + return (FeatureMapChange)getInitialDiff(); + } + + /** + * Returns the key of the FeatureMap.Entry for the given side. + * + * @param side + * the given side. + * @return the key of the FeatureMap.Entry for the given side, or null if not found. + */ + private EStructuralFeature getKey(MergeViewerSide side) { + EStructuralFeature key = null; + final FeatureMapChange diff = (FeatureMapChange)getInitialDiff(); + final FeatureMap.Entry entry = (FeatureMap.Entry)diff.getValue(); + if ((side != MergeViewerSide.ANCESTOR && side.convertToDifferenceSource().equals(diff.getSource())) + && !isInTerminalState(diff)) { + key = entry.getEStructuralFeature(); + } else if (isInTerminalState(diff) && !isMergedTargetIsSource(diff)) { + key = entry.getEStructuralFeature(); + } else { + // The entry of the diff source side. + final Object value = entry.getValue(); + // The feature map object of the opposite side of the diff source. + final EObject eObject = getEObject(side); + // The entries of the opposite side of the diff source. + final List list = ReferenceUtil.getAsList(eObject, getStructuralFeature()); + + final IEqualityHelper equalityHelper = getComparison().getEqualityHelper(); + + for (Object object : list) { + // We've found the same value on the opposite side, return the key associated + if (object instanceof FeatureMap.Entry + && equalityHelper.matchingValues(value, ((FeatureMap.Entry)object).getValue())) { + key = ((FeatureMap.Entry)object).getEStructuralFeature(); + break; + } + } + } + return key; + } + + /** + * Returns true if the given diff is merged and the target side of the merge is the same as the diff + * source. + * + * @param diff + * the given {@link FeatureMapChange}. + * @return true if the given diff is merged and the target side of the merge is the same as the diff + * source, false otherwise. + */ + private boolean isMergedTargetIsSource(FeatureMapChange diff) { + IMergeData mergeData = (IMergeData)EcoreUtil.getExistingAdapter(ComparisonUtil.getComparison(diff), + IMergeData.class); + if (mergeData != null) { + MergeMode mode = MergeMode.getMergeMode(diff, mergeData.isLeftEditable(), + mergeData.isRightEditable()); + return diff.getSource() == mode.getMergeTarget(mergeData.isLeftEditable(), + mergeData.isRightEditable()); + } + return false; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java new file mode 100644 index 000000000..14b152327 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java @@ -0,0 +1,330 @@ +/******************************************************************************* + * Copyright (c) 2012, 2018 Obeo and others. + * 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 + * Philip Langer - add caching + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.size; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.newArrayListWithCapacity; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.internal.utils.DiffUtil; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareConstants; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.utils.IEqualityHelper; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EObject; + +/** + * A specific {@link AbstractStructuralFeatureAccessor} for multi-valued structural feature objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ManyStructuralFeatureAccessorImpl extends AbstractStructuralFeatureAccessor { + + /** + * A cache used by {@link #getDiffWithValue(Object)}. + */ + Map valueDiffs; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapater factory used to create the accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of the accessor. + */ + public ManyStructuralFeatureAccessorImpl(AdapterFactory adapterFactory, Diff diff, MergeViewerSide side) { + super(adapterFactory, diff, side); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getItems() + */ + public ImmutableList getItems() { + List ret; + List list = getFeatureValues(getSide()); + ret = createMergeViewerItemFrom(list); + + if (getSide() != MergeViewerSide.ANCESTOR + && list.size() < EMFCompareConstants.LIST_SIZE_INSERTION_POINT_THRESHOLD) { + ret = createInsertionPoints(ret); + } + + return ImmutableList.copyOf(ret); + } + + /** + * Create IMergeViewerItems for the given values. + * + * @param values + * the given values. + * @return the list of newly created IMergeViewerItems. + */ + private List createMergeViewerItemFrom(List values) { + List ret = newArrayListWithCapacity(values.size()); + for (Object value : values) { + IMergeViewerItem valueToAdd = createMergeViewerItemFrom(value); + ret.add(valueToAdd); + } + return ret; + } + + /** + * Create a IMergeViewerItem for the given object. + * + * @param object + * the given object. + * @return an IMergeViewerItem. + */ + private IMergeViewerItem createMergeViewerItemFrom(Object object) { + Diff diff = getDiffWithValue(object); + Object left = matchingValue(object, MergeViewerSide.LEFT); + Object right = matchingValue(object, MergeViewerSide.RIGHT); + Object ancestor = matchingValue(object, MergeViewerSide.ANCESTOR); + final boolean leftEmptyBox = !getFeatureValues(MergeViewerSide.LEFT).contains(left); + final boolean rightEmptyBox = !getFeatureValues(MergeViewerSide.RIGHT).contains(right); + if (leftEmptyBox || rightEmptyBox) { + if (leftEmptyBox) { + left = null; + } + if (rightEmptyBox) { + right = null; + } + } + return new MergeViewerItem(getComparison(), diff, left, right, ancestor, getSide(), + getRootAdapterFactory()); + } + + /** + * Create insertion points for the given values. + * + * @param values + * the given values. + * @return a list of newly created insertion points that implement {@link IMergeViewerItem}. + */ + private List createInsertionPoints( + final List values) { + List ret = newArrayList(values); + for (Diff diff : getDifferences().reverse()) { + boolean isLeft = getSide() == MergeViewerSide.LEFT; + Object left = getValueFromDiff(diff, MergeViewerSide.LEFT); + Object right = getValueFromDiff(diff, MergeViewerSide.RIGHT); + + final boolean leftEmptyBox = isLeft + && (left == null || !getFeatureValues(getSide()).contains(left)); + final boolean rightEmptyBox = !isLeft + && (right == null || !getFeatureValues(getSide()).contains(right)); + if (leftEmptyBox || rightEmptyBox) { + // Bug 458818: Don't display a delete+moved element twice + // If the diff is part of a conflict, + // we don't want to display both the MOVE and the DELETE on the same side + if (diff.getKind() == DifferenceKind.MOVE && isPartOfConflictWithDelete(diff)) { + continue; + } + Object ancestor = getValueFromDiff(diff, MergeViewerSide.ANCESTOR); + if (leftEmptyBox) { + left = null; + } + if (rightEmptyBox) { + right = null; + } + IMergeViewerItem insertionPoint = new MergeViewerItem(getComparison(), diff, left, right, + ancestor, getSide(), getRootAdapterFactory()); + + final int insertionIndex = Math.min(findInsertionIndex(diff, isLeft), ret.size()); + List subList = ret.subList(0, insertionIndex); + final int nbInsertionPointBefore = size(filter(subList, IMergeViewerItem.IS_INSERTION_POINT)); + + int index = Math.min(insertionIndex + nbInsertionPointBefore, ret.size()); + ret.add(index, insertionPoint); + } + } + return ret; + } + + private boolean isPartOfConflictWithDelete(final Diff diff) { + if (diff.getConflict() == null) { + return false; + } + return Iterables.any(diff.getConflict().getDifferences(), new Predicate() { + public boolean apply(Diff aDiff) { + return diff != aDiff && aDiff.getKind() == DifferenceKind.DELETE; + } + }); + } + + /** + * Find the insertion index for the given diff. + * + * @param diff + * the given diff. + * @param rightToLeft + * the way of merge. + * @return the insertion index. + */ + protected int findInsertionIndex(Diff diff, boolean rightToLeft) { + return DiffUtil.findInsertionIndex(getComparison(), diff, rightToLeft); + } + + /** + * Get the Diff corresponding to the given object. + * + * @param value + * the given object. + * @return the Diff corresponding to the given object. + */ + private Diff getDiffWithValue(Object value) { + if (valueDiffs == null) { + valueDiffs = Maps.newIdentityHashMap(); + for (Diff diff : getDifferences()) { + Object valueOfDiff = getValueFromDiff(diff, getSide()); + valueDiffs.put(valueOfDiff, diff); + } + } + + return valueDiffs.get(value); + } + + /** + * Get the value of the given side associated to the given Diff. + * + * @param diff + * the given Diff. + * @param side + * the side of the Diff. + * @return the value associated to the given Diff. + */ + protected Object getValueFromDiff(final Diff diff, MergeViewerSide side) { + Object diffValue = getDiffValue(diff); + Object ret = matchingValue(diffValue, side); + return ret; + } + + /** + * Get the value of the given side of the Match corresponding to the given object. + * + * @param object + * the given object. + * @param side + * the given side. + * @return the value of the given side of the Match corresponding to the given object. + */ + private Object matchingValue(Object object, MergeViewerSide side) { + final Object ret; + if (object instanceof EObject) { + final Match matchOfValue = getComparison().getMatch((EObject)object); + if (matchOfValue != null) { + switch (side) { + case ANCESTOR: + ret = matchOfValue.getOrigin(); + break; + case LEFT: + ret = matchOfValue.getLeft(); + break; + case RIGHT: + ret = matchOfValue.getRight(); + break; + default: + throw new IllegalStateException(); + } + } else { + ret = matchingValue(object, getFeatureValues(side)); + } + } else { + ret = matchingValue(object, getFeatureValues(side)); + } + return ret; + } + + /** + * Get the value in the given list that match to the given value. + * + * @param value + * the given value. + * @param in + * the list of values. + * @return the value in the given list that match to the given value. + */ + private Object matchingValue(Object value, List in) { + Object ret = null; + IEqualityHelper equalityHelper = getComparison().getEqualityHelper(); + Iterator valuesIterator = in.iterator(); + while (valuesIterator.hasNext() && ret == null) { + Object object = valuesIterator.next(); + if (equalityHelper.matchingValues(object, value)) { + ret = object; + } + } + return ret; + } + + /** + * Returns the values of the current feature on the given side. + * + * @param side + * the given side. + * @return the values of the current feature on the given side. + */ + protected List getFeatureValues(MergeViewerSide side) { + final EObject eObject = getEObject(side); + return ReferenceUtil.getAsListResolving(eObject, getStructuralFeature()); + } + + /** + * Returns either {@link ReferenceChange#getValue()}, {@link AttributeChange#getValue()} or a + * {@link FeatureMapChange#getValue()} depending on the runtime type of the give, {@code diff} or null + * otherwise. + * + * @param diff + * the given Diff. + * @return the value of the given Diff. + */ + protected Object getDiffValue(Diff diff) { + final Object ret; + if (diff instanceof ReferenceChange) { + ret = ((ReferenceChange)diff).getValue(); + } else if (diff instanceof AttributeChange) { + ret = ((AttributeChange)diff).getValue(); + } else if (diff instanceof FeatureMapChange) { + ret = ((FeatureMapChange)diff).getValue(); + } else if (diff.getPrimeRefining() instanceof ReferenceChange) { + ret = ((ReferenceChange)diff.getPrimeRefining()).getValue(); + } else { + ret = null; + } + return ret; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java new file mode 100644 index 000000000..e5b3c504d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/MatchAccessor.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.contentmergeviewer.accessor.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.getFirst; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl.AbstractTypedElementAdapter; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.internal.util.ResourceUIUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * A specific {@link ICompareAccessor} for {@link Match} objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class MatchAccessor extends AbstractTypedElementAdapter implements ICompareAccessor { + + /** The match associated with this accessor. */ + private final Match fMatch; + + /** The diff associated with this accessor. */ + private Diff fDiff; + + /** The side of this accessor. */ + private final MergeViewerSide fSide; + + /** + * Creates a new object wrapping the given eObject. + * + * @param adapterFactory + * the adapter factory used to create the accessor. + * @param match + * the match to associate with this accessor. + * @param side + * the side of this accessor. + */ + public MatchAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) { + this(adapterFactory, match, null, side); + } + + /** + * Creates a new object wrapping the given eObject. + * + * @param adapterFactory + * the adapter factory used to create the accessor. + * @param match + * the match to associate with this accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of this accessor. + */ + public MatchAccessor(AdapterFactory adapterFactory, Match match, Diff diff, MergeViewerSide side) { + super(adapterFactory); + fMatch = match; + fDiff = diff; + fSide = side; + } + + /** + * Returns the side of this accessor. + * + * @return the side of this accessor. + */ + protected final MergeViewerSide getSide() { + return fSide; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + final EObject eObject = MergeViewerUtil.getBestSideEObject(fMatch, fSide); + if (eObject != null) { + return getItemDelegator().getText(eObject); + } else { + return getItemDelegator().getText(fMatch); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + final EObject eObject = MergeViewerUtil.getBestSideEObject(fMatch, fSide); + final Object image; + if (eObject != null) { + image = getItemDelegator().getImage(eObject); + } else { + image = getItemDelegator().getImage(fMatch); + } + return ExtendedImageRegistry.getInstance().getImage(image); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + return TypeConstants.TYPE_EMATCH; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getComparison() + */ + public Comparison getComparison() { + return fMatch.getComparison(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getInitialItem() + */ + public IMergeViewerItem getInitialItem() { + final MergeViewerItem.Container container; + if (fMatch instanceof NotLoadedFragmentMatch) { + container = new MergeViewerItem.Container(fMatch.getComparison(), fDiff, fMatch, fMatch, fMatch, + fSide, getRootAdapterFactory()); + } else { + container = new MergeViewerItem.Container(fMatch.getComparison(), fDiff, fMatch, fSide, + getRootAdapterFactory()); + } + return container; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor#getItems() + */ + public ImmutableList getItems() { + final ImmutableList.Builder ret = ImmutableList.builder(); + final Collection items = Lists.newArrayList(); + final Collection matches = getComparison().getMatches(); + + for (Match match : matches) { + MergeViewerItem.Container container = null; + if (ResourceUIUtil.isFragment(match, getSide())) { + IMergeViewerItem item = ResourceUIUtil.createItemForNotLoadedFragmentMatch(match, getSide(), + getComparison(), getRootAdapterFactory()); + if (item != null) { + items.add(item); + } + } else if (getSide() != MergeViewerSide.ANCESTOR + || (getSide() == MergeViewerSide.ANCESTOR && match.getOrigin() != null)) { + ResourceAttachmentChange diff = getFirst( + filter(match.getDifferences(), ResourceAttachmentChange.class), null); + container = new MergeViewerItem.Container(getComparison(), diff, match.getLeft(), + match.getRight(), match.getOrigin(), getSide(), getRootAdapterFactory()); + items.add(container); + } + } + + final IMergeViewerItem newContainer = ResourceUIUtil.addNewContainerForNotLoadedFragmentMatches(items, + getSide(), getComparison(), getRootAdapterFactory()); + if (newContainer != null) { + ret.add(newContainer); + } else { + ret.addAll(items); + } + return ret.build(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceContentsAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceContentsAccessorImpl.java new file mode 100644 index 000000000..58747a68d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceContentsAccessorImpl.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.contentmergeviewer.accessor.impl; + +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; + +import com.google.common.collect.ImmutableList; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IResourceContentsAccessor; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl.AbstractTypedElementAdapter; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.ResourceAttachmentChangeMergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.provider.EcoreEditPlugin; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * A specific {@link IResourceContentsAccessor} for {@link ResourceAttachmentChange} objects. + * + * @author Axel Richard + * @since 4.0 + */ +public class ResourceContentsAccessorImpl extends AbstractTypedElementAdapter implements IResourceContentsAccessor { + + /** The difference performed. */ + private final Diff fDiff; + + /** The side on which the difference is located. */ + private final MergeViewerSide fSide; + + /** The match associated to the performed difference. */ + private final Match fOwnerMatch; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapter factory used to create the accessor. + * @param diff + * The difference performed. + * @param side + * The side on which the difference is located. + */ + public ResourceContentsAccessorImpl(AdapterFactory adapterFactory, Diff diff, MergeViewerSide side) { + super(adapterFactory); + fDiff = diff; + fSide = side; + fOwnerMatch = diff.getMatch(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IResourceContentsAccessor#getComparison() + */ + public Comparison getComparison() { + return fOwnerMatch.getComparison(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IResourceContentsAccessor#getInitialItem() + */ + public IMergeViewerItem getInitialItem() { + Diff initialDiff = fDiff; + EObject diffValue = (EObject)MergeViewerUtil + .getResourceAttachmentChangeValue((ResourceAttachmentChange)initialDiff, getSide()); + if (isInTerminalState(initialDiff)) { + Object left = MergeViewerUtil.getValueFromResourceAttachmentChange( + (ResourceAttachmentChange)initialDiff, getComparison(), MergeViewerSide.LEFT); + Object right = MergeViewerUtil.getValueFromResourceAttachmentChange( + (ResourceAttachmentChange)initialDiff, getComparison(), MergeViewerSide.RIGHT); + DifferenceSource source = initialDiff.getSource(); + DifferenceKind kind = initialDiff.getKind(); + boolean b5 = source == DifferenceSource.LEFT && kind == DifferenceKind.ADD && right == null; + boolean b6 = source == DifferenceSource.LEFT && kind == DifferenceKind.DELETE && left == null; + boolean b7 = source == DifferenceSource.RIGHT && kind == DifferenceKind.ADD && left == null; + boolean b8 = source == DifferenceSource.RIGHT && kind == DifferenceKind.DELETE && right == null; + if (b5 || b8) { + left = null; + } + if (b6 || b7) { + right = null; + } + if (b5 || b8 || b6 || b7) { + Object ancestor = MergeViewerUtil.getValueFromResourceAttachmentChange( + (ResourceAttachmentChange)initialDiff, getComparison(), MergeViewerSide.ANCESTOR); + return new MergeViewerItem.Container(getComparison(), initialDiff, left, right, ancestor, + getSide(), getRootAdapterFactory()); + } + + } + if (diffValue == null && MergeViewerSide.ANCESTOR != getSide()) { + if (MergeViewerSide.LEFT == getSide()) { + diffValue = (EObject)MergeViewerUtil.getResourceAttachmentChangeValue( + (ResourceAttachmentChange)initialDiff, MergeViewerSide.RIGHT); + } else { + diffValue = (EObject)MergeViewerUtil.getResourceAttachmentChangeValue( + (ResourceAttachmentChange)initialDiff, MergeViewerSide.LEFT); + } + if (diffValue == null) { + diffValue = (EObject)MergeViewerUtil.getResourceAttachmentChangeValue( + (ResourceAttachmentChange)initialDiff, MergeViewerSide.ANCESTOR); + } + } + Match match = getComparison().getMatch(diffValue); + + if (match != null) { + Object left = match.getLeft(); + Object right = match.getRight(); + Object ancestor = match.getOrigin(); + // Manage case where the resource attachment change is between an existing resource and an unknown + // resource + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.LEFT, initialDiff) == null) { + left = null; + } + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.RIGHT, initialDiff) == null) { + right = null; + } + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.ANCESTOR, initialDiff) == null) { + ancestor = null; + } + + return new MergeViewerItem.Container(getComparison(), initialDiff, left, right, ancestor, + getSide(), getRootAdapterFactory()); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IResourceContentsAccessor#getItems() + */ + public ImmutableList getItems() { + final ImmutableList ret = ImmutableList + .of(new ResourceAttachmentChangeMergeViewerItem(getComparison(), null, + getResource(MergeViewerSide.LEFT), getResource(MergeViewerSide.RIGHT), + getResource(MergeViewerSide.ANCESTOR), getSide(), getRootAdapterFactory())); + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IResourceContentsAccessor#getResource(org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide) + */ + public Resource getResource(MergeViewerSide side) { + return MergeViewerUtil.getResource(fOwnerMatch.getComparison(), side, fDiff); + } + + /** + * Returns the side of the content merge viewer on which the difference is performed. + * + * @return The side of the content merge viewer on which the difference is performed. + */ + protected final MergeViewerSide getSide() { + return fSide; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + return ResourceContentsAccessorImpl.class.getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + return ExtendedImageRegistry.getInstance() + .getImage(EcoreEditPlugin.getPlugin().getImage("full/obj16/EObject")); //$NON-NLS-1$ + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + return TypeConstants.TYPE_ERESOURCE_DIFF; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceStreamAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceStreamAccessorImpl.java new file mode 100644 index 000000000..747cc4af6 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ResourceStreamAccessorImpl.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - bug 508526 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedHashMap; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.IStreamContentAccessor; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl.AbstractTypedElementAdapter; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * A specific {@link org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.IStreamContentAccessor} + * for resources. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ResourceStreamAccessorImpl extends AbstractTypedElementAdapter implements IStreamContentAccessor { + + /** The default size of the input stream resource contents. */ + private static final int INPUT_STREAM_DEFAULT_SIZE = 10240; + + /** The resource associated to this accessor. */ + private final Resource fResource; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapater factory used to create the accessor. + * @param resource + * the Resource to associate with the accessor. + */ + public ResourceStreamAccessorImpl(AdapterFactory adapterFactory, Resource resource) { + super(adapterFactory); + this.fResource = resource; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + return this.getClass().getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + Object image = getItemDelegator().getImage(fResource); + return ExtendedImageRegistry.getInstance().getImage(image); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + return "org.eclipse.emf.compare.rcp.ui.fallbackText"; //$NON-NLS-1$ + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.IStreamContentAccessor#getContents() + */ + public InputStream getContents() throws CoreException { + ByteArrayOutputStream os = new ByteArrayOutputStream(INPUT_STREAM_DEFAULT_SIZE); + try { + fResource.save(os, new LinkedHashMap<>()); + } catch (IOException e) { + EMFCompareRCPUIPlugin.getDefault().log(e); + } + return new ByteArrayInputStream(os.toByteArray()); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java new file mode 100644 index 000000000..4c5a690eb --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2012, 2015 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.contentmergeviewer.accessor.impl; + +import com.google.common.collect.ImmutableList; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EObject; + +/** + * A specific {@link AbstractStructuralFeatureAccessor} for mono-valued structural feature objects. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class SingleStructuralFeatureAccessorImpl extends AbstractStructuralFeatureAccessor { + + /** + * Default constructor. + * + * @param adapterFactory + * the adapater factory used to create the accessor. + * @param diff + * the diff associated with this accessor. + * @param side + * the side of the accessor. + */ + public SingleStructuralFeatureAccessorImpl(AdapterFactory adapterFactory, Diff diff, + MergeViewerSide side) { + super(adapterFactory, diff, side); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor.#getItems() + */ + public ImmutableList getItems() { + Object thisSideValue = getValue(getSide()); + if (thisSideValue == null && getSide() == MergeViewerSide.ANCESTOR) { + // No use retrieving all sides ... + return ImmutableList.of(); + } + + Object leftValue = getValue(MergeViewerSide.LEFT); + Object rightValue = getValue(MergeViewerSide.RIGHT); + Object ancestorValue = getValue(MergeViewerSide.ANCESTOR); + + // there can be only one diff on !many structural feature. + Diff diff = getInitialDiff(); + IMergeViewerItem insertionPoint = new MergeViewerItem(getComparison(), diff, leftValue, rightValue, + ancestorValue, getSide(), getRootAdapterFactory()); + return ImmutableList.of(insertionPoint); + } + + /** + * Get the value associated to the given side. + * + * @param side + * the given side. + * @return the value associated to the given side. + */ + private Object getValue(MergeViewerSide side) { + Object value = null; + EObject eObject = getEObject(side); + if (eObject != null) { + value = ReferenceUtil.safeResolvingEGet(eObject, getStructuralFeature()); + } + return value; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/StringAttributeChangeAccessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/StringAttributeChangeAccessor.java new file mode 100644 index 000000000..e155549b0 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/StringAttributeChangeAccessor.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.impl; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.IStreamContentAccessor; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.TypeConstants; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.provider.EcoreEditPlugin; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * A {@link ITypedElement} that can be used as input of TextMergeViewer. The returned content is the value of + * the given {@link EAttribute} on the given {@link EObject}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class StringAttributeChangeAccessor implements ITypedElement, IStreamContentAccessor { + + /** + * The EObject to get the value of the EAttribute from. + */ + private final EObject fEObject; + + /** + * The EAttribute to retrieve from the wrapped EObject. + */ + private final EAttribute fAttribute; + + /** + * Creates a new accessor for the given eObject and eAttribute. + * + * @param eObject + * The EObject to get the value of the EAttribute from. + * @param attributeChange + * The attribute change to get the attribute Eattribute from. + */ + public StringAttributeChangeAccessor(EObject eObject, AttributeChange attributeChange) { + this.fEObject = eObject; + this.fAttribute = attributeChange.getAttribute(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.IStreamContentAccessor#getContents() + */ + public InputStream getContents() throws CoreException { + Object value = ReferenceUtil.safeEGet(getEObject(), getEAtribute()); + String stringValue = EcoreUtil.convertToString(getEAtribute().getEAttributeType(), value); + // Assume that the platform locale is appropriate. + if (stringValue != null) { + return new ByteArrayInputStream(stringValue.getBytes()); + } else { + return new ByteArrayInputStream(new byte[0]); + } + } + + /** + * Returns the EObject to get the value of the EAttribute from. + * + * @return the EObject to get the value of the EAttribute from. + */ + protected final EObject getEObject() { + return fEObject; + } + + /** + * Returns the EAttribute to retrieve from the wrapped EObject. + * + * @return the EAttribute to retrieve from the wrapped EObject. + */ + protected final EAttribute getEAtribute() { + return fAttribute; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + return this.getClass().getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + return ExtendedImageRegistry.getInstance() + .getImage(EcoreEditPlugin.getPlugin().getImage("full/obj16/EAttribute")); //$NON-NLS-1$ + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + return TypeConstants.TYPE_ETEXT_DIFF; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/legacy/impl/TypedNotifier.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/legacy/impl/TypedNotifier.java new file mode 100644 index 000000000..ebb503402 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/legacy/impl/TypedNotifier.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.contentmergeviewer.accessor.legacy.impl; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.impl.AbstractTypedElementAdapter; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; +import org.eclipse.swt.graphics.Image; + +/** + * A specific implementation of {@link AbstractTypedElementAdapter} for notifiers. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class TypedNotifier extends AbstractTypedElementAdapter { + + /** EMF ResourceSet type. */ + public static final String NODE_TYPE_EMF_RESOURCESET = "NODE_TYPE__EMF_RESOURCESET"; //$NON-NLS-1$ + + /** EMF Resource type. */ + public static final String NODE_TYPE_EMF_RESOURCE = "NODE_TYPE__EMF_RESOURCE"; //$NON-NLS-1$ + + /** EMF EObject type. */ + public static final String NODE_TYPE_EMF_EOBJECT = "NODE_TYPE__EMF_EOBJECT"; //$NON-NLS-1$ + + /** EMF Comparison type. */ + public static final String NODE_TYPE_EMF_COMPARISON = "NODE_TYPE__EMF_COMPARISON"; //$NON-NLS-1$ + + /** The notifier to use to retrieve the type. */ + private final Notifier fNotifier; + + /** + * Default constructor. + * + * @param adapterFactory + * the adapter factory to use to retrieve item. + * @param notifier + * the notifier to use to retrieve the type. + */ + public TypedNotifier(AdapterFactory adapterFactory, Notifier notifier) { + super(adapterFactory); + fNotifier = notifier; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getName() + */ + public String getName() { + return getItemDelegator().getText(fNotifier); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getImage() + */ + public Image getImage() { + Object imageObject = getItemDelegator().getImage(fNotifier); + return ExtendedImageRegistry.getInstance().getImage(imageObject); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.legacy.ITypedElement#getType() + */ + public String getType() { + final String type; + if (fNotifier instanceof ResourceSet) { + type = NODE_TYPE_EMF_RESOURCESET; + } else if (fNotifier instanceof Resource) { + type = NODE_TYPE_EMF_RESOURCE; + } else if (fNotifier instanceof Comparison) { + type = NODE_TYPE_EMF_COMPARISON; + } else if (fNotifier instanceof EObject) { + type = NODE_TYPE_EMF_EOBJECT; + } else { + type = ITypedElement.UNKNOWN_TYPE; + } + return type; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationDescriptor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationDescriptor.java new file mode 100644 index 000000000..fd2812bdb --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationDescriptor.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.emf.compare.adapterfactory.context.IContextTester; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; + +/** + * The generic descriptor for content merge viewer customizations. + * + * @author Stefan Dirix + * @param + * the type of object produced by the descriptor. + */ +public class ContentMergeViewerCustomizationDescriptor { + + /** + * Underlying {@link IConfigurationElement} describing this customization. + */ + private final IConfigurationElement configurationElement; + + /** + * Ranking of this handler. + */ + private final int ranking; + + /** + * Qualified class name of the provider from this {@link #configurationElement}. Will be used as + * identifier. + */ + private final String providerClassName; + + private final String providerAttributeName; + + /** + * Qualified class name of the context class + */ + private final String contextClassName; + + private final String contextAttributeName; + + /** + * Don't log the same error multiple times. + */ + private boolean logOnce; + + /** + * Don't log the same error multiple times. + */ + private boolean logOnceContext; + + /** + * The provider provided by this descriptor. + */ + private T provider; + + /** + * The context tester provided by this descriptor. + */ + private IContextTester contextTester; + + /** + * Default constructor. + * + * @param configurationElement + * Configuration element that served to populate this descriptor. + * @param contentProviderClass + * The contentProvider which + * @param mergeViewerItemProviderClass + * @param contextClass + * @param ranking + * Ranking of this handler. High-priority handlers take precedence over low-priority ones. + */ + ContentMergeViewerCustomizationDescriptor(IConfigurationElement configurationElement, + String providerClass, String providerAttributeName, String contextClass, + String contextAttributeName, int ranking) { + this.configurationElement = checkNotNull(configurationElement); + this.providerClassName = checkNotNull(providerClass); + this.contextClassName = contextClass; + this.ranking = ranking; + this.providerAttributeName = providerAttributeName; + this.contextAttributeName = contextAttributeName; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.ui.internal.logical.view.ILogicalModelViewHandler#getRanking() + */ + public int getRanking() { + return ranking; + } + + /** + * Get the qualified class name of the described provider. + * + * @return the qualified class name of the described provider. + */ + public String getProviderClassName() { + return providerClassName; + } + + /** + * Create an instance of this provider. + * + * @return a new instance of this provider + */ + @SuppressWarnings("unchecked") + T getProvider() { + if (provider == null) { + try { + provider = (T)configurationElement.createExecutableExtension(providerAttributeName); + } catch (CoreException e) { + // Shouldn't happen since the registry listener should have checked that. + // log anyway. + if (!logOnce) { + logOnce = true; + final String message = EMFCompareRCPUIMessages + .getString("ContentCustomizationRegistry.invalidProvider", providerClassName); //$NON-NLS-1$ + final IStatus status = new Status(IStatus.ERROR, + configurationElement.getDeclaringExtension().getContributor().getName(), message, + e); + EMFCompareRCPUIPlugin.getDefault().getLog().log(status); + } + } + } + return provider; + } + + /** + * Create an instance of this tester. + * + * @return a new instance of this tester. + */ + IContextTester getContextTester() { + if (contextClassName != null && contextTester == null) { + try { + contextTester = (IContextTester)configurationElement + .createExecutableExtension(contextAttributeName); + } catch (CoreException e) { + // Shouldn't happen since the registry listener should have checked that. + // log anyway. + if (!logOnceContext) { + logOnceContext = true; + final String message = EMFCompareRCPUIMessages + .getString("ContentCustomizationRegistry.invalidContextTester", contextClassName); //$NON-NLS-1$ + final IStatus status = new Status(IStatus.ERROR, + configurationElement.getDeclaringExtension().getContributor().getName(), message, + e); + EMFCompareRCPUIPlugin.getDefault().getLog().log(status); + } + } + } + return contextTester; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistry.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistry.java new file mode 100644 index 000000000..1ae18bbf0 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistry.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.adapterfactory.context.IContextTester; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemContentProvider; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemProvider; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IOptionalProvider; + +/** + * The registry responsible for managing the content merge viewer customizations. + * + * @author Stefan Dirix + */ +public class ContentMergeViewerCustomizationRegistry { + /** Keeps track of the extensions providing {@link IMergeViewerItemProvider}s. */ + private final Map> registeredDescriptors; + + /** Keeps track of the extensions providing {@link IMergeViewerItemContentProvider}s. */ + private final Map> registeredTreeDescriptors; + + /** + * Constructs and initialized this registry. + */ + public ContentMergeViewerCustomizationRegistry() { + registeredDescriptors = new LinkedHashMap>(); + registeredTreeDescriptors = new LinkedHashMap>(); + } + + /** + * Adds the given {@link ContentMergeViewerCustomizationDescriptor} to this registry, using the given + * {@code className} as the identifier. + * + * @param className + * The identifier for the given {@link ContentMergeViewerCustomizationDescriptor}. + * @param descriptor + * The {@link ContentMergeViewerCustomizationDescriptor} which is to be added to this registry. + */ + public void addCustomization(String className, + ContentMergeViewerCustomizationDescriptor descriptor) { + registeredDescriptors.put(className, descriptor); + } + + /** + * Adds the given {@link ContentMergeViewerCustomizationDescriptor} to this registry, using the given + * {@code className} as the identifier. + * + * @param className + * The identifier for the given {@link ContentMergeViewerCustomizationDescriptor}. + * @param descriptor + * The {@link ContentMergeViewerCustomizationDescriptor} which is to be added to this registry. + */ + public void addTreeCustomization(String className, + ContentMergeViewerCustomizationDescriptor descriptor) { + registeredTreeDescriptors.put(className, descriptor); + } + + /** + * Removes the {@link ContentMergeViewerCustomizationDescriptor} and its managed + * {@link IDependencyProvider} identified by the given {@code className} from this registry. + * + * @param className + * Identifier of the provider we are to remove from this registry. + */ + public void removeDescriptor(String className) { + registeredDescriptors.remove(className); + registeredTreeDescriptors.remove(className); + } + + /** Clears out all registered listeners from this registry. */ + public void clear() { + registeredDescriptors.clear(); + registeredTreeDescriptors.clear(); + } + + private T getBestFittingProvider( + Collection> descriptors, Comparison comparison, + Object object) { + ContentMergeViewerCustomizationDescriptor bestDescriptor = null; + final Map context = createContext(comparison); + + for (ContentMergeViewerCustomizationDescriptor descriptor : descriptors) { + IContextTester contextTester = descriptor.getContextTester(); + // check context + if (contextTester != null && !contextTester.apply(context)) { + continue; + } + // check ranking + if (bestDescriptor != null && bestDescriptor.getRanking() > descriptor.getRanking()) { + continue; + } + // check provider + if (descriptor.getProvider().canHandle(object)) { + bestDescriptor = descriptor; + } + } + + if (bestDescriptor != null) { + return bestDescriptor.getProvider(); + } + + return null; + } + + /** + * Creates the context for the {@link IContextTester}s. + * + * @param comparison + * the {@link Comparison}. + * @return the created context. + */ + private Map createContext(Comparison comparison) { + final Map context = new HashMap(); + context.put(IContextTester.CTX_COMPARISON, comparison); + return context; + } + + /** + * Returns the best fitting {@link IMergeViewerItemProvider}. + * + * @param comparison + * the {@link Comparison} is used to check the context. + * @param object + * the {@link Object} for which the {@link IMergeViewerItemProvider} is responsible. + * @return the determined {@link IMergeViewerItemProvider} if one exists, {@code null} otherwise. + */ + public IMergeViewerItemProvider getBestFittingMergeViewerItemProvider(Comparison comparison, + Object object) { + return getBestFittingProvider(registeredDescriptors.values(), comparison, object); + } + + /** + * Returns the best fitting {@link IMergeViewerItemContentProvider}. + * + * @param comparison + * the {@link Comparison} is used to check the context. + * @param object + * the {@link Object} for which the {@link IMergeViewerItemContentProvider} is responsible. + * @return the determined {@link IMergeViewerItemContentProvider} if one exists, {@code null} otherwise. + */ + public IMergeViewerItemContentProvider getBestFittingMergeViewerItemContentProvider(Comparison comparison, + Object object) { + return getBestFittingProvider(registeredTreeDescriptors.values(), comparison, object); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistryListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistryListener.java new file mode 100644 index 000000000..3e27edd34 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/customization/ContentMergeViewerCustomizationRegistryListener.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.customization; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemContentProvider; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemProvider; + +/** + * The listener responsible for handling registration events regarding content merge viewer customizations. + * + * @author Stefan Dirix + */ +public class ContentMergeViewerCustomizationRegistryListener extends AbstractRegistryEventListener { + + /** The content customization tag of our extension point. */ + private static final String TAG_CONTENT_CUSTOMIZATION = "contentCustomization"; //$NON-NLS-1$ + + /** The tree content customization tag of our extension point. */ + private static final String TAG_TREE_CONTENT_CUSTOMIZATION = "treeContentCustomization"; //$NON-NLS-1$ + + /** The "contentProvider" attribute of the tree content customization tag. */ + private static final String ATTRIBUTE_CONTENTPROVIDER = "contentProvider"; //$NON-NLS-1$ + + /** The "mergeViewerItemProvider" attribute of the tree content customization tag. */ + private static final String ATTRIBUTE_MERGEVIEWERITEMPROVIDER = "mergeViewerItemProvider"; //$NON-NLS-1$ + + /** The "context" attribute of the tree content customization tag. */ + private static final String ATTRIBUTE_CONTEXT = "context"; //$NON-NLS-1$ + + /** The "ranking" attribute of the tree content customization tag. */ + private static final String ATTRIBUTE_RANKING = "ranking"; //$NON-NLS-1$ + + /** The actual registry this listener will alter. */ + private final ContentMergeViewerCustomizationRegistry registry; + + /** + * Initialize a registry event listener for our handlers. + * + * @param pluginID + * ID of the plugin contributing the extension point to monitor. + * @param extensionPointID + * Actual id of the extension point to monitor. + * @param log + * Log in which errors/warning should be logged. + * @param contentMergeViewerCustomizationRegistry + * The actual store of handlers this registry will alter. + */ + public ContentMergeViewerCustomizationRegistryListener(String pluginID, String extensionPointID, ILog log, + ContentMergeViewerCustomizationRegistry contentMergeViewerCustomizationRegistry) { + super(pluginID, extensionPointID, log); + this.registry = contentMergeViewerCustomizationRegistry; + } + + @Override + protected boolean addedValid(IConfigurationElement element) { + if (element.getName().equals(TAG_CONTENT_CUSTOMIZATION)) { + final String mergeViewerItemProvider = element.getAttribute(ATTRIBUTE_MERGEVIEWERITEMPROVIDER); + + final String context = element.getAttribute(ATTRIBUTE_CONTEXT); + + final String rankingStr = element.getAttribute(ATTRIBUTE_RANKING); + int ranking = -1; + try { + ranking = Integer.parseInt(rankingStr); + } catch (NumberFormatException e) { + log(IStatus.ERROR, element, EMFCompareRCPUIMessages.getString( + "ContentCustomizationRegistry.invalidRanking", mergeViewerItemProvider, rankingStr)); //$NON-NLS-1$ + } + + final ContentMergeViewerCustomizationDescriptor descriptor = new ContentMergeViewerCustomizationDescriptor( + element, mergeViewerItemProvider, ATTRIBUTE_MERGEVIEWERITEMPROVIDER, context, + ATTRIBUTE_CONTEXT, ranking); + registry.addCustomization(mergeViewerItemProvider, descriptor); + return true; + } + if (element.getName().equals(TAG_TREE_CONTENT_CUSTOMIZATION)) { + final String contentProvider = element.getAttribute(ATTRIBUTE_CONTENTPROVIDER); + + final String context = element.getAttribute(ATTRIBUTE_CONTEXT); + + final String rankingStr = element.getAttribute(ATTRIBUTE_RANKING); + int ranking = -1; + try { + ranking = Integer.parseInt(rankingStr); + } catch (NumberFormatException e) { + log(IStatus.ERROR, element, EMFCompareRCPUIMessages.getString( + "ContentCustomizationRegistry.invalidRanking", contentProvider, rankingStr)); //$NON-NLS-1$ + } + + final ContentMergeViewerCustomizationDescriptor descriptor = new ContentMergeViewerCustomizationDescriptor( + element, contentProvider, ATTRIBUTE_CONTENTPROVIDER, context, ATTRIBUTE_CONTEXT, ranking); + registry.addTreeCustomization(contentProvider, descriptor); + return true; + } + return false; + } + + /** + * Returns the attribute with the {@code attributeName} from the given {@code element}. + * + * @param element + * the {@link IConfigurationElement}. + * @param attributeName + * the name of the attribute which's value is to be determined. + * @param defaultResult + * the result of this method if the attribute does not exist. + * @return The determined value of the attribute if it exists, {@code defaultResult} otherwise. + */ + protected String getAttribute(IConfigurationElement element, String attributeName, String defaultResult) { + String attribute = element.getAttribute(attributeName); + if (attribute != null) { + return attribute; + } + return defaultResult; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + final String className; + if (element.getName().equals(TAG_CONTENT_CUSTOMIZATION)) { + className = element.getAttribute(ATTRIBUTE_MERGEVIEWERITEMPROVIDER); + } else { + className = element.getAttribute(ATTRIBUTE_CONTENTPROVIDER); + } + registry.removeDescriptor(className); + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + // Don't work twice as much, validate as we add. + // Removing cannot fail. + return true; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties new file mode 100644 index 000000000..5137d3bc6 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties @@ -0,0 +1,109 @@ +################################################################################ +# Copyright (c) 2013, 2016 Obeo and others. +# 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 +# Philip Langer - bug 493921 +# Simon Delisle - bug 495753 +################################################################################ +## note : apostrophes need to be doubled in these messages or they'll be ignored +TableMergeViewer.directResourceContentsLabel = resource contents +TableMergeViewer.featureMapEntryKeyLabel = feature map entry key : EStructuralFeature + +duplicate.extension = The extension {0} is registered twice + +SynchronizerDialog.hyperlink.message = See EMF Compare preferences +SynchronizerDialog.notAskAgain.label = Do not ask me again. +FilterActionMenu.tooltip = Filters +FilterAction.synchronization.dialog.title = Filters preference +FilterAction.synchronization.dialog.message = Would you like to remember the selected filters for next comparison? +GroupAction.synchronization.dialog.title = Group preference +GroupAction.synchronization.dialog.message = Would you like to remember the selected group for next comparison? + +GroupActionMenu.tooltip = Groups + +KindGroupProvider.addition.label = Additions +KindGroupProvider.deletion.label = Deletions +KindGroupProvider.change.label = Changes +KindGroupProvider.move.label = Moves + +ThreeWayComparisonGroupProvider.conflicts.label = Conflicts +ThreeWayComparisonGroupProvider.left.label = Left Side +ThreeWayComparisonGroupProvider.right.label = Right Side + +BasicDifferenceGroup.name = Group + +InteractiveFilterUIContent.sync.behavior.group.label = Remember selected filters +InteractiveFilterUIContent.sync.behavior.label = Remember user-selected filters in future comparisons: + + +# Messages for preference pages. + +ConfigurationUIRegistryEventListener.incorrectIdParameter.message = Id does not match any item to configure. +ConfigurationUIRegistryEventListener.incorrectConfiguratorParameter.message = The element is not an instance of IConfigurationUIFactory + +# Messages for preference pages. + +InteractiveUIContent.defaultConfiguration.label = The selected engine has no configuration option +InteractiveUIContent.configurationComposite.label = Configuration +InteractiveUIContent.descriptionComposite.label = Description +InteractiveUIContent.incorrectSelection.title = Incorrect selection +InteractiveUIContent.incorrectSelection.message = At least one item has to be selected. + +GroupsInteractiveContent.SYNC_BEHAVIOR_GROUP_LABEL = Remember selected groups +GroupsInteractiveContent.SYNC_BEHAVIOR_LABEL = Remember user-selected group in future comparisons: +GroupsInteractiveContent.ALWAYS_COMBO_LABEL = Always +GroupsInteractiveContent.NEVER_COMBO_LABEL = Never +GroupsInteractiveContent.ASK_EACH_TIME_LABEL = Ask each time + +PostProcessorPreferencePage.preferencePage.description = Select active post processors: + +GroupsPreferencePage.viewerDescription.label = Rank each group by priority (Highest ranked enabled element will be use as default): +GroupsPreferencePage.twoWayComparisonTab.label = 2 way comparison +GroupsPreferencePage.threeWayComparisonTab.label = 3 way comparison + +FiltersPreferencePage.INTRO_SELECT_TEXT = Select the filters that should be enabled by default\: +FiltersPreferencePage.activateIntro.text = Deactivating filters entirely prevents them from being applied and hides them from the list of available filters in the drop-down filter menu in the compare editor. If a filter is deactivated below, but enabled in the Enabled/Disabled tab, the filter will be deactivated and hidden. +FiltersPreferencePage.INTRO_DEACTIVATE_TEXT = Select the filters that should be active (the others will be completely ignored)\: +FiltersPreferencePage.activate.tab.label = Activate/Deactivate +FiltersPreferencePage.select.tab.label = Enable/Disable +FiltersPreferencePage.selectIntro.text = You can configure whether filters should be enabled or disabled by default. You can still enable or disable them using the drop-down filter menu in the compare editor. Note that 'disabled' filters may still have an impact on the differences shown in the compare editor. + +EnginesPreferencePage.differenceEngine.tab.label = Difference +EnginesPreferencePage.equivalenceEngine.tab.label = Equivalence +EnginesPreferencePage.requirementEngine.tab.label = Requirement +EnginesPreferencePage.conflictDetector.tab.label = Conflict +EnginesPreferencePage.matchEngine.tab.label = Match +EnginesPreferencePage.matchEngineIntro.text = Select active matching engines: +EnginesPreferencePage.diffEngineIntro.text = Select the difference engine to use: +EnginesPreferencePage.equiEngineIntro.text = Select the equivalence engine to use: +EnginesPreferencePage.reqEngineIntro.text = Select the requirement engine to use: +EnginesPreferencePage.conflictDetectorIntro.text = Select the conflict detector to use: + +AdapterFactoryPreferencePage.itemProviderGroup.text = Item Providers +AdapterFactoryPreferencePage.descriptionGroup.text = Description +AdapterFactoryPreferencePage.preferencePage.description = Select active item providers used in the comparison editor: + +LoggingPreferencePage.preferencePage.description = Logging in EMFCompare +LoggingPreferencePage.log.level = Log level: +LoggingPreferencePage.log.file = Log file: +LoggingPreferencePage.log.file.size = Maximum file size (MB): +LoggingPreferencePage.log.backup.count = Max number of backup log files: +LoggingPreferencePage.filebutton.label = Select... +LoggingPreferencePage.error.message = Empty or invalid information + +EMFComparePreferencePage.intro.text = Expand the tree to edit preferences for a specific feature. + +DefaultMatchEngineConfiguratorUI.useIdentifier.label = Select if identifiers should be used: +DefaultMatchEngineConfiguratorUI.whenAvailable.label = When available: The engine will use some heuristics when identifiers are missing +DefaultMatchEngineConfiguratorUI.only.label = Only: Objects without identifiers will never be matched. +DefaultMatchEngineConfiguratorUI.never.label = Never: Objects will be matched with some heuristics regardless of having identifiers. + +ContentCustomizationRegistry.invalidRanking = Ranking of resolver ''{0}'' is not a valid integer : ''{1}''. +ContentCustomizationRegistry.invalidContextTester = IContextTester named ''{0}'' could not be instantiated. +ContentCustomizationRegistry.invalidProvider = Provider named ''{0}'' could not be instantiated. + diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/ColorChangeEvent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/ColorChangeEvent.java new file mode 100644 index 000000000..d6d70bb17 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/ColorChangeEvent.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer; + +/** + * Event to notify a color change. + * + * @author Arthur Daussy + */ +public class ColorChangeEvent implements IColorChangeEvent { + + /** Id of the color that have changed. */ + private final String colorId; + + /** + * Constructor. + * + * @param colorId + * Id of the color that has been modified. + */ + public ColorChangeEvent(String colorId) { + super(); + this.colorId = colorId; + } + + /** + * {@inheritDoc} + */ + public String getColorID() { + return colorId; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java new file mode 100644 index 000000000..6bb02ecfc --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java @@ -0,0 +1,346 @@ +/******************************************************************************* + * Copyright (c) 2012-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.mergeviewer; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; + +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor; +import org.eclipse.jface.resource.ColorRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +/** + * Default implementation that use a cache to store created Color and that is listening to a preference store + * for color configuration. + * + * @author Mikael Barbero + */ +public class CompareColorImpl implements RemovalListener, ICompareColor { + + /** Min component for RGB. */ + private static final int MIN_RGB_COMPONENT = 0; + + /** Max component for RGB. */ + private static final int MAX_RGB_COMPONENT = 255; + + /** Loaded color cache size */ + private static final int MAX_CACHE_SIZE = 16; + + /** Gray color component */ + private static final int MED_RGB_COMPONENT = 128; + + /** Scale factor */ + private static final double INTERPOLATION_SCALE_1 = 0.6; + + /** Scale factor */ + private static final double INTERPOLATION_SCALE_2 = 0.97; + + /** Scale factor to compute the color of border. */ + private static final double DARKER_BORDER_SCALE_FACTOR = -0.5; + + /** Incoming color key in theme */ + public static final String INCOMING_CHANGE_COLOR_THEME_KEY = "org.eclipse.emf.compare.incomingChangeColor";//$NON-NLS-1$ + + /** Conflicting color key in theme */ + public static final String CONFLICTING_CHANGE_COLOR_THEME_KEY = "org.eclipse.emf.compare.conflictingChangeColor";//$NON-NLS-1$ + + /** Outgoing color key in theme */ + public static final String OUTGOING_CHANGE_COLOR_THEME_KEY = "org.eclipse.emf.compare.outgoingChangeColor";//$NON-NLS-1$ + + /** Required difference color key in theme */ + public static final String REQUIRED_DIFF_COLOR_THEME_KEY = "org.eclipse.emf.compare.requiredChangeColor";//$NON-NLS-1$ + + /** Unmergeable difference color key in theme */ + public static final String UNMERGEABLE_DIFF_COLOR_THEME_KEY = "org.eclipse.emf.compare.unmergeableChangeColor";//$NON-NLS-1$ + + private final LoadingCache fColors; + + private final Display fDisplay; + + private final ColorRegistry fColorRegistry; + + private final boolean fLeftIsLocal; + + private RGB incomingSelected; + + private RGB incoming; + + private RGB incomingFill; + + private RGB conflictSelected; + + private RGB conflict; + + private RGB conflictFill; + + private RGB outgoingSelected; + + private RGB outgoing; + + private RGB outgoingFill; + + private RGB requiredColor; + + private RGB requiredBorderColor; + + private RGB unmergeableColor; + + private RGB unmergeableBorderColor; + + /** + * Constructor. With this constructor the colors will disposed at the same as the control. + * + * @param control + * Use for get {@link Display}. The colors will be disposed with the control. + * @param leftIsLocal + * @param colorRegistry + * ColorRegistry where to find all needed color. Those color will be available through the + * constants: (UNMERGEABLE_DIFF_COLOR_THEME_KEY, REQUIRED_DIFF_COLOR_THEME_KEY, + * RESOLVED_CHANGE_COLOR_THEME_KEY, OUTGOING_CHANGE_COLOR_THEME_KEY, + * CONFLICTING_CHANGE_COLOR_THEME_KEY, INCOMING_CHANGE_COLOR_THEME_KEY) + */ + public CompareColorImpl(Display fDisplay, boolean leftIsLocal, ColorRegistry colorRegistry) { + this.fDisplay = fDisplay; + this.fLeftIsLocal = leftIsLocal; + this.fColors = CacheBuilder.newBuilder().maximumSize(MAX_CACHE_SIZE).removalListener(this) + .build(new CacheLoader() { + @Override + public Color load(RGB rgb) throws Exception { + return new Color(CompareColorImpl.this.fDisplay, rgb); + } + }); + this.fColorRegistry = colorRegistry; + updateColors(); + } + + public final void onRemoval(RemovalNotification notification) { + Color color = notification.getValue(); + if (!color.isDisposed()) { + color.dispose(); + } + } + + private Color getColor(RGB rgb) { + if (rgb == null) { + return null; + } + return fColors.getUnchecked(rgb); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.ICompareColor#getFillColor(org.eclipse.emf.compare.Diff, + * boolean, boolean, boolean) + */ + public Color getFillColor(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected) { + return getColor(getFillRGB(diff, isThreeWay, isIgnoreAncestor, selected)); + } + + private RGB getFillRGB(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected) { + RGB selectedFill = getBackground(); + if (isThreeWay && !isIgnoreAncestor) { + boolean requiredConflictForWayOfMerge = false; + + if (diff.getConflict() == null && !requiredConflictForWayOfMerge) { + switch (diff.getSource()) { + case RIGHT: + if (fLeftIsLocal) { + return selected ? selectedFill : incomingFill; + } + return selected ? selectedFill : outgoingFill; + case LEFT: + if (fLeftIsLocal) { + return selected ? selectedFill : outgoingFill; + } + return selected ? selectedFill : incomingFill; + } + } else { + return selected ? selectedFill : conflictFill; + } + return selected ? selectedFill : conflictFill; + } + return selected ? selectedFill : outgoingFill; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.ICompareColor#getStrokeColor(org.eclipse.emf.compare.Diff, + * boolean, boolean, boolean) + */ + public Color getStrokeColor(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected) { + return getColor(getStrokeRGB(diff, isThreeWay, isIgnoreAncestor, selected)); + } + + private RGB getStrokeRGB(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected) { + if (isThreeWay && !isIgnoreAncestor) { + boolean requiredConflictForWayOfMerge = false; + + if (diff != null && diff.getConflict() == null && !requiredConflictForWayOfMerge) { + switch (diff.getSource()) { + case RIGHT: + if (fLeftIsLocal) { + return selected ? incomingSelected : incoming; + } + return selected ? outgoingSelected : outgoing; + case LEFT: + if (fLeftIsLocal) { + return selected ? outgoingSelected : outgoing; + } + return selected ? incomingSelected : incoming; + } + } else { + return selected ? conflictSelected : conflict; + } + return selected ? conflictSelected : conflict; + } + return selected ? outgoingSelected : outgoing; + } + + protected final void updateColors() { + RGB background = getBackground(); + + unmergeableColor = fColorRegistry.getRGB(UNMERGEABLE_DIFF_COLOR_THEME_KEY); + if (unmergeableColor == null) { + unmergeableColor = new RGB(255, 205, 180); + } + unmergeableBorderColor = interpolate(unmergeableColor, background, DARKER_BORDER_SCALE_FACTOR); + + requiredColor = fColorRegistry.getRGB(REQUIRED_DIFF_COLOR_THEME_KEY); + if (requiredColor == null) { + requiredColor = new RGB(215, 255, 200); + } + requiredBorderColor = interpolate(requiredColor, background, DARKER_BORDER_SCALE_FACTOR); + + conflictSelected = fColorRegistry.getRGB(CONFLICTING_CHANGE_COLOR_THEME_KEY); + if (conflictSelected == null) { + conflictSelected = new RGB(MAX_RGB_COMPONENT, 0, 0); // RED + } + conflict = interpolate(conflictSelected, background, INTERPOLATION_SCALE_1); + conflictFill = interpolate(conflictSelected, background, INTERPOLATION_SCALE_2); + + outgoingSelected = fColorRegistry.getRGB(OUTGOING_CHANGE_COLOR_THEME_KEY); + if (outgoingSelected == null) { + outgoingSelected = new RGB(0, 0, 0); // BLACK + } + outgoing = interpolate(outgoingSelected, background, INTERPOLATION_SCALE_1); + outgoingFill = interpolate(outgoingSelected, background, INTERPOLATION_SCALE_2); + + incomingSelected = fColorRegistry.getRGB(INCOMING_CHANGE_COLOR_THEME_KEY); + if (incomingSelected == null) { + incomingSelected = new RGB(0, 0, MAX_RGB_COMPONENT); // BLUE + } + incoming = interpolate(incomingSelected, background, INTERPOLATION_SCALE_1); + incomingFill = interpolate(incomingSelected, background, INTERPOLATION_SCALE_2); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.ICompareColor#dispose() + */ + public void dispose() { + fColors.invalidateAll(); + } + + /** + * Get the background of the current display + * + * @param fDisplay + * @return + */ + private RGB getBackground() { + return fDisplay.getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(); + } + + /** + * Interpolate two colors using a scale factor + * + * @param fg + * Foreground color + * @param bg + * Background color + * @param scale + * Scale factor + * @return resulting {@link RGB} + */ + private static RGB interpolate(RGB fg, RGB bg, double scale) { + final RGB ret; + if (fg != null && bg != null) { + int red = (int)((1.0 - scale) * fg.red + scale * bg.red); + int green = (int)((1.0 - scale) * fg.green + scale * bg.green); + int blue = (int)((1.0 - scale) * fg.blue + scale * bg.blue); + ret = new RGB(getValidComponent(red), getValidComponent(green), getValidComponent(blue)); + } else if (fg != null) { + ret = fg; + } else if (bg != null) { + ret = bg; + } else { + ret = new RGB(MED_RGB_COMPONENT, MED_RGB_COMPONENT, MED_RGB_COMPONENT); // a gray + } + + return ret; + } + + /** + * Check that the component if valid for RGB object (0 < component < 255) + * + * @param colorComponent + * Input component + * @return A valid component + */ + private static int getValidComponent(int colorComponent) { + int validvalue = colorComponent; + if (colorComponent > MAX_RGB_COMPONENT) { + return MAX_RGB_COMPONENT; + } else if (colorComponent < MIN_RGB_COMPONENT) { + return MIN_RGB_COMPONENT; + } + return validvalue; + } + + /** + * {@inheritDoc} + */ + public Color getRequiredFillColor() { + return getColor(requiredColor); + } + + /** + * {@inheritDoc} + */ + public Color getUnmergeableFillColor() { + return getColor(unmergeableColor); + } + + /** + * {@inheritDoc} + */ + public Color getRequiredStrokeColor() { + return getColor(requiredBorderColor); + } + + /** + * {@inheritDoc} + */ + public Color getUnmergeableStrokeColor() { + return getColor(unmergeableBorderColor); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/IColorChangeEvent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/IColorChangeEvent.java new file mode 100644 index 000000000..a7a567d33 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/IColorChangeEvent.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer; + +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * A event notifying the bus that some color have change their value. + * + * @author Arthur Daussy + */ +public interface IColorChangeEvent extends ICompareEvent { + + /** + * Get the color ID that has been modified. + * + * @return The color ID + */ + String getColorID(); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractMergeViewer.java new file mode 100644 index 000000000..4639f835b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractMergeViewer.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2012, 2018 Obeo and others. + * 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 + * Philip Langer - bug 514079 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl; + +import com.google.common.base.Predicate; +import com.google.common.eventbus.Subscribe; + +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.internal.util.SWTUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProviderChange; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.swt.events.DisposeEvent; + +/** + * An abstract implementation of {@link IMergeViewer}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractMergeViewer extends ContentViewer implements IMergeViewer { + + /** The side of the viewer. */ + private final MergeViewerSide fSide; + + /** The compare configuration object used by this viewer. */ + private final IEMFCompareConfiguration compareConfiguration; + + /** The filter to apply on this viewer. */ + private Predicate differenceFilter; + + /** The difference group provider used by this viewer. */ + private IDifferenceGroupProvider differenceGroupProvider; + + /** + * Default constructor. + * + * @param side + * the side of the viewer. + * @param compareConfiguration + * the compare configuration object used by this viewer. + */ + public AbstractMergeViewer(MergeViewerSide side, final IEMFCompareConfiguration compareConfiguration) { + fSide = side; + this.compareConfiguration = compareConfiguration; + getCompareConfiguration().getEventBus().register(this); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer#getSide() + */ + public MergeViewerSide getSide() { + return fSide; + } + + /** + * Returns the effective side taking into account {@link CompareConfiguration#isMirrored()} to switch left + * and right. + * + * @param side + * @return the effective side with respect to mirroring. + */ + protected MergeViewerSide getEffectiveSide() { + if (getCompareConfiguration().isMirrored()) { + return getSide().opposite(); + } + return getSide(); + } + + /** + * Returns the compare configuration object used by this viewer. + * + * @return the compare configuration object used by this viewer. + */ + protected IEMFCompareConfiguration getCompareConfiguration() { + return compareConfiguration; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.ContentViewer#handleDispose(org.eclipse.swt.events.DisposeEvent) + */ + @Override + protected void handleDispose(DisposeEvent event) { + getCompareConfiguration().getEventBus().unregister(this); + super.handleDispose(event); + } + + /** + * Handle the change of difference group provider in the UI. + * + * @param event + * an IDifferenceGroupProviderChange that stores the new selected difference group provider. + */ + @Subscribe + public void handleDifferenceGroupProviderChange(IDifferenceGroupProviderChange event) { + differenceGroupProvider = event.getDifferenceGroupProvider(); + SWTUtil.safeRefresh(this, true, true); + } + + /** + * Returns the difference group provider selected in the UI. + * + * @return the difference group provider selected in the UI. + */ + public IDifferenceGroupProvider getDifferenceGroupProvider() { + if (differenceGroupProvider == null) { + return getCompareConfiguration().getStructureMergeViewerGrouper().getProvider(); + } else { + return differenceGroupProvider; + } + } + + /** + * Handle the change of filters in the UI. + * + * @param event + * an IDifferenceFilterChange that stores the new state of filters. + */ + @Subscribe + public void handleDifferenceFilterChange(IDifferenceFilterChange event) { + differenceFilter = event.getPredicate(); + SWTUtil.safeRefresh(this, true, true); + } + + /** + * Returns an aggregated predicate corresponding to the selected predicates of selected filters and + * unselected predicates of unselected filters in the UI. + * + * @return an aggregated predicate corresponding to the selected predicates of selected filters and + * unselected predicates of unselected filters in the UI. + */ + protected final Predicate getDifferenceFilter() { + if (differenceFilter == null) { + return getCompareConfiguration().getStructureMergeViewerFilter().getAggregatedPredicate(); + } else { + return differenceFilter; + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractStructuredMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractStructuredMergeViewer.java new file mode 100644 index 000000000..2c5912f09 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractStructuredMergeViewer.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - bug 527567 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl; + +import java.util.EnumSet; + +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +/** + * A specific {@link AbstractMergeViewer} for the EMF Compare Editor. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractStructuredMergeViewer extends AbstractMergeViewer { + + /** The primary control associated with this viewer. */ + private final Control fControl; + + /** A listener which is notified when a viewer's selection changes. */ + private final ISelectionChangedListener fForwardingSelectionListener; + + /** + * Default constructor. + * + * @param parent + * the parent widget. + * @param side + * the side of the viewer. + * @param compareConfiguration + * the compare configuration object used by this viewer. + */ + public AbstractStructuredMergeViewer(Composite parent, MergeViewerSide side, + IEMFCompareConfiguration compareConfiguration) { + super(side, compareConfiguration); + + fControl = createControl(parent); + hookControl(fControl); + + fForwardingSelectionListener = new ForwardingViewerSelectionListener(); + getStructuredViewer().addSelectionChangedListener(fForwardingSelectionListener); + createContextMenu(); + } + + /** + * Creates the primary control associated with this viewer. + * + * @param parent + * the parent widget of this viewer. + * @return the created primary control associated with this viewer. + */ + protected abstract Control createControl(Composite parent); + + /** + * Returns the wrapped {@link StructuredViewer}. + * + * @return the wrapped {@link StructuredViewer}. + */ + protected abstract StructuredViewer getStructuredViewer(); + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#getControl() + */ + @Override + public Control getControl() { + return fControl; + } + + /** + * Creates the context menu for the {@link #getStructuredViewer() structured viewer} adding a + * {@link IMenuListener menu listener} that calls {@link #fillContextMenu(IMenuManager)}. + */ + protected void createContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Control control = getStructuredViewer().getControl(); + Menu menu = menuMgr.createContextMenu(control); + control.setMenu(menu); + } + + /** + * Fills the context menu for the {@link #getStructuredViewer() structured viewer. By default, this + * determines the merge mode from the {@link #getCompareConfiguration() compare configuration}, and uses + * the {@link #getDiff() diff} of the {@link #getSelection() selection} to + * {@link #createAction(MergeMode, Diff) create actions}. The default implementation of + * {@code createAction} returns {@code null}, in which case no action is {@link IMenuManager#add(IAction) + * added} to the menu manager. + * + * @param manager + * the menu manager of the {@link #createContextMenu() context menu}. + * @see #getDiff() + * @see #createAction(MergeMode, Diff) + */ + protected void fillContextMenu(IMenuManager manager) { + IEMFCompareConfiguration configuration = getCompareConfiguration(); + boolean leftEditable = configuration.isLeftEditable(); + boolean rightEditable = configuration.isRightEditable(); + if (rightEditable || leftEditable) { + Diff diff = getDiff(); + if (diff != null) { + final EnumSet modes; + if (rightEditable && leftEditable) { + modes = EnumSet.of(MergeMode.RIGHT_TO_LEFT, MergeMode.LEFT_TO_RIGHT); + } else { + modes = EnumSet.of(MergeMode.ACCEPT, MergeMode.REJECT); + } + for (MergeMode mode : modes) { + IAction action = createAction(mode, diff); + if (action != null) { + manager.add(action); + } + } + } + } + } + + /** + * Returns the {@link IMergeViewerItem#getDiff() diff} associated with the one {@link IMergeViewerItem} in + * the viewer's {@link #getSelection() selection}. + * + * @return the diff associated with the one {@code IMergeViewerItem} in the viewer's selection. + */ + protected Diff getDiff() { + ISelection selection = getSelection(); + if (!selection.isEmpty() && selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection)selection; + if (structuredSelection.size() == 1) { + Object firstElement = structuredSelection.getFirstElement(); + if (firstElement instanceof IMergeViewerItem) { + IMergeViewerItem mergeViewerItem = (IMergeViewerItem)firstElement; + return mergeViewerItem.getDiff(); + } + } + } + return null; + } + + /** + * Creates the action for merging the given diff via the specified mode. By default this returns + * {@code null}. + * + * @param mode + * the merge mode. + * @param diff + * the diff to be merged. + * @return a new action for merging the given diff via the specified mode. + */ + protected IAction createAction(MergeMode mode, Diff diff) { + return null; + } + + @Override + protected void handleDispose(DisposeEvent event) { + getStructuredViewer().removeSelectionChangedListener(fForwardingSelectionListener); + hookDispose(); + super.handleDispose(event); + } + + protected abstract void hookDispose(); + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() + */ + @Override + public ISelection getSelection() { + return getStructuredViewer().getSelection(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean) + */ + @Override + public void setSelection(ISelection selection, boolean reveal) { + getStructuredViewer().setSelection(selection, reveal); + } + + /** + * {@inheritDoc} + */ + @Override + public void setContentProvider(IContentProvider contentProvider) { + super.setContentProvider(contentProvider); + getStructuredViewer().setContentProvider(contentProvider); + } + + /** + * {@inheritDoc} + */ + @Override + public void setLabelProvider(IBaseLabelProvider labelProvider) { + super.setLabelProvider(labelProvider); + getStructuredViewer().setLabelProvider(labelProvider); + } + + /** + * A specific implementation of {@link ISelectionChangedListener} for the AbstractStructuredMergeViewer. + * + * @author Mikael Barbero + * @since 4.0 + */ + private class ForwardingViewerSelectionListener implements ISelectionChangedListener { + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) + */ + public void selectionChanged(SelectionChangedEvent event) { + fireSelectionChanged( + new SelectionChangedEvent(AbstractStructuredMergeViewer.this, event.getSelection())); + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeItemWrapper.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeItemWrapper.java new file mode 100644 index 000000000..d58d6d199 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeItemWrapper.java @@ -0,0 +1,414 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - bug 527567 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.TreeItem; + +/** + * A wrapper of Table Item or Tree Item. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractTableOrTreeItemWrapper { + + /** + * Create an ItemWrapper from an Item. + * + * @param item + * the given Item. + * @return the wrapped Item. + */ + public static AbstractTableOrTreeItemWrapper create(Item item) { + final AbstractTableOrTreeItemWrapper wrapper; + if (item instanceof TreeItem) { + wrapper = new TreeItemWrapper((TreeItem)item); + } else if (item instanceof TableItem) { + wrapper = new TableItemWrapper((TableItem)item); + } else if (item == null) { + wrapper = null; + } else { + throw new IllegalArgumentException("Item must be instance of TreeItem or TableItem"); //$NON-NLS-1$ + } + return wrapper; + } + + /** + * Returns the wrapped Item. + * + * @return the wrapped Item. + */ + protected abstract Item getItem(); + + /** + * returns the bounds (as Rectangle) of the Item. + * + * @return the bounds (as Rectangle) of the Item. + */ + public abstract Rectangle getBounds(); + + /** + * Returns the parent of the Item. + * + * @return the parent of the Item. + */ + public abstract Scrollable getParent(); + + /** + * Returns the number of columns contained in the receiver. + * + * @return the number of columns contained in the receiver. + */ + public abstract int getParentColumnCount(); + + /** + * Returns a rectangle describing the size and location relative to its parent of an image at a column in + * the tree or the table. + * + * @param index + * the index that specifies the column. + * @return a rectangle describing the size and location relative to its parent of an image at a column in + * the tree or the table. + */ + public abstract Rectangle getImageBounds(int index); + + /** + * Returns a rectangle describing the size and location relative to its parent of the text at a column in + * the tree or the table. + * + * @param index + * the index that specifies the column. + * @return a rectangle describing the size and location relative to its parent of the text at a column in + * the tree or the table. + */ + public abstract Rectangle getTextBounds(int index); + + /** + * Returns the text stored at the given column index in the receiver, or empty string if the text has not + * been set. + * + * @param index + * the index that specifies the column. + * @return the text stored at the given column index in the receiver, or empty string if the text has not + * been set. + */ + public abstract String getText(int index); + + /** + * Returns the image stored at the given column index in the receiver, or null if the image has not been + * set or if the column does not exist. + * + * @param index + * the index that specifies the column. + * @return the image stored at the given column index in the receiver, or null if the image has not been + * set or if the column does not exist. + */ + public abstract Image getImage(int index); + + /** + * Returns the parent Item of the receiver. + * + * @return the parent Item of the receiver. + */ + public abstract AbstractTableOrTreeItemWrapper getParentItem(); + + /** + * Returns the height of the area which would be used to display the parent item of an Item of the tree or + * the table. + * + * @return the height of the area which would be used to display the parent item of an Item of the tree or + * the table. + */ + public abstract int getParentItemHeight(); + + /** + * Returns whether the receiver can be expanded to show children. + * + * @return whether the receiver can be expanded to show children. + */ + public boolean isExpandable() { + return false; + } + + /** + * Returns the data associated to the Item. + * + * @return the data associated to the Item. + */ + public Object getData() { + return getItem().getData(); + } + + /** + * A wrapper of Tree Item. + * + * @author Mikael Barbero + * @since 4.0 + */ + private static class TreeItemWrapper extends AbstractTableOrTreeItemWrapper { + + /** + * The wrapped Tree Item. + */ + private final TreeItem fItem; + + /** + * Default constructor. + * + * @param item + * the TreeItem to wrap. + */ + public TreeItemWrapper(TreeItem item) { + fItem = item; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getItem() + */ + @Override + protected Item getItem() { + return fItem; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getBounds() + */ + @Override + public Rectangle getBounds() { + return fItem.getBounds(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParent() + */ + @Override + public Scrollable getParent() { + return fItem.getParent(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentColumnCount() + */ + @Override + public int getParentColumnCount() { + return fItem.getParent().getColumnCount(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getImageBounds(int) + */ + @Override + public Rectangle getImageBounds(int index) { + return fItem.getImageBounds(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentItem() + */ + @Override + public AbstractTableOrTreeItemWrapper getParentItem() { + return AbstractTableOrTreeItemWrapper.create(fItem.getParentItem()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentItemHeight() + */ + @Override + public int getParentItemHeight() { + return fItem.getParent().getItemHeight(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#isExpandable() + */ + @Override + public boolean isExpandable() { + return fItem.getItemCount() > 0; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getTextBounds(int) + */ + @Override + public Rectangle getTextBounds(int index) { + return fItem.getTextBounds(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getText(int) + */ + @Override + public String getText(int index) { + return fItem.getText(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getImage(int) + */ + @Override + public Image getImage(int index) { + return fItem.getImage(index); + } + + } + + /** + * A wrapper of Table Item. + * + * @author Mikael Barbero + * @since 4.0 + */ + private static class TableItemWrapper extends AbstractTableOrTreeItemWrapper { + + /** + * The wrapped Table Item. + */ + private final TableItem fItem; + + /** + * Default constructor. + * + * @param item + * the TableItem to wrap. + */ + public TableItemWrapper(TableItem item) { + fItem = item; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getItem() + */ + @Override + protected Item getItem() { + return fItem; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getBounds() + */ + @Override + public Rectangle getBounds() { + return fItem.getBounds(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParent() + */ + @Override + public Scrollable getParent() { + return fItem.getParent(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentColumnCount() + */ + @Override + public int getParentColumnCount() { + return fItem.getParent().getColumnCount(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getImageBounds(int) + */ + @Override + public Rectangle getImageBounds(int index) { + return fItem.getImageBounds(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentItem() + */ + @Override + public AbstractTableOrTreeItemWrapper getParentItem() { + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getParentItemHeight() + */ + @Override + public int getParentItemHeight() { + return fItem.getParent().getItemHeight(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getTextBounds(int) + */ + @Override + public Rectangle getTextBounds(int index) { + return fItem.getTextBounds(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getText(int) + */ + @Override + public String getText(int index) { + return fItem.getText(index); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeItemWrapper#getImage(int) + */ + @Override + public Image getImage(int index) { + return fItem.getImage(index); + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeMergeViewer.java new file mode 100644 index 000000000..decd275a5 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/AbstractTableOrTreeMergeViewer.java @@ -0,0 +1,527 @@ +/******************************************************************************* + * Copyright (c) 2012, 2018 Obeo and others. + * 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 + * Philip Langer - bug 527858, 514079, 527567 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl; + +import com.google.common.base.Objects; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.internal.utils.ComparisonUtil; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.jface.viewers.IElementComparer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.Region; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Scrollable; + +/** + * An abstract specialization of {@link AbstractStructuredMergeViewer} for Tables or Trees. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractTableOrTreeMergeViewer extends AbstractStructuredMergeViewer { + + /** IMAGE_GAP. */ + static final int IMAGE_GAP = 5; + + /** DELTA_IMAGE_GAP. */ + static final int DELTA_IMAGE_GAP = 2; + + /** TEXT_GAP. */ + static final int TEXT_GAP = 2; + + /** CELL_GAP. */ + static final int CELL_GAP = 1; + + /** The color provider of this viewer. */ + private final ICompareColor.Provider fColorProvider; + + /** A listener that listen to erase items events. */ + private Listener fEraseItemListener; + + /** A listener that listen to paint items events. */ + private Listener fPaintItemListener; + + /** This will be used in order to resize the table items to an even height. */ + private MesureItemListener fMesureItemListener; + + /** + * Default constructor. + * + * @param parent + * the parent widget of this viewer. + * @param side + * the side of this viewer. + * @param colorProvider + * the color provider to use with this viewer. + * @param compareConfiguration + * the compare configuration object to use with this viewer. + */ + public AbstractTableOrTreeMergeViewer(Composite parent, MergeViewerSide side, + ICompareColor.Provider colorProvider, IEMFCompareConfiguration compareConfiguration) { + super(parent, side, compareConfiguration); + + getStructuredViewer().setUseHashlookup(true); + getStructuredViewer().setComparer(new ElementComparer()); + + fColorProvider = colorProvider; + fEraseItemListener = new Listener() { + public void handleEvent(Event event) { + AbstractTableOrTreeMergeViewer.this.handleEraseItemEvent(event); + } + }; + getStructuredViewer().getControl().addListener(SWT.EraseItem, fEraseItemListener); + fPaintItemListener = new Listener() { + public void handleEvent(Event event) { + AbstractTableOrTreeMergeViewer.this.handlePaintItemEvent(event); + } + }; + getStructuredViewer().getControl().addListener(SWT.PaintItem, fPaintItemListener); + + fMesureItemListener = new MesureItemListener(); + getStructuredViewer().getControl().addListener(SWT.MeasureItem, fMesureItemListener); + } + + /** + * Handle the paint item event. + * + * @param event + * the paint item event. + */ + protected void handlePaintItemEvent(Event event) { + AbstractTableOrTreeItemWrapper itemWrapper = AbstractTableOrTreeItemWrapper.create((Item)event.item); + String text = itemWrapper.getText(event.index); + Image image = itemWrapper.getImage(event.index); + /* center column 1 vertically */ + + int cellGap = TEXT_GAP; + if (event.index == 0) { + cellGap = 0; + } + Point size = event.gc.textExtent(text); + int yOffset = Math.max(0, (event.height - size.y) / 2); + if (image != null) { + int imageYOffset = Math.max(0, (event.height - image.getBounds().height) / 2); + event.gc.drawImage(image, event.x + cellGap, event.y + imageYOffset); + } + event.gc.drawText(text, itemWrapper.getTextBounds(event.index).x + cellGap, event.y + yOffset, true); + } + + /** + * Handle the erase item event. + * + * @param event + * the erase item event. + */ + protected void handleEraseItemEvent(Event event) { + // let the #handlePaintItem handle the painting of foreground + event.detail &= ~SWT.FOREGROUND; + + Item item = (Item)event.item; + AbstractTableOrTreeItemWrapper itemWrapper = AbstractTableOrTreeItemWrapper.create(item); + Object data = itemWrapper.getData(); + + if (data instanceof IMergeViewerItem) { + IMergeViewerItem mergeViewerItem = ((IMergeViewerItem)data); + Diff diff = mergeViewerItem.getDiff(); + if (diff != null) { + if (!MergeViewerUtil.isMarkAsMerged(diff, mergeViewerItem, getCompareConfiguration())) { + if (mergeViewerItem.isInsertionPoint()) { + paintItemDiffBox(event, itemWrapper, diff, + getBoundsForInsertionPoint(event, itemWrapper)); + } else { + paintItemDiffBox(event, itemWrapper, diff, getBounds(event, itemWrapper)); + } + } + } + } + + // Avoid drawing the ugly focus box on tables. + // It looks especially bad for our own painted items. + event.detail &= ~SWT.FOCUSED; + } + + /** + * Paint a box around the given diff, and a line that will be related to associated element in the + * opposite viewer. + * + * @param event + * the paint item event. + * @param itemWrapper + * a TableItemWrapper or TreeItemWrapper. + * @param diff + * the given Diff. + * @param bounds + * a Rectangle that contains coordinates of the box to paint. + */ + private void paintItemDiffBox(Event event, AbstractTableOrTreeItemWrapper itemWrapper, Diff diff, + Rectangle bounds) { + event.detail &= ~SWT.HOT; + + GC g = event.gc; + Color oldBackground = g.getBackground(); + Color oldForeground = g.getForeground(); + + setGCStyleForDiff(g, diff, isSelected(event)); + g.fillRectangle(bounds); + g.drawRectangle(bounds); + + if (diff.getKind() == DifferenceKind.MOVE) { + g.setLineStyle(SWT.LINE_SOLID); + } + + switch (getEffectiveSide()) { + case LEFT: + drawLineFromBoxToCenter(itemWrapper, bounds, g); + break; + case RIGHT: + drawLineFromCenterToBox(itemWrapper, bounds, g); + break; + default: + break; + } + + if (isSelected(event)) { + g.setForeground(event.display.getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + g.setBackground(event.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + event.detail &= ~SWT.SELECTED; + } else { + g.setBackground(oldBackground); + g.setForeground(oldForeground); + } + } + + /** + * Draw a line from center to box. + * + * @param itemWrapper + * a TableItemWrapper or TreeItemWrapper. + * @param boxBounds + * a Rectangle that contains coordinates of the box. + * @param g + * the SWT GC tool. + */ + private void drawLineFromCenterToBox(AbstractTableOrTreeItemWrapper itemWrapper, Rectangle boxBounds, + GC g) { + AbstractTableOrTreeItemWrapper parent = itemWrapper.getParentItem(); + final int xOffset; + if (itemWrapper.isExpandable()) { + if (parent != null) { + xOffset = parent.getImageBounds(0).x; + } else { + xOffset = 0; + } + } else { + xOffset = boxBounds.x; + } + + Rectangle itemBounds = itemWrapper.getBounds(); + Point from = new Point(0, 0); + from.y = itemBounds.y + (itemBounds.height / 2); + Point to = new Point(xOffset, from.y); + g.drawLine(from.x, from.y, to.x, to.y); + } + + /** + * Draw a line from box to center. + * + * @param itemWrapper + * a TableItemWrapper or TreeItemWrapper. + * @param boxBounds + * a Rectangle that contains coordinates of the box. + * @param g + * the SWT GC tool. + */ + private void drawLineFromBoxToCenter(AbstractTableOrTreeItemWrapper itemWrapper, Rectangle boxBounds, + GC g) { + Rectangle itemBounds = itemWrapper.getBounds(); + Rectangle clientArea = itemWrapper.getParent().getClientArea(); + Point from = new Point(0, 0); + from.x = boxBounds.x + boxBounds.width; + from.y = itemBounds.y + (itemBounds.height / 2); + Point to = new Point(0, from.y); + to.x = clientArea.x + clientArea.width; + // We expect the to.x to be to the right so we need this guard because otherwise the line may be drawn + // on top of the hover information when the box is clipped. + if (from.x < to.x) { + g.drawLine(from.x, from.y, to.x, to.y); + } + } + + /** + * Computes the bounds (as Rectangle) in case of the given Item is an insertion point. + * + * @param event + * the paint item event. + * @param itemWrapper + * a TableItemWrapper or TreeItemWrapper. + * @return the bounds (as Rectangle) of the insertion point. + */ + private static Rectangle getBoundsForInsertionPoint(Event event, + AbstractTableOrTreeItemWrapper itemWrapper) { + Rectangle fill = getBounds(event, itemWrapper); + Rectangle treeBounds = itemWrapper.getParent().getClientArea(); + Rectangle itemBounds = itemWrapper.getBounds(); + fill.x = itemWrapper.getImageBounds(0).x + 2; + fill.y = fill.y + (itemBounds.height / 3); + fill.width = treeBounds.width / 4; + fill.height = itemBounds.height / 3; + + return fill; + } + + /** + * Set the background, foreground colors and the line style for the given diff. + * + * @param g + * the SWT GC tool. + * @param diff + * the given Diff. + * @param selected + * is the Diff selected or not. + */ + private void setGCStyleForDiff(GC g, Diff diff, boolean selected) { + final Comparison comparison = ComparisonUtil.getComparison(diff); + final boolean isThreeWay = comparison.isThreeWay(); + + if (diff.getKind() == DifferenceKind.MOVE) { + g.setLineStyle(SWT.LINE_DOT); + } + + g.setForeground(fColorProvider.getCompareColor().getStrokeColor(diff, isThreeWay, false, selected)); + g.setBackground(fColorProvider.getCompareColor().getFillColor(diff, isThreeWay, false, selected)); + } + + /** + * Computes the bounds (as Rectangle) of the given Item. + * + * @param event + * the paint item event. + * @param itemWrapper + * a TableItemWrapper or TreeItemWrapper. + * @return the bounds (as Rectangle) of the given Item. + */ + private static Rectangle getBounds(Event event, AbstractTableOrTreeItemWrapper itemWrapper) { + Scrollable tree = itemWrapper.getParent(); + Rectangle treeBounds = tree.getClientArea(); + Rectangle itemBounds = itemWrapper.getBounds(); + + // Compute the left and right points of all columns based on images and text being present so that the + // box only bounds what's visibly present. + int columnCount = itemWrapper.getParentColumnCount(); + int limit = Math.max(1, columnCount); + int left = -1; + int right = -1; + for (int i = 0; i < limit; ++i) { + Image image = itemWrapper.getImage(i); + if (image != null) { + Rectangle imageBounds = itemWrapper.getImageBounds(i); + if (left == -1) { + left = imageBounds.x - TEXT_GAP; + if (i > 0) { + left += TEXT_GAP; + } + } + right = imageBounds.x + imageBounds.width + TEXT_GAP; + if (i > 0) { + right += TEXT_GAP; + } + } + + String text = itemWrapper.getText(i); + if (!text.isEmpty()) { + Rectangle textBounds = itemWrapper.getTextBounds(i); + if (left == -1) { + left = textBounds.x - TEXT_GAP; + if (i > 0) { + left += TEXT_GAP; + } + } + int textWidth = event.gc.textExtent(text).x; + right = textBounds.x + textWidth + TEXT_GAP; + if (i > 0) { + right += TEXT_GAP; + } + } + } + + Rectangle fill = new Rectangle(0, 0, 0, 0); + fill.x = left; + fill.y = itemBounds.y; + if (!"cocoa".equals(SWT.getPlatform())) { //$NON-NLS-1$ + fill.y += 1; + } + // +x to add the icon and the expand "+" if we are in a tree + // fill.width = itemBounds.width + imageBounds.width + DELTA_IMAGE_GAP; + fill.width = right - left; + fill.height = itemBounds.height - 1; + if (!"cocoa".equals(SWT.getPlatform())) { //$NON-NLS-1$ + fill.height -= 3; + } + + final GC g = event.gc; + // If you wish to paint the selection beyond the end of last column, you must change the clipping + // region. + if (event.index == columnCount - 1 || columnCount == 0) { + int width = treeBounds.x + treeBounds.width - event.x; + if (width > 0) { + Region region = new Region(); + g.getClipping(region); + region.add(event.x, event.y, width, event.height); + g.setClipping(region); + region.dispose(); + } + } + g.setAdvanced(true); + + return fill; + } + + /** + * Check the event indicates a user-interface component state is selected. + * + * @param event + * the event. + * @return true, if the event indicates a user-interface component state is selected, false otherwise. + */ + private static boolean isSelected(Event event) { + return (event.detail & SWT.SELECTED) != 0; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractStructuredMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent) + */ + @Override + protected void handleDispose(DisposeEvent event) { + getStructuredViewer().getControl().removeListener(SWT.MeasureItem, fMesureItemListener); + getStructuredViewer().getControl().removeListener(SWT.EraseItem, fEraseItemListener); + getStructuredViewer().getControl().removeListener(SWT.PaintItem, fPaintItemListener); + super.handleDispose(event); + } + + /** + * A specific implementation of {@link IElementComparer} that compare EMF Compare Viewer Items. + * + * @author Mikael Barbero + * @since 4.0 + */ + public static final class ElementComparer implements IElementComparer { + /** + * {@inheritDoc}. + */ + public int hashCode(Object element) { + final int hashCode; + if (element instanceof IMergeViewerItem) { + IMergeViewerItem item = (IMergeViewerItem)element; + Diff diff = item.getDiff(); + if (diff != null && diff.getConflict() != null + && diff.getConflict().getKind() == ConflictKind.PSEUDO) { + // we do not create only one item per diff in pseudo conflict, so we hash the conflict and + // not the diff + hashCode = Objects.hashCode(item.getAncestor(), diff.getConflict()); + } else if (diff != null && item.getLeft() == null && item.getRight() == null) { + hashCode = Objects.hashCode(item.getAncestor(), diff); + } else { + hashCode = Objects.hashCode(item.getLeft(), item.getRight(), item.getAncestor()); + } + } else { + hashCode = element.hashCode(); + } + return hashCode; + } + + /** + * {@inheritDoc}. + */ + public boolean equals(Object a, Object b) { + final boolean ret; + if (a != b && a instanceof IMergeViewerItem && b instanceof IMergeViewerItem) { + IMergeViewerItem itemA = (IMergeViewerItem)a; + IMergeViewerItem itemB = (IMergeViewerItem)b; + Diff diffA = itemA.getDiff(); + Diff diffB = itemB.getDiff(); + if (diffA != null && diffA.getConflict() != null + && diffA.getConflict().getKind() == ConflictKind.PSEUDO && diffB != null + && diffB.getConflict() != null + && diffB.getConflict().getKind() == ConflictKind.PSEUDO) { + // pseudo conflict + ret = Objects.equal(itemA.getAncestor(), itemB.getAncestor()) + && Objects.equal(diffA.getConflict(), diffB.getConflict()); + } else if (diffA != null && diffB != null && itemA.getLeft() == null + && itemA.getRight() == null && itemB.getLeft() == null && itemB.getRight() == null) { + ret = Objects.equal(diffA, diffB); + } else if (diffA == null || diffB == null + || Objects.equal(diffA.getConflict(), diffB.getConflict())) { + // only compare diffs if they exist on both sides + // or if they aren't diffs for the same conflict + ret = Objects.equal(itemA.getLeft(), itemB.getLeft()) + && Objects.equal(itemA.getRight(), itemB.getRight()) + && Objects.equal(itemA.getAncestor(), itemB.getAncestor()); + } else { + ret = Objects.equal(itemA.getLeft(), itemB.getLeft()) + && Objects.equal(itemA.getRight(), itemB.getRight()) + && Objects.equal(itemA.getAncestor(), itemB.getAncestor()) + && Objects.equal(diffA, diffB); + } + } else { + ret = Objects.equal(a, b); + } + return ret; + } + } + + /** + * This will be used in order to resize the table items to an even height. Otherwise the lines we draw + * around it look somewhat flattened. + * + * @author Mikael Barbero + * @since 4.0 + */ + public static class MesureItemListener implements Listener { + /** + * The height to which we will resize items. + */ + private int fHeight = Integer.MIN_VALUE; + + /** + * {@inheritDoc} + * + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + public void handleEvent(Event event) { + if (fHeight == Integer.MIN_VALUE) { + AbstractTableOrTreeItemWrapper itemWrapper = AbstractTableOrTreeItemWrapper + .create((Item)event.item); + Rectangle imageBounds = itemWrapper.getImageBounds(0); + fHeight = imageBounds.height + 3; + } + event.height = fHeight; + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TableMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TableMergeViewer.java new file mode 100644 index 000000000..87a6f33b7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TableMergeViewer.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer.impl; + +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.IStructuralFeatureAccessor; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.FeatureMapKeyChangeAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.accessor.impl.ResourceContentsAccessorImpl; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.FeatureMap; +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +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.Label; + +/** + * A concrete implementation of {@link AbstractTableOrTreeMergeViewer} for TableViewer. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class TableMergeViewer extends AbstractTableOrTreeMergeViewer { + + /** The TableViewer. */ + private TableViewer fTableViewer; + + /** The InfoViewer. */ + private InfoViewer fInfoViewer; + + /** + * Default constructor. + * + * @param parent + * the parent widget of this viewer. + * @param side + * the side of this viewer. + * @param colorProvider + * the color provider to use with this viewer. + * @param compareConfiguration + * the compare configuration object to use with this viewer. + */ + public TableMergeViewer(Composite parent, MergeViewerSide side, ICompareColor.Provider colorProvider, + IEMFCompareConfiguration compareConfiguration) { + super(parent, side, colorProvider, compareConfiguration); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractMergeViewer#createControl(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginLeft = -1; + layout.marginRight = -1; + layout.marginTop = -1; + layout.marginBottom = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + fInfoViewer = new InfoViewer(composite, getSide()); + fInfoViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + + fTableViewer = new TableViewer(composite, + SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + fTableViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + return composite; + } + + public final int getVerticalOffset() { + return fInfoViewer.getControl().getSize().y - 2; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.impl.AbstractMergeViewer.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer() + */ + @Override + public final TableViewer getStructuredViewer() { + return fTableViewer; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractMergeViewer#setContentProvider(org.eclipse.jface.viewers.IContentProvider) + */ + @Override + public void setContentProvider(IContentProvider contentProvider) { + super.setContentProvider(contentProvider); + fInfoViewer.setContentProvider(contentProvider); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractMergeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider) + */ + @Override + public void setLabelProvider(IBaseLabelProvider labelProvider) { + super.setLabelProvider(labelProvider); + fInfoViewer.setLabelProvider(labelProvider); + } + + @Override + protected void hookDispose() { + fTableViewer = null; + fInfoViewer = null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) + */ + @Override + protected void inputChanged(Object input, Object oldInput) { + fTableViewer.setInput(input); + fInfoViewer.setInput(input); + ((Composite)getControl()).layout(true); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#refresh() + */ + @Override + public void refresh() { + fInfoViewer.refresh(); + fTableViewer.refresh(); + } + + /** + * A content viewer is a model-based adapter on a widget which accesses its model by means of a content + * provider and a label provider. This InfoViewer is the top part of the TableMergeViewer. It contains the + * object an the feature concerned by the Diff. + * + * @author Mikael Barbero + * @since 4.0 + */ + private static class InfoViewer extends ContentViewer { + + /** The side of this viewer. */ + private final MergeViewerSide fSide; + + /** The control associated with this viewer. */ + private final Composite fControl; + + /** The Icon of the EObject concerned by the Diff. */ + private final Label fEObjectIcon; + + /** The Label of the EObject concerned by the Diff. */ + private final Label fEObjectLabel; + + /** The Icon of the feature concerned by the Diff. */ + private final Label fFeatureIcon; + + /** The Label of the feature concerned by the Diff. */ + private final Label fFeatureLabel; + + /** Stores the selection for this viewer. */ + private ISelection fSelection; + + /** Stores the input of this viewer. */ + private Object fInput; + + /** + * Default constructor. + * + * @param parent + * the parent widget of this viewer. + * @param side + * the side of this viewer. + */ + public InfoViewer(Composite parent, MergeViewerSide side) { + this.fControl = new Composite(parent, SWT.BORDER); + this.fSide = side; + + fControl.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + GridLayout layout = new GridLayout(3, false); + layout.verticalSpacing = 0; + layout.horizontalSpacing = 0; + layout.marginLeft = 1; + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.marginBottom = 0; + fControl.setLayout(layout); + + Composite eObjectComposite = new Composite(fControl, SWT.NONE); + GridLayout eObjectCompositelayout = new GridLayout(2, false); + eObjectCompositelayout.verticalSpacing = 0; + eObjectCompositelayout.horizontalSpacing = 0; + eObjectCompositelayout.marginLeft = 0; + eObjectCompositelayout.marginHeight = 0; + eObjectCompositelayout.marginWidth = 0; + eObjectCompositelayout.marginBottom = 0; + eObjectComposite.setLayout(eObjectCompositelayout); + fEObjectIcon = new Label(eObjectComposite, SWT.NONE); + fEObjectIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1)); + fEObjectLabel = new Label(eObjectComposite, SWT.NONE); + fEObjectLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + eObjectComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 3, 1)); + + Label lblIn = new Label(fControl, SWT.NONE); + lblIn.setText(" "); //$NON-NLS-1$ + + fFeatureIcon = new Label(fControl, SWT.NONE); + fFeatureIcon.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1)); + fFeatureLabel = new Label(fControl, SWT.NONE); + fFeatureLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + hookControl(fControl); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#getControl() + */ + @Override + public Control getControl() { + return fControl; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) + */ + @Override + protected void inputChanged(Object input, Object oldInput) { + fInput = input; + fControl.setRedraw(false); + try { + refresh(); + } finally { + fControl.setRedraw(true); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#getSelection() + */ + @Override + public ISelection getSelection() { + return fSelection; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#refresh() + */ + @Override + public void refresh() { + if (fInput instanceof FeatureMapKeyChangeAccessorImpl) { + FeatureMapKeyChangeAccessorImpl featureMapAccessor = (FeatureMapKeyChangeAccessorImpl)fInput; + + final FeatureMapChange diff = featureMapAccessor.getFeatureMapChange(); + final FeatureMap.Entry entry = (FeatureMap.Entry)diff.getValue(); + final Object entryValue = entry.getValue(); + + if (getLabelProvider() instanceof ILabelProvider) { + ILabelProvider labelProvider = (ILabelProvider)getLabelProvider(); + + fFeatureLabel.setText( + EMFCompareRCPUIMessages.getString("TableMergeViewer.featureMapEntryKeyLabel")); //$NON-NLS-1$ + + fEObjectIcon.setImage(labelProvider.getImage(entryValue)); + fEObjectLabel.setText(labelProvider.getText(entryValue)); + } + + fControl.layout(true); + } else if (fInput instanceof IStructuralFeatureAccessor) { + IStructuralFeatureAccessor featureAccessor = (IStructuralFeatureAccessor)fInput; + + EObject eObject = featureAccessor.getEObject(fSide); + if (eObject == null) { + if (fSide != MergeViewerSide.ANCESTOR) { + eObject = featureAccessor.getEObject(MergeViewerSide.ANCESTOR); + if (eObject == null) { + eObject = featureAccessor.getEObject(fSide.opposite()); + } + } else { + eObject = featureAccessor.getEObject(MergeViewerSide.LEFT); + if (eObject == null) { + eObject = featureAccessor.getEObject(MergeViewerSide.RIGHT); + } + } + } + EStructuralFeature structuralFeature = featureAccessor.getStructuralFeature(); + + if (getLabelProvider() instanceof ILabelProvider) { + ILabelProvider labelProvider = (ILabelProvider)getLabelProvider(); + + fFeatureIcon.setImage(labelProvider.getImage(structuralFeature)); + fFeatureLabel.setText(labelProvider.getText(structuralFeature)); + + fEObjectIcon.setImage(labelProvider.getImage(eObject)); + fEObjectLabel.setText(labelProvider.getText(eObject)); + } + + fControl.layout(true); + } else if (fInput instanceof ResourceContentsAccessorImpl) { + final ResourceContentsAccessorImpl resourceContentAccessor = (ResourceContentsAccessorImpl)fInput; + final Resource resource = resourceContentAccessor.getResource(fSide); + + if (getLabelProvider() instanceof ILabelProvider) { + ILabelProvider labelProvider = (ILabelProvider)getLabelProvider(); + fFeatureLabel.setText(EMFCompareRCPUIMessages + .getString("TableMergeViewer.directResourceContentsLabel")); //$NON-NLS-1$ + + fEObjectIcon.setImage(labelProvider.getImage(resource)); + fEObjectLabel.setText(labelProvider.getText(resource)); + } + + fControl.layout(true); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean) + */ + @Override + public void setSelection(ISelection selection, boolean reveal) { + fSelection = selection; + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TreeMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TreeMergeViewer.java new file mode 100644 index 000000000..8319b9a16 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/impl/TreeMergeViewer.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - bug 527567 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl; + +import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * A concrete implementation of {@link AbstractTableOrTreeMergeViewer} for TreeViewer. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class TreeMergeViewer extends AbstractTableOrTreeMergeViewer { + + /** + * The Input of the viewer. + */ + private Object fInput; + + /** + * The TreeViewer. + */ + private TreeViewer fTreeViewer; + + /** + * Default constructor. + * + * @param parent + * the parent widget of this viewer. + * @param side + * the side of this viewer. + * @param colorProvider + * the color provider to use with this viewer. + * @param compareConfiguration + * the compare configuration object to use with this viewer. + */ + public TreeMergeViewer(Composite parent, MergeViewerSide side, ICompareColor.Provider colorProvider, + IEMFCompareConfiguration compareConfiguration) { + super(parent, side, colorProvider, compareConfiguration); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractMergeViewer#createControl(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createControl(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + layout.marginLeft = -1; + layout.marginRight = -1; + layout.marginTop = -1; + layout.marginBottom = 0; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + composite.setLayout(layout); + + fTreeViewer = createTreeViewer(composite); + fTreeViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + return composite; + } + + /** + * Creates a new tree viewer. + * + * @param parent + * the parent of the new tree viewer. + * @return a new tree viewer. + */ + protected TreeViewer createTreeViewer(Composite parent) { + return new TreeViewer(parent); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.ide.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer() + */ + @Override + public TreeViewer getStructuredViewer() { + return fTreeViewer; + } + + /** + * Set the expanded state of the given element or tree path. + * + * @param elementOrTreePath + * the given element or tree path. + * @param expanded + * the expanded state . + */ + public void setExpandedState(Object elementOrTreePath, boolean expanded) { + getStructuredViewer().setExpandedState(elementOrTreePath, expanded); + } + + @Override + protected void hookDispose() { + fInput = null; + fTreeViewer = null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object) + */ + @Override + protected void inputChanged(Object input, Object oldInput) { + if (input instanceof ICompareAccessor) { + fInput = input; + /* + * Sets the selection to null to prevent memory in the tree viewer. See + * StructuredViewer#preservingSelection(Runnable updateCode, boolean reveal) + */ + getStructuredViewer().setSelection(null); + getStructuredViewer().setInput(input); + } else { + fInput = null; + getStructuredViewer().setInput(null); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.IInputProvider#getInput() + */ + @Override + public Object getInput() { + return fInput; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.Viewer#refresh() + */ + @Override + public void refresh() { + fTreeViewer.refresh(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/MergeViewerItem.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/MergeViewerItem.java new file mode 100644 index 000000000..485e75940 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/MergeViewerItem.java @@ -0,0 +1,1135 @@ +/******************************************************************************* + * Copyright (c) 2012, 2015 Obeo and others. + * 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.mergeviewer.item.impl; + +import static com.google.common.base.Predicates.instanceOf; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.getFirst; +import static com.google.common.collect.Iterables.isEmpty; +import static com.google.common.collect.Iterables.size; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.newArrayListWithCapacity; +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.graph.IGraphView; +import org.eclipse.emf.compare.internal.spec.EObjectUtil; +import org.eclipse.emf.compare.internal.utils.DiffUtil; +import org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.internal.util.ResourceUIUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.utils.Objects; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.util.FeatureMap; +import org.eclipse.emf.ecore.util.FeatureMapUtil; +import org.eclipse.emf.edit.provider.ITreeItemContentProvider; +import org.eclipse.emf.edit.provider.ItemProviderAdapter; + +/** + * @author Mikael Barbero + */ +public class MergeViewerItem extends AdapterImpl implements IMergeViewerItem { + + private final Object fLeft; + + private final Object fRight; + + private final Object fAncestor; + + private final Diff fDiff; + + private final Comparison fComparison; + + private final MergeViewerSide fSide; + + private final AdapterFactory fAdapterFactory; + + public MergeViewerItem(Comparison comparison, Diff diff, Object left, Object right, Object ancestor, + MergeViewerSide side, AdapterFactory adapterFactory) { + fLeft = left; + fRight = right; + fAncestor = ancestor; + fDiff = diff; + fSide = side; + fAdapterFactory = adapterFactory; + fComparison = comparison; + } + + /** + * @param comparison + * @param diff + * @param match + * @param side + * @param adapterFactory + */ + public MergeViewerItem(Comparison comparison, Diff diff, Match match, MergeViewerSide side, + AdapterFactory adapterFactory) { + this(comparison, diff, match.getLeft(), match.getRight(), match.getOrigin(), side, adapterFactory); + } + + /** + * @return + */ + public final Diff getDiff() { + return fDiff; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.ide.ui.internal.contentmergeviewer.IMergeViewerItem#getAncestor() + */ + public final Object getAncestor() { + return fAncestor; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.ide.ui.internal.contentmergeviewer.IMergeViewerItem#getLeft() + */ + public final Object getLeft() { + return fLeft; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.ide.ui.internal.contentmergeviewer.IMergeViewerItem#getRight() + */ + public final Object getRight() { + return fRight; + } + + /** + * @return the fSide + */ + public final MergeViewerSide getSide() { + return fSide; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.ide.ui.internal.contentmergeviewer.IMergeViewerItem#getSideValue(org.eclipse.emf.compare.rcp.ui.mergeviewer.ide.ui.internal.contentmergeviewer.IMergeViewer.MergeViewerSide) + */ + public final Object getSideValue(MergeViewerSide side) { + switch (side) { + case LEFT: + return fLeft; + case RIGHT: + return fRight; + case ANCESTOR: + return fAncestor; + default: + throw new IllegalStateException(); // happy compiler :) + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem#getParent() + */ + public IMergeViewerItem.Container getParent() { + IMergeViewerItem.Container ret = null; + + if (getDiff() instanceof ResourceAttachmentChange) { + ret = createBasicContainer((ResourceAttachmentChange)getDiff()); + } else { + Object sideValue = getBestSideValue(); + ITreeItemContentProvider treeItemContentProvider = (ITreeItemContentProvider)fAdapterFactory + .adapt(sideValue, ITreeItemContentProvider.class); + + Object parent = treeItemContentProvider != null ? treeItemContentProvider.getParent(sideValue) + : null; + if (parent instanceof EObject) { + ret = createBasicContainer((EObject)parent); + } + } + return ret; + } + + public IMergeViewerItem cloneAsOpposite() { + return new MergeViewerItem(getComparison(), getDiff(), getLeft(), getRight(), getAncestor(), + getSide(), getAdapterFactory()); + } + + protected final Object getBestSideValue() { + Object sideValue; + if (fSide != MergeViewerSide.ANCESTOR) { + sideValue = getSideValue(fSide); + if (sideValue == null) { + sideValue = getSideValue(fSide.opposite()); + if (sideValue == null) { + sideValue = getSideValue(MergeViewerSide.ANCESTOR); + } + } + } else { + sideValue = getSideValue(MergeViewerSide.ANCESTOR); + if (sideValue == null) { + sideValue = getSideValue(MergeViewerSide.LEFT); + if (sideValue == null) { + sideValue = getSideValue(MergeViewerSide.RIGHT); + } + } + } + return sideValue; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem#isInsertionPoint() + */ + public boolean isInsertionPoint() { + return getSideValue(getSide()) == null && getDiff() != null; + } + + /** + * {@inheritDoc} + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + String className = this.getClass().getName(); + int start = className.lastIndexOf('.'); + // @formatter:off + return Objects.toStringHelper(className.substring(start + 1)) + .add("ancestor", EObjectUtil.getLabel((EObject)getAncestor())) //$NON-NLS-1$ + .add("left", EObjectUtil.getLabel((EObject)getLeft())) //$NON-NLS-1$ + .add("right", EObjectUtil.getLabel((EObject)getRight())) //$NON-NLS-1$ + .add("side", getSide()) //$NON-NLS-1$ + .add("diff", getDiff()).toString(); //$NON-NLS-1$ + // @formatter:on + } + + /** + * @return the fComparison + */ + public final Comparison getComparison() { + return fComparison; + } + + /** + * @return the fAdapterFactory + */ + protected final AdapterFactory getAdapterFactory() { + return fAdapterFactory; + } + + @Deprecated + protected final IMergeViewerItem.Container createBasicContainer(EObject eObject) { + IMergeViewerItem.Container ret = null; + Match parentMatch = fComparison.getMatch(eObject); + if (parentMatch == null) { + return null; + } + EObject expectedValue = MergeViewerUtil.getEObject(parentMatch, fSide); + if (expectedValue != null) { + Iterable diffs = getDiffsWithValue(expectedValue, parentMatch); + Diff diff = getFirst(diffs, null); + ret = new MergeViewerItem.Container(fComparison, diff, parentMatch, fSide, fAdapterFactory); + + } else { + expectedValue = MergeViewerUtil.getEObject(parentMatch, fSide.opposite()); + Iterable diffs = Lists.newArrayList(); + if (expectedValue != null) { + diffs = getDiffsWithValue(expectedValue, parentMatch); + } + if (isEmpty(diffs)) { + expectedValue = MergeViewerUtil.getEObject(parentMatch, MergeViewerSide.ANCESTOR); + if (expectedValue != null) { + diffs = getDiffsWithValue(expectedValue, parentMatch); + } + } + + if (!isEmpty(diffs)) { + Diff diff = diffs.iterator().next(); + if (diff instanceof ResourceAttachmentChange) { + ret = new MergeViewerItem.Container(fComparison, diff, parentMatch, fSide, + fAdapterFactory); + } else { + ret = createInsertionPoint(diff, fSide, fAdapterFactory); + } + } + } + return ret; + } + + /** + * Return an Iterable of {@link Diff} which are linked to the given expectedValue. Try to get containment + * reference changes first, then if empty, try to get resource attachment changes. + * + * @param expectedValue + * @return + */ + private Iterable getDiffsWithValue(EObject expectedValue, Match parentMatch) { + Iterable diffs = filter(fComparison.getDifferences(expectedValue), + CONTAINMENT_REFERENCE_CHANGE); + if (size(diffs) > 1 && fSide != MergeViewerSide.ANCESTOR) { + diffs = filter(diffs, fromSide(fSide.convertToDifferenceSource())); + if (size(diffs) > 1) { + throw new IllegalStateException( + "Should not have more than one ReferenceChange on each Match for a side"); //$NON-NLS-1$ + } + } + + Diff referenceChange = getFirst(diffs, null); + if (referenceChange == null) { + diffs = filter(parentMatch.getDifferences(), instanceOf(ResourceAttachmentChange.class)); + } + + return diffs; + } + + /** + * Create an IMergeViewerItem for the parent of the given {@link ResourceAttachmentChange}. + * + * @param diff + * the given {@link ResourceAttachmentChange}. + * @return an IMergeViewerItem. + */ + @Deprecated + protected final IMergeViewerItem.Container createBasicContainer(ResourceAttachmentChange diff) { + final Comparison comparison = getComparison(); + Resource left = MergeViewerUtil.getResource(comparison, MergeViewerSide.LEFT, diff); + Resource right = MergeViewerUtil.getResource(comparison, MergeViewerSide.RIGHT, diff); + Resource ancestor = MergeViewerUtil.getResource(comparison, MergeViewerSide.ANCESTOR, diff); + IMergeViewerItem.Container ret = new ResourceAttachmentChangeMergeViewerItem(comparison, null, left, + right, ancestor, getSide(), getAdapterFactory()); + return ret; + } + + @Deprecated + protected final List createInsertionPoints(Comparison comparison, + EStructuralFeature eStructuralFeature, final List values, + List differences) { + final List ret = newArrayList(values); + if (differences.isEmpty()) { + return ret; + } + + final List sideContent = ReferenceUtil.getAsList((EObject)getSideValue(getSide()), + eStructuralFeature); + final List oppositeContent = ReferenceUtil + .getAsList((EObject)getSideValue(getSide().opposite()), eStructuralFeature); + + for (Diff diff : Lists.reverse(differences)) { + EObject value = (EObject)MergeViewerUtil.getDiffValue(diff); + Match match = getComparison().getMatch(value); + if (!isPseudoAddConflict(diff) && (isAddOnOppositeSide(diff) || isDeleteOnSameSide(diff) + || isInsertOnBothSides(diff, match))) { + if (match == null && isInTerminalState(diff)) { + EObject bestSideValue = (EObject)getBestSideValue(); + match = getComparison().getMatch(bestSideValue); + match = getMatchWithNullValues(match); + } + + if (match != null && !isRealAddConflict(diff, match)) { + IMergeViewerItem.Container insertionPoint = new MergeViewerItem.Container(getComparison(), + diff, match.getLeft(), match.getRight(), match.getOrigin(), getSide(), + getAdapterFactory()); + + final int insertionIndex; + if (match.getLeft() == null && match.getRight() == null && diff.getConflict() != null + && diff.getConflict().getKind() == ConflictKind.PSEUDO) { + // pseudo conflict delete... + insertionIndex = ReferenceUtil + .getAsList((EObject)getSideValue(MergeViewerSide.ANCESTOR), + eStructuralFeature) + .indexOf(value); + } else { + insertionIndex = Math.min( + DiffUtil.findInsertionIndex(comparison, oppositeContent, sideContent, value), + ret.size()); + } + + // offset the insertion by the number of previous insertion points in the list + // Cannot be improved by keeping the number of created insertion points because the given + // "values" parameter may already contains some insertion points. + int realIndex = 0; + for (int index = 0; index < insertionIndex && realIndex < ret.size(); realIndex++) { + if (!ret.get(realIndex).isInsertionPoint()) { + index++; + } + } + + ret.add(realIndex, insertionPoint); + } + } + } + return ret; + } + + private boolean isAddOnOppositeSide(Diff diff) { + if (!isInTerminalState(diff) && diff.getKind() == DifferenceKind.ADD) { + DifferenceSource source = diff.getSource(); + MergeViewerSide side = getSide(); + return (source == DifferenceSource.LEFT && side == MergeViewerSide.RIGHT) + || (source == DifferenceSource.RIGHT && side == MergeViewerSide.LEFT); + } + + return false; + } + + private boolean isDeleteOnSameSide(Diff diff) { + if (!isInTerminalState(diff) && diff.getKind() == DifferenceKind.DELETE) { + DifferenceSource source = diff.getSource(); + MergeViewerSide side = getSide(); + return (source == DifferenceSource.LEFT && side == MergeViewerSide.LEFT) + || (source == DifferenceSource.RIGHT && side == MergeViewerSide.RIGHT); + } + + return false; + } + + private boolean isInsertOnBothSides(Diff diff, Match match) { + return isInTerminalState(diff) + && (match == null || (match.getLeft() == null && match.getRight() == null)); + } + + private boolean isPseudoAddConflict(Diff diff) { + Conflict conflict = diff.getConflict(); + return conflict != null && conflict.getKind() == ConflictKind.PSEUDO + && diff.getKind() == DifferenceKind.ADD; + } + + private boolean isRealAddConflict(Diff diff, Match match) { + // Real add conflict (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=442898) + return match.getRight() != null && match.getLeft() != null && isAddOnOppositeSide(diff); + } + + /** + * After merging a diff which will lead to have an insertion point on both sides, the match associated + * with this diff will be unreacheable because its left and right sides will be null. This method will + * find this match. + * + * @param match + * the given match. + * @return the match associated with the given merged diff. + */ + private Match getMatchWithNullValues(Match match) { + for (Match subMatch : match.getSubmatches()) { + if (subMatch.getLeft() == null && subMatch.getRight() == null) { + return subMatch; + } + } + return null; + } + + private IMergeViewerItem.Container createInsertionPoint(Diff diff, MergeViewerSide side, + AdapterFactory adapterFactory) { + Object left = MergeViewerUtil.getValueFromDiff(diff, MergeViewerSide.LEFT); + Object right = MergeViewerUtil.getValueFromDiff(diff, MergeViewerSide.RIGHT); + + IMergeViewerItem.Container insertionPoint = null; + if (left == null && right == null) { + // Do not display anything + } else { + final boolean leftEmptyBox = side == MergeViewerSide.LEFT + && (left == null || !MergeViewerUtil.getValues(diff, side).contains(left)); + final boolean rightEmptyBox = side == MergeViewerSide.RIGHT + && (right == null || !MergeViewerUtil.getValues(diff, side).contains(right)); + if (leftEmptyBox || rightEmptyBox) { + Object ancestor = MergeViewerUtil.getValueFromDiff(diff, MergeViewerSide.ANCESTOR); + + insertionPoint = new MergeViewerItem.Container(getComparison(), diff, left, right, ancestor, + side, adapterFactory); + } + } + + return insertionPoint; + } + + @Deprecated + protected final List createMergeViewerItemFrom(Collection values) { + List ret = newArrayListWithCapacity(values.size()); + for (EObject value : filter(values, EObject.class)) { + Match match = getComparison().getMatch(value); + if (this.fDiff != null || (match != null && !isMatchWithAllProxyData(match))) { + IMergeViewerItem valueToAdd = createMergeViewerItemFrom(value); + if (valueToAdd != null) { + ret.add(valueToAdd); + } + } + } + return ret; + } + + @Deprecated + protected boolean yieldsMergeViewerItem(Collection values) { + Iterable elements = filter(values, EObject.class); + if (fDiff != null && !Iterables.isEmpty(elements)) { + return true; + } + + for (EObject element : elements) { + Match match = getComparison().getMatch(element); + if (match != null && !isMatchWithAllProxyData(match)) { + return true; + } + } + + return false; + } + + @Deprecated + protected boolean yieldsInsertionPoint(Iterable diffs) { + return Iterables.any(diffs, new Predicate() { + public boolean apply(Diff diff) { + if (isPseudoAddConflict(diff)) { + return false; + } + + EObject value = (EObject)MergeViewerUtil.getDiffValue(diff); + Match match = getComparison().getMatch(value); + if (isAddOnOppositeSide(diff) || isDeleteOnSameSide(diff) + || isInsertOnBothSides(diff, match)) { + if (match == null && isInTerminalState(diff)) { + EObject bestSideValue = (EObject)getBestSideValue(); + match = getComparison().getMatch(bestSideValue); + match = getMatchWithNullValues(match); + } + + return match != null && !isRealAddConflict(diff, match); + } + + return false; + } + }); + } + + /** + * Check if the given match holds a proxy on each side. + * + * @param match + * the given match. + * @return true if the given match holds a proxy on each side, false otherwise. + */ + private boolean isMatchWithAllProxyData(Match match) { + boolean proxy = false; + EObject left = match.getLeft(); + EObject right = match.getRight(); + EObject origin = match.getOrigin(); + if (left != null && right != null) { + if (left.eIsProxy() && right.eIsProxy()) { + proxy = true; + } + } + if (proxy == true && fComparison.isThreeWay() && (origin == null || !origin.eIsProxy())) { + proxy = false; + } + return proxy; + } + + /** + * Creates an IMergeViewerItem from an EObject. + * + * @param eObject + * the given eObject. + * @return an IMergeViewerItem. + */ + @Deprecated + protected IMergeViewerItem createMergeViewerItemFrom(EObject eObject) { + + Match match = getComparison().getMatch(eObject); + + ReferenceChange referenceChange = (ReferenceChange)getFirst( + filter(getComparison().getDifferences(eObject), CONTAINMENT_REFERENCE_CHANGE), null); + if (match != null) { + return new MergeViewerItem.Container(getComparison(), referenceChange, match, getSide(), + getAdapterFactory()); + } else { + switch (getSide()) { + case LEFT: + return new MergeViewerItem.Container(getComparison(), referenceChange, eObject, null, + null, getSide(), getAdapterFactory()); + case RIGHT: + return new MergeViewerItem.Container(getComparison(), referenceChange, null, eObject, + null, getSide(), getAdapterFactory()); + case ANCESTOR: + return new MergeViewerItem.Container(getComparison(), referenceChange, null, null, + eObject, getSide(), getAdapterFactory()); + default: + throw new IllegalStateException(); + } + } + } + + /** + * Returns a list of those of the given diffs that are displayed in a group as provided by the given group + * provider and satisfy the given predicate. + * + * @param unfilteredDiffs + * the unfiltered diffs + * @param predicate + * a filter predicate; a {@code null} predicate will be satisfied by any diff + * @param groupProvider + * the active group provider + * @return a list of the filtered diffs + */ + @Deprecated + protected List filteredDiffs(Iterable unfilteredDiffs, + Predicate predicate, IDifferenceGroupProvider groupProvider) { + return Lists.newArrayList(filter(unfilteredDiffs, visibleInMergeViewer(predicate, groupProvider))); + } + + @Deprecated + protected Predicate visibleInMergeViewer(final Predicate predicate, + final IDifferenceGroupProvider groupProvider) { + if (predicate == null) { + return Predicates.alwaysTrue(); + } + + return new Predicate() { + public boolean apply(Diff diff) { + return MergeViewerUtil.isVisibleInMergeViewer(diff, groupProvider, predicate); + } + }; + } + + @Deprecated + public static class Container extends MergeViewerItem implements IMergeViewerItem.Container { + + /** + * + */ + private static final IMergeViewerItem[] NO_ITEMS_ARR = new IMergeViewerItem[0]; + + /** + * @param comparison + * @param diff + * @param left + * @param right + * @param ancestor + */ + public Container(Comparison comparison, Diff diff, Object left, Object right, Object ancestor, + MergeViewerSide side, AdapterFactory adapterFactory) { + super(comparison, diff, left, right, ancestor, side, adapterFactory); + } + + /** + * @param fComparison + * @param referenceChange + * @param parentMatch + * @param fSide + * @param fAdapterFactory + */ + public Container(Comparison comparison, Diff diff, Match match, MergeViewerSide side, + AdapterFactory adapterFactory) { + super(comparison, diff, match, side, adapterFactory); + } + + /** + * @return the noItemsArr + */ + public static IMergeViewerItem[] getNoItemsArr() { + return NO_ITEMS_ARR; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.MergeViewerItem.item.impl.AbstractMergeViewerItem#getParent() + */ + @Override + public IMergeViewerItem.Container getParent() { + IMergeViewerItem.Container ret = null; + + if (getDiff() instanceof ResourceAttachmentChange) { + ret = createBasicContainer((ResourceAttachmentChange)getDiff()); + } else { + Object sideValue = getBestSideValue(); + ITreeItemContentProvider treeItemContentProvider = (ITreeItemContentProvider)getAdapterFactory() + .adapt(sideValue, ITreeItemContentProvider.class); + + Object parent = treeItemContentProvider != null ? treeItemContentProvider.getParent(sideValue) + : null; + if (parent instanceof EObject) { + ret = createBasicContainer((EObject)parent); + } else if (parent instanceof Resource) { + ret = getParent((Resource)parent); + } else if (sideValue instanceof NotLoadedFragmentMatch) { + ret = getParent((NotLoadedFragmentMatch)sideValue); + } + } + return ret; + } + + /** + * Get the parent (as MergeViewerItem) of the MergeViewerItem in case the MergeViewerItem is a + * {@link org.eclipse.emf.ecore.resource.Resource}. + * + * @param resource + * the Resource for which we want the parent (as MergeViewerItem) + * @return the parent (a MergeViewerItem) of the given element. + */ + private IMergeViewerItem.Container getParent(Resource resource) { + final IMergeViewerItem.Container parent; + URI uri = resource.getURI(); + if (ResourceUIUtil.isFragment(uri)) { + final Object object = getBestSideValue(); + final Match matchOfValue = getComparison().getMatch((EObject)object); + final NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch( + matchOfValue); + parent = new MergeViewerItem.Container(getComparison(), getDiff(), notLoadedFragmentMatch, + notLoadedFragmentMatch, notLoadedFragmentMatch, getSide(), getAdapterFactory()); + } else { + parent = null; + } + return parent; + + } + + /** + * Get the parent of the MergeViewerItem in case the MergeViewerItem is a + * {@link org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch}. + * + * @param nlfm + * the NotLoadedFragmentMatch for which we want the parent (as MergeViewerItem) + * @return the parent (a MergeViewerItem) of the given element. + */ + private IMergeViewerItem.Container getParent(NotLoadedFragmentMatch nlfm) { + IMergeViewerItem.Container parent = null; + final Collection children = nlfm.getChildren(); + for (Match match : children) { + URI uri = ResourceUIUtil.getDataURI(match, getSide()); + if (uri != null) { + IGraphView graph = ResourceUIUtil.getResourcesURIGraph(); + URI parentData = graph.getParentData(uri); + ResourceSet rs = ResourceUIUtil.getDataResourceSet(match, getSide()); + Resource resourceParent = ResourceUIUtil.getParent(rs, uri); + while (resourceParent == null && parentData != null) { + resourceParent = ResourceUIUtil.getParent(rs, parentData.trimFragment()); + parentData = graph.getParentData(parentData.trimFragment()); + } + if (resourceParent != null && parentData != null) { + EObject eObjectParent = resourceParent.getEObject(parentData.fragment()); + if (eObjectParent != null) { + parent = createBasicContainer(eObjectParent); + break; + } + } else { + parent = createNotLoadedFragmentContainer(rs, uri); + if (parent != null) { + break; + } + } + } + } + return parent; + } + + /** + * Create an IMergeViewerItem.Container that holds NotLoadedFragmentMatches. + * + * @param uri + * the URI of the Match element for which we want to create a container. + * @return an IMergeViewerItem.Container. + */ + private IMergeViewerItem.Container createNotLoadedFragmentContainer(ResourceSet rs, URI uri) { + final IMergeViewerItem.Container parent; + URI parentURI = ResourceUIUtil.getParentResourceURI(rs, uri); + URI rootResourceURI = ResourceUIUtil.getRootResourceURI(uri); + if (parentURI == null) { + parentURI = rootResourceURI; + } + Collection notLoadedFragmentMatches = Lists.newArrayList(); + Collection rootMatches = getComparison().getMatches(); + Collection uris = ResourceUIUtil.getDataURIs(rootMatches, getSide()); + for (Match rootMatch : rootMatches) { + URI rootMatchDataURI = ResourceUIUtil.getDataURI(rootMatch, getSide()); + if (!rootResourceURI.equals(rootMatchDataURI) && !parentURI.equals(rootMatchDataURI) + && ResourceUIUtil.isChildOf(rootMatchDataURI, ImmutableSet.of(parentURI)) + && !ResourceUIUtil.isChildOf(rootMatchDataURI, uris)) { + notLoadedFragmentMatches.add(new NotLoadedFragmentMatch(rootMatch)); + } + } + if (notLoadedFragmentMatches.size() > 1) { + final NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch( + notLoadedFragmentMatches); + parent = new MergeViewerItem.Container(getComparison(), getDiff(), notLoadedFragmentMatch, + notLoadedFragmentMatch, notLoadedFragmentMatch, getSide(), getAdapterFactory()); + } else { + parent = null; + } + return parent; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem.Container#hasChildren(IDifferenceGroupProvider, + * Predicate) + */ + public boolean hasChildren(IDifferenceGroupProvider groupProvider, + Predicate predicate) { + if (getLeft() instanceof NotLoadedFragmentMatch) { + NotLoadedFragmentMatch notLoadedFragmentMatch = (NotLoadedFragmentMatch)getLeft(); + return !notLoadedFragmentMatch.getChildren().isEmpty(); + } + + Object sideValue = getSideValue(getSide()); + EObject bestSideValue = (EObject)getBestSideValue(); + Match match = getComparison().getMatch(bestSideValue); + + Iterable differences = match == null ? Collections. emptyList() + : ImmutableList.copyOf(filter(match.getDifferences(), CONTAINMENT_REFERENCE_CHANGE)); + + Collection childrenFeatures = getChildrenFeatures(bestSideValue); + for (EStructuralFeature eStructuralFeature : childrenFeatures) { + if (eStructuralFeature instanceof EReference) { + if (hasChildrenOfReference(groupProvider, predicate, sideValue, differences, + (EReference)eStructuralFeature)) { + return true; + } + } else if (FeatureMapUtil.isFeatureMap(eStructuralFeature)) { + if (hasChildrenOfFeatureMap(groupProvider, predicate, sideValue, differences, + eStructuralFeature)) { + return true; + } + } + } + + return hasNotLoadedFragmentsItems(match); + } + + private boolean hasChildrenOfReference(IDifferenceGroupProvider groupProvider, + Predicate predicate, Object container, Iterable differences, + EReference reference) { + List featureContent = ReferenceUtil.getAsList((EObject)container, reference); + if (yieldsMergeViewerItem(featureContent)) { + return true; + } + + if (getSide() != MergeViewerSide.ANCESTOR) { + Iterable differencesOnFeature = filter(differences, onFeature(reference.getName())); + Iterable filteredDiffs = filter(differencesOnFeature, + visibleInMergeViewer(predicate, groupProvider)); + return yieldsInsertionPoint(filteredDiffs); + } + + return true; + } + + private boolean hasChildrenOfFeatureMap(IDifferenceGroupProvider groupProvider, + Predicate predicate, Object container, Iterable differences, + EStructuralFeature featureMap) { + List mapContent = ReferenceUtil.getAsList((EObject)container, featureMap); + List featureContent = Lists.newArrayList(); + Set derivedFeatures = Sets.newLinkedHashSet(); + for (Object object : mapContent) { + if (object instanceof FeatureMap.Entry) { + featureContent.add(((FeatureMap.Entry)object).getValue()); + derivedFeatures.add(((FeatureMap.Entry)object).getEStructuralFeature()); + } + } + + if (yieldsMergeViewerItem(featureContent)) { + return true; + } + + if (getSide() != MergeViewerSide.ANCESTOR) { + Iterable differencesOnFeature = filter(differences, onFeatures(derivedFeatures)); + Iterable filteredDiffs = filter(differencesOnFeature, + visibleInMergeViewer(predicate, groupProvider)); + return yieldsInsertionPoint(filteredDiffs); + } + + return false; + } + + private boolean hasNotLoadedFragmentsItems(Match match) { + Collection childrenMatches = ResourceUIUtil + .getChildrenMatchWithNotLoadedParent(getComparison(), match, getSide()); + return !childrenMatches.isEmpty(); + } + + @Override + public IMergeViewerItem.Container cloneAsOpposite() { + return new MergeViewerItem.Container(getComparison(), getDiff(), getLeft(), getRight(), + getAncestor(), getSide(), getAdapterFactory()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem.Container#getChildren(IDifferenceGroupProvider, + * Predicate) + */ + public IMergeViewerItem[] getChildren(IDifferenceGroupProvider group, + Predicate predicate) { + + List ret = newArrayList(); + + if (this.getLeft() instanceof NotLoadedFragmentMatch) { + ret.addAll(getChildren((NotLoadedFragmentMatch)this.getLeft())); + } else { + Object sideValue = getSideValue(getSide()); + EObject bestSideValue = (EObject)getBestSideValue(); + + final Collection childrenFeatures = getChildrenFeatures( + bestSideValue); + + Match match = getComparison().getMatch(bestSideValue); + final ImmutableList differences; + if (match != null) { + differences = ImmutableList + .copyOf(filter(match.getDifferences(), CONTAINMENT_REFERENCE_CHANGE)); + } else { + differences = ImmutableList.of(); + } + + for (EStructuralFeature eStructuralFeature : childrenFeatures) { + if (eStructuralFeature instanceof EReference) { + ret.addAll(getChildrenOfReference(group, predicate, sideValue, differences, + (EReference)eStructuralFeature)); + } else if (FeatureMapUtil.isFeatureMap(eStructuralFeature)) { + ret.addAll(getChildrenOfFeatureMap(group, predicate, sideValue, differences, + eStructuralFeature)); + } + } + + // Add not loaded fragment match if needed + ret.addAll(getNotLoadedFragmentsItems(match)); + } + return ret.toArray(NO_ITEMS_ARR); + } + + /** + * Get the children of the MergeViewerItem in case the MergeViewerItem is a + * {@link org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch}. + * + * @param nlfm + * the NotLoadedFragmentMatch for which we want the children (as MergeViewerItems) + * @return the children (a list of MergeViewerItems) of the given element. + */ + private List getChildren(NotLoadedFragmentMatch nlfm) { + final List ret = newArrayList(); + final Collection matches = nlfm.getChildren(); + for (Match match : matches) { + final MergeViewerItem.Container container; + if (match instanceof NotLoadedFragmentMatch) { + container = new MergeViewerItem.Container(getComparison(), getDiff(), match, match, match, + getSide(), getAdapterFactory()); + } else { + container = new MergeViewerItem.Container(getComparison(), getDiff(), match.getLeft(), + match.getRight(), match.getOrigin(), getSide(), getAdapterFactory()); + } + ret.add(container); + } + return ret; + } + + /** + * Return potential NotLoadedFragment children items (as MergeViewerItem) of the MergeViewerItem in + * case the MergeViewerItem is a {@link org.eclipse.emf.compare.match.Match}. + * + * @param match + * the Match for which we want the potential NotLoadedFragment children items (as + * MergeViewerItems) + * @return the NotLoadedFragment children items (a list of MergeViewerItems) of the given element. + */ + private List getNotLoadedFragmentsItems(Match match) { + final List ret = newArrayList(); + final Collection childrenMatches = ResourceUIUtil + .getChildrenMatchWithNotLoadedParent(getComparison(), match, getSide()); + if (childrenMatches.size() > 0) { + boolean setNames = childrenMatches.size() > 1; + for (Match child : childrenMatches) { + NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch(child); + if (setNames) { + notLoadedFragmentMatch + .setName(ResourceUIUtil.getResourceName(notLoadedFragmentMatch)); + } + MergeViewerItem.Container notLoadedFragmentItem = new MergeViewerItem.Container( + getComparison(), null, notLoadedFragmentMatch, notLoadedFragmentMatch, + notLoadedFragmentMatch, getSide(), getAdapterFactory()); + ret.add(notLoadedFragmentItem); + } + } + return ret; + } + + /** + * Returns the children of the container that apply on the given reference. + * + * @param group + * The active group provider. + * @param predicate + * The active predicate. + * @param container + * The container object. + * @param differences + * The differences that apply on the container. + * @param reference + * The reference for which we want the children. + */ + private List getChildrenOfReference(final IDifferenceGroupProvider group, + final Predicate predicate, final Object container, + final ImmutableList differences, final EReference reference) { + List ret = Lists.newArrayList(); + List featureContent = ReferenceUtil.getAsList((EObject)container, reference); + List mergeViewerItem = createMergeViewerItemFrom(featureContent); + if (getSide() != MergeViewerSide.ANCESTOR) { + Iterable differencesOnFeature = filter(differences, + onFeature(reference.getName())); + List filteredDiffs = filteredDiffs(differencesOnFeature, predicate, group); + ret.addAll(createInsertionPoints(getComparison(), reference, mergeViewerItem, filteredDiffs)); + } else { + ret.addAll(mergeViewerItem); + } + return ret; + } + + /** + * Returns the children of the container that apply on the given reference. + * + * @param group + * The active group provider. + * @param predicate + * The active predicate. + * @param container + * The container object. + * @param differences + * The differences that apply on the container. + * @param reference + * The feature map for which we want the children. + */ + private List getChildrenOfFeatureMap(final IDifferenceGroupProvider group, + final Predicate predicate, final Object container, + final ImmutableList differences, final EStructuralFeature featureMap) { + List ret = Lists.newArrayList(); + List mapContent = ReferenceUtil.getAsList((EObject)container, featureMap); + List featureContent = Lists.newArrayList(); + Set derivedFeatures = Sets.newLinkedHashSet(); + for (Object object : mapContent) { + if (object instanceof FeatureMap.Entry) { + featureContent.add(((FeatureMap.Entry)object).getValue()); + derivedFeatures.add(((FeatureMap.Entry)object).getEStructuralFeature()); + } + } + List mergeViewerItem = createMergeViewerItemFrom(featureContent); + if (getSide() != MergeViewerSide.ANCESTOR) { + Iterable differencesOnFeature = filter(differences, onFeatures(derivedFeatures)); + List filteredDiffs = filteredDiffs(differencesOnFeature, predicate, group); + ret.addAll( + createInsertionPoints(getComparison(), featureMap, mergeViewerItem, filteredDiffs)); + } else { + ret.addAll(mergeViewerItem); + } + return ret; + } + + private Predicate onFeatures(Iterable features) { + return Predicates.or(Iterables.transform(features, + new Function>() { + public Predicate apply(EStructuralFeature feature) { + return onFeature(feature.getName()); + } + })); + } + + /** + * Returns the list of children features to display within the UI. + * + * @param object + * @return + */ + protected Collection getChildrenFeatures(Object object) { + Collection ret = Lists.newArrayList(); + Collection childrenFeaturesFromItemProviderAdapter = getChildrenFeaturesFromItemProviderAdapter( + object); + if (childrenFeaturesFromItemProviderAdapter == null) { + ret = getChildrenFeaturesFromEClass(object); + } else { + ret = childrenFeaturesFromItemProviderAdapter; + } + + return ret; + } + + protected Collection getChildrenFeaturesFromEClass(Object object) { + ImmutableSet.Builder features = ImmutableSet.builder(); + if (object instanceof EObject) { + for (EReference feature : ((EObject)object).eClass().getEAllContainments()) { + features.add(feature); + } + } + return features.build(); + } + + @SuppressWarnings("unchecked") + protected Collection getChildrenFeaturesFromItemProviderAdapter( + Object object) { + Collection ret = null; + + Object treeItemContentProvider = getAdapterFactory().adapt(object, + ITreeItemContentProvider.class); + + if (treeItemContentProvider instanceof ItemProviderAdapter) { + ItemProviderAdapter itemProviderAdapter = (ItemProviderAdapter)treeItemContentProvider; + Method method; + try { + method = itemProviderAdapter.getClass().getMethod("getChildrenFeatures", Object.class); //$NON-NLS-1$ + method.setAccessible(true); + ret = (Collection)method.invoke(itemProviderAdapter, + object); + } catch (SecurityException | NoSuchMethodException | IllegalArgumentException + | IllegalAccessException | InvocationTargetException e) { + // ignore + } + } + + return ret; + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeMergeViewerItem.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeMergeViewerItem.java new file mode 100644 index 000000000..57a304838 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeMergeViewerItem.java @@ -0,0 +1,312 @@ +/******************************************************************************* + * Copyright (c) 2013, 2015 Obeo and others. + * 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.mergeviewer.item.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.getFirst; +import static com.google.common.collect.Lists.newArrayList; +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; + +import java.util.List; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.internal.utils.DiffUtil; +import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; + +/** + * A specific {@link MergeViewerItem} for {@link ResourceAttachmentChange}. + * + * @author Axel Richard + */ +public class ResourceAttachmentChangeMergeViewerItem extends MergeViewerItem.Container { + + /** + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem.Container#Container(Comparison + * comparison, Diff diff, Object left, Object right, Object ancestor, MergeViewerSide side, + * AdapterFactory adapterFactory) + */ + public ResourceAttachmentChangeMergeViewerItem(Comparison comparison, Diff diff, Resource left, + Resource right, Resource ancestor, IMergeViewer.MergeViewerSide side, + AdapterFactory adapterFactory) { + super(comparison, diff, left, right, ancestor, side, adapterFactory); + } + + /** + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem.Container#Container(Comparison, + * Diff, Match, MergeViewerSide, AdapterFactory) + */ + public ResourceAttachmentChangeMergeViewerItem(Comparison comparison, Diff diff, Match match, + IMergeViewer.MergeViewerSide side, AdapterFactory adapterFactory) { + super(comparison, diff, match, side, adapterFactory); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem.Container#hasChildren(IDifferenceGroupProvider, + * Predicate) + */ + @Override + public boolean hasChildren(IDifferenceGroupProvider groupProvider, Predicate predicate) { + return getChildren(groupProvider, predicate).length > 0; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem.Container#getChildren(IDifferenceGroupProvider, + * Predicate) + */ + @SuppressWarnings("unchecked") + @Override + public IMergeViewerItem[] getChildren(IDifferenceGroupProvider group, + Predicate filters) { + Object sideValue = getSideValue(getSide()); + Object bestSideValue = getBestSideValue(); + + List ret = newArrayList(); + + if (bestSideValue instanceof Resource) { + List mergeViewerItems = newArrayList(); + if (sideValue instanceof Resource) { + mergeViewerItems = createMergeViewerItemFrom(((Resource)sideValue).getContents()); + } + + if (getSide() != IMergeViewer.MergeViewerSide.ANCESTOR) { + EList differences = getComparison().getDifferences(); + Iterable racs = filter(differences, ResourceAttachmentChange.class); + List resourceAttachmentChanges = Lists.newArrayList(racs); + Object left = getLeft(); + Object right = getRight(); + Object ancestor = getAncestor(); + for (ResourceAttachmentChange resourceAttachmentChange : racs) { + // filter out merged reference changes + if (isInTerminalState(resourceAttachmentChange)) { + // Remove resource attachment changes that are not linked with the current resources. + resourceAttachmentChanges.remove(resourceAttachmentChange); + } else if (isUnrelated(resourceAttachmentChange, left) + && isUnrelated(resourceAttachmentChange, right) + && isUnrelated(resourceAttachmentChange, ancestor)) { + resourceAttachmentChanges.remove(resourceAttachmentChange); + } + } + ret.addAll(createInsertionPoints(mergeViewerItems, + (List)filteredDiffs(resourceAttachmentChanges, filters, + group))); + } else { + ret.addAll(mergeViewerItems); + } + + } + + return ret.toArray(getNoItemsArr()); + } + + private boolean isUnrelated(ResourceAttachmentChange change, Object resource) { + final String resourceURI = change.getResourceURI(); + return resource == null || (resource instanceof Resource && resourceURI != null + && !resourceURI.equals(((Resource)resource).getURI().toString())); + } + + /** + * Creates an IMergeViewerItem from an EObject. + * + * @param eObject + * the given eObject. + * @return an IMergeViewerItem. + */ + @Override + protected IMergeViewerItem createMergeViewerItemFrom(EObject eObject) { + + Match match = getComparison().getMatch(eObject); + + if (match != null) { + ResourceAttachmentChange rac = getFirst( + filter(match.getDifferences(), ResourceAttachmentChange.class), null); + if (rac != null) { + Object left = match.getLeft(); + Object right = match.getRight(); + Object ancestor = match.getOrigin(); + // Manage case where the resource attachment change is between an existing resource and an + // unknown resource + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.LEFT, rac) == null) { + left = null; + } + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.RIGHT, rac) == null) { + right = null; + } + if (MergeViewerUtil.getResource(getComparison(), MergeViewerSide.ANCESTOR, rac) == null) { + ancestor = null; + } + + return new MergeViewerItem.Container(getComparison(), rac, left, right, ancestor, getSide(), + getAdapterFactory()); + } + } + return null; + + } + + /** + * Creates insertion points for the given list of IMergeViewerItem corresponding to the given list of + * ResourceAttachmentChange. + * + * @param values + * the given list of IMergeViewerItem. + * @param racs + * the givel list of ResourceAttachmentChange + * @return the given list of IMergeViewerItem with additional insertion points. + */ + private List createInsertionPoints( + final List values, final List racs) { + List ret = newArrayList(values); + for (ResourceAttachmentChange diff : Lists.reverse(racs)) { + boolean rightToLeft = (getSide() == IMergeViewer.MergeViewerSide.LEFT); + Comparison comparison = getComparison(); + Object left = MergeViewerUtil.getValueFromResourceAttachmentChange(diff, comparison, + IMergeViewer.MergeViewerSide.LEFT); + Object right = MergeViewerUtil.getValueFromResourceAttachmentChange(diff, comparison, + IMergeViewer.MergeViewerSide.RIGHT); + + DifferenceSource source = diff.getSource(); + DifferenceKind kind = diff.getKind(); + boolean b1 = source == DifferenceSource.LEFT && kind == DifferenceKind.DELETE + && getSide() == MergeViewerSide.LEFT && !isInTerminalState(diff); + boolean b2 = source == DifferenceSource.LEFT && kind == DifferenceKind.ADD + && getSide() == MergeViewerSide.RIGHT && !isInTerminalState(diff); + boolean b3 = source == DifferenceSource.RIGHT && kind == DifferenceKind.ADD + && getSide() == MergeViewerSide.LEFT && !isInTerminalState(diff); + boolean b4 = source == DifferenceSource.RIGHT && kind == DifferenceKind.DELETE + && getSide() == MergeViewerSide.RIGHT && !isInTerminalState(diff); + + boolean b5 = isInTerminalState(diff) && source == DifferenceSource.LEFT + && kind == DifferenceKind.ADD && right == null; + boolean b6 = isInTerminalState(diff) && source == DifferenceSource.LEFT + && kind == DifferenceKind.DELETE && left == null; + boolean b7 = isInTerminalState(diff) && source == DifferenceSource.RIGHT + && kind == DifferenceKind.ADD && left == null; + boolean b8 = isInTerminalState(diff) && source == DifferenceSource.RIGHT + && kind == DifferenceKind.DELETE && right == null; + // do not duplicate insertion point for pseudo add conflict + // so we must only create one for pseudo delete conflict + boolean b9 = diff.getConflict() == null + || (diff.getConflict().getKind() != ConflictKind.PSEUDO || kind == DifferenceKind.DELETE); + + if ((b1 || b2 || b3 || b4 || b5 || b6 || b7 || b8) && b9) { + Object ancestor = MergeViewerUtil.getValueFromResourceAttachmentChange(diff, comparison, + IMergeViewer.MergeViewerSide.ANCESTOR); + if (left != null && MergeViewerUtil.getResource(comparison, IMergeViewer.MergeViewerSide.LEFT, + diff) == null) { + left = null; + } + if (right != null && MergeViewerUtil.getResource(comparison, + IMergeViewer.MergeViewerSide.RIGHT, diff) == null) { + right = null; + } + if (ancestor != null && MergeViewerUtil.getResource(comparison, + IMergeViewer.MergeViewerSide.ANCESTOR, diff) == null) { + ancestor = null; + } + if (b5 || b8) { + left = null; + } + if (b6 || b7) { + right = null; + } + IMergeViewerItem insertionPoint = new MergeViewerItem.Container(comparison, diff, left, right, + ancestor, getSide(), getAdapterFactory()); + + final int insertionIndex; + if (left == null && right == null && ancestor != null) { + Resource resource = MergeViewerUtil.getResource(comparison, + IMergeViewer.MergeViewerSide.ANCESTOR, diff); + List contents = resource.getContents(); + insertionIndex = contents.indexOf(ancestor); + } else { + insertionIndex = Math.min(findInsertionIndex(diff, rightToLeft), ret.size()); + } + + // offset the insertion by the number of previous insertion points in the list + // Can not b improved by keeping the number of created insertion points because the given + // "values" parameter may already contains some insertion points. + int realIndex = 0; + for (int index = 0; index < insertionIndex && realIndex < ret.size(); realIndex++) { + if (!ret.get(realIndex).isInsertionPoint()) { + index++; + } + } + ret.add(realIndex, insertionPoint); + } + } + return ret; + } + + /** + * Find an insertion index for the given diff. + * + * @param diff + * the given diff. + * @param rightToLeft + * the way of merge. + * @return an insertion index for the given diff. + */ + private int findInsertionIndex(Diff diff, boolean rightToLeft) { + final Match valueMatch = diff.getMatch(); + final Comparison comparison = getComparison(); + + final EObject expectedValue; + if (valueMatch.getLeft() != null) { + expectedValue = valueMatch.getLeft(); + } else { + expectedValue = valueMatch.getRight(); + } + + final Resource initialResource; + final Resource expectedResource; + if (rightToLeft) { + initialResource = MergeViewerUtil.getResource(comparison, IMergeViewer.MergeViewerSide.RIGHT, + diff); + expectedResource = MergeViewerUtil.getResource(comparison, IMergeViewer.MergeViewerSide.LEFT, + diff); + } else { + initialResource = MergeViewerUtil.getResource(comparison, IMergeViewer.MergeViewerSide.LEFT, + diff); + expectedResource = MergeViewerUtil.getResource(comparison, IMergeViewer.MergeViewerSide.RIGHT, + diff); + } + if (expectedResource != null) { + final List sourceList = initialResource.getContents(); + final List targetList = expectedResource.getContents(); + + return DiffUtil.findInsertionIndex(comparison, sourceList, targetList, expectedValue); + } else { + return 0; + } + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeProvider.java new file mode 100644 index 000000000..c1b3c1b7c --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/item/impl/ResourceAttachmentChangeProvider.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl; + +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemContentProvider; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemProviderConfiguration; + +/** + * Legacy Provider to keep backward compatibility with {@link ResourceAttachmentChangeMergeViewerItem}. + * + * @author Stefan Dirix + */ +public class ResourceAttachmentChangeProvider implements IMergeViewerItemContentProvider { + + /** + * {@inheritDoc} + */ + public Object getParent(Object object, IMergeViewerItemProviderConfiguration configuration) { + return ((ResourceAttachmentChangeMergeViewerItem)object).getParent(); + } + + /** + * {@inheritDoc} + */ + public Object[] getChildren(Object object, IMergeViewerItemProviderConfiguration configuration) { + return ((ResourceAttachmentChangeMergeViewerItem)object).getChildren( + configuration.getDifferenceGroupProvider(), configuration.getDifferenceFilterPredicate()); + } + + /** + * {@inheritDoc} + */ + public boolean hasChildren(Object object, IMergeViewerItemProviderConfiguration configuration) { + return ((ResourceAttachmentChangeMergeViewerItem)object).hasChildren( + configuration.getDifferenceGroupProvider(), configuration.getDifferenceFilterPredicate()); + } + + /** + * {@inheritDoc} + */ + public boolean canHandle(Object object) { + return object instanceof ResourceAttachmentChangeMergeViewerItem; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/AdapterFactoriesPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/AdapterFactoriesPreferencePage.java new file mode 100644 index 000000000..fcb60c2df --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/AdapterFactoriesPreferencePage.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + *******************************************************************************/ +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.ComparisonChain; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.internal.adapterfactory.RankedAdapterFactoryDescriptor; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.PreferencePage; +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.swt.SWT; +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.TableItem; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Preferences page used to enable/disable adapter factories that have been contributed to EMF Compare. + * + * @author Arthur Daussy + */ +public class AdapterFactoriesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** Height hint for the description label. */ + private static final int DESCRIPTION_LABEL_HEIGHT_HINT = 50; + + /** Width hint for configuration composite. */ + private static final int DESCRIPTION_LABEL_WIDTH_HINT = 400; + + private CheckboxTableViewer adapterFactoryDescriptorViewer; + + public void init(IWorkbench workbench) { + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, + EMFCompareRCPPlugin.PLUGIN_ID); + store.setSearchContexts(new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + setPreferenceStore(store); + } + + @Override + protected Control createContents(Composite parent) { + Composite containerComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(containerComposite); + containerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + Label introductionLabel = new Label(containerComposite, SWT.WRAP); + introductionLabel.setText( + EMFCompareRCPUIMessages.getString("AdapterFactoryPreferencePage.preferencePage.description")); //$NON-NLS-1$ + + createViewer(containerComposite); + + createDescriptionText(containerComposite); + + fillViewer(); + + return containerComposite; + } + + private void fillViewer() { + List descriptors = Lists + .newArrayList(EMFCompareRCPPlugin.getDefault().getAdapterFactoryRegistry().getDescriptors()); + Collections.sort(descriptors, new Comparator() { + + public int compare(RankedAdapterFactoryDescriptor o1, RankedAdapterFactoryDescriptor o2) { + return ComparisonChain.start().compare(o1.getId(), o2.getId()).result(); + } + }); + + adapterFactoryDescriptorViewer.setInput(descriptors); + if (!descriptors.isEmpty()) { + adapterFactoryDescriptorViewer.setSelection(new StructuredSelection(descriptors.get(0)), true); + } + + List disabledDescriptors = EMFComparePreferences.getDisabledAdapterFactoryDescriptorIds(); + + initViewer(disabledDescriptors); + } + + private void createDescriptionText(Composite parent) { + Group descriptionComposite = new Group(parent, SWT.NONE); + descriptionComposite.setText( + EMFCompareRCPUIMessages.getString("AdapterFactoryPreferencePage.descriptionGroup.text")); //$NON-NLS-1$ + descriptionComposite.setLayout(new GridLayout(1, false)); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + + final Label engineDescriptionLabel = new Label(descriptionComposite, SWT.WRAP); + engineDescriptionLabel + .setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); + layoutData.heightHint = DESCRIPTION_LABEL_HEIGHT_HINT; + layoutData.widthHint = DESCRIPTION_LABEL_WIDTH_HINT; + engineDescriptionLabel.setLayoutData(layoutData); + + // Updates description text with selection + adapterFactoryDescriptorViewer.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + if (adapterFactoryDescriptorViewer.equals(event.getSource())) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structSelection = (IStructuredSelection)selection; + Object first = structSelection.getFirstElement(); + if (first instanceof RankedAdapterFactoryDescriptor) { + String description = ((RankedAdapterFactoryDescriptor)first).getDescription(); + if (description != null) { + engineDescriptionLabel.setText(description); + } else { + engineDescriptionLabel.setText(""); //$NON-NLS-1$ + } + } + } + } + + } + }); + } + + private void createViewer(Composite containerComposite) { + adapterFactoryDescriptorViewer = CheckboxTableViewer.newCheckList(containerComposite, + SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + + adapterFactoryDescriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); + adapterFactoryDescriptorViewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + if (element instanceof RankedAdapterFactoryDescriptor) { + return ((RankedAdapterFactoryDescriptor)element).getLabel(); + + } + return super.getText(element); + } + }); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + adapterFactoryDescriptorViewer.getControl().setLayoutData(gd); + + // Prevents unselecting non optional providers + adapterFactoryDescriptorViewer.addCheckStateListener(new ICheckStateListener() { + + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (element instanceof RankedAdapterFactoryDescriptor) { + RankedAdapterFactoryDescriptor provider = (RankedAdapterFactoryDescriptor)element; + if (!provider.isOptional()) { + event.getCheckable().setChecked(element, true); + } + } + + } + }); + } + + private void initViewer(List disabledDescriptors) { + for (TableItem item : adapterFactoryDescriptorViewer.getTable().getItems()) { + RankedAdapterFactoryDescriptor descriptor = (RankedAdapterFactoryDescriptor)item.getData(); + if (!descriptor.isOptional()) { + item.setForeground(item.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + item.setChecked(true); + } else { + item.setChecked(!disabledDescriptors.contains(descriptor.getId())); + } + } + } + + @Override + protected void performDefaults() { + initViewer(Collections. emptyList()); + super.performDefaults(); + } + + @Override + public boolean performOk() { + Object[] checkedDescriptors = adapterFactoryDescriptorViewer.getCheckedElements(); + + SetView descriptorsToDisable = Sets.difference( + Sets.newHashSet( + EMFCompareRCPPlugin.getDefault().getAdapterFactoryRegistry().getDescriptors()), + Sets.newHashSet(checkedDescriptors)); + + Iterable descriptorsToDisableIds = Iterables.transform( + Iterables.filter(descriptorsToDisable, RankedAdapterFactoryDescriptor.class), + new Function() { + + public String apply(Object input) { + return ((RankedAdapterFactoryDescriptor)input).getId(); + } + }); + + getPreferenceStore().putValue(EMFComparePreferences.DISABLED_ADAPTER_FACTORY, + Joiner.on(';').join(descriptorsToDisableIds)); + + return super.performOk(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java new file mode 100644 index 000000000..b4b4e933f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/DataHolder.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 Arthur Daussy + * @param + * Type of the item descriptor. + */ +public class DataHolder { + + /** Field name (used for databinding). */ + public static final String DATA_FIELD_NAME = "data"; //$NON-NLS-1$ + + /** Filed holding multiple data. */ + private Set> data = new LinkedHashSet>(); + + /** + * Get data. + * + * @return Set> + */ + public Set> getData() { + return data; + } + + /** + * Set data. + * + * @param currentSelection + * . + */ + public void setData(Set> currentSelection) { + this.data = currentSelection; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EMFComparePreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EMFComparePreferencePage.java new file mode 100644 index 000000000..616c9a408 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EMFComparePreferencePage.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2006, 2013 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 org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +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.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * Global preference page for EMF Compare + * + * @author Arthur Daussy + */ +public class EMFComparePreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + public EMFComparePreferencePage() { + noDefaultAndApplyButton(); + } + + public EMFComparePreferencePage(String title) { + super(title); + noDefaultAndApplyButton(); + } + + public EMFComparePreferencePage(String title, ImageDescriptor image) { + super(title, image); + noDefaultAndApplyButton(); + } + + public void init(IWorkbench workbench) { + + } + + @Override + protected Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, false)); + Label label = new Label(container, SWT.NONE); + label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false)); + label.setText(EMFCompareRCPUIMessages.getString("EMFComparePreferencePage.intro.text")); //$NON-NLS-1$ + return container; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java new file mode 100644 index 000000000..3762a9d06 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java @@ -0,0 +1,590 @@ +/******************************************************************************* + * Copyright (c) 2014, 2017 Obeo and others. + * 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 + * Philip Langer - bug 499986, refactorings + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.CONFLICTS_DETECTOR; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.DIFF_ENGINES; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.EQUI_ENGINES; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.MATCH_ENGINE_DISABLE_ENGINES; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.REQ_ENGINES; +import static org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages.getString; + +import com.google.common.base.Strings; +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.conflict.IConflictDetector; +import org.eclipse.emf.compare.diff.IDiffEngine; +import org.eclipse.emf.compare.equi.IEquiEngine; +import org.eclipse.emf.compare.match.IMatchEngine; +import org.eclipse.emf.compare.match.IMatchEngine.Factory; +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.tracer.TracingConstant; +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.impl.InteractiveUIContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent.InteractiveUIBuilder; +import org.eclipse.emf.compare.req.IReqEngine; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.swt.SWT; +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.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Preference page for engines preferences + * + * @author Arthur Daussy + */ +public class EnginesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** The match engine registry. */ + private static final IItemRegistry MATCH_ENGINE_REGISTRY = EMFCompareRCPPlugin.getDefault() + .getMatchEngineFactoryDescriptorRegistry(); + + /** The req engine registry. */ + private static final IItemRegistry REQ_ENGINE_REGISTRY = EMFCompareRCPPlugin.getDefault() + .getReqEngineDescriptorRegistry(); + + /** The diff engine registry. */ + private static final IItemRegistry DIFF_ENGINE_REGISTRY = EMFCompareRCPPlugin.getDefault() + .getDiffEngineDescriptorRegistry(); + + /** The equi engine registry. */ + private static final IItemRegistry EQUI_ENGINE_REGISTRY = EMFCompareRCPPlugin.getDefault() + .getEquiEngineDescriptorRegistry(); + + /** The conflict engine registry. */ + private static final IItemRegistry CONFLICT_DETECTOR_REGISTRY = EMFCompareRCPPlugin + .getDefault().getConflictDetectorDescriptorRegistry(); + + /** Option to specify what is the default, if no preference or default preference is available. */ + private enum DefaultOption { + /** The highest ranked is the default. */ + HIGHEST_RANKED, + /** All registered engines should be the default. */ + ALL; + } + + /** An option to specify what should be stored in the preferences. */ + private enum StoreOption { + /** The enabled items. */ + ENABLED_ITEMS, + /** The disabled items. */ + DISABLED_ITEMS; + } + + /** Pointer to all {@link InteractiveUIContent} of each tab */ + private final Map interactiveUis = new HashMap(); + + /** Data regarding the Difference selected engine */ + private final DataHolder diffEngineData = new DataHolder(); + + /** Data regarding the Equivalence selected engine */ + private final DataHolder equiEngineData = new DataHolder(); + + /** Data regarding the Requirement selected engine */ + private final DataHolder reqEngineData = new DataHolder(); + + /** Data regarding the Conflicts detector selected engine */ + private final DataHolder conflictsDetectorData = new DataHolder(); + + /** Data regarding the selected match engine factories. */ + private final DataHolder matchEnginesData = new DataHolder(); + + public EnginesPreferencePage() { + super(); + } + + public EnginesPreferencePage(String title) { + super(title); + } + + public EnginesPreferencePage(String title, ImageDescriptor image) { + super(title, image); + } + + public void init(IWorkbench workbench) { + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, + EMFCompareRCPPlugin.PLUGIN_ID); + store.setSearchContexts(new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + setPreferenceStore(store); + } + + @Override + protected Control createContents(Composite parent) { + + Composite container = new Composite(parent, SWT.NULL); + container.setLayout(new FillLayout(SWT.HORIZONTAL)); + TabFolder tabFolder = new TabFolder(container, SWT.NONE); + + createMatchEngineTab(tabFolder); + createDiffEngineTab(tabFolder); + createEquiEngineTab(tabFolder); + createReqEngineTab(tabFolder); + createConflictDetectorTab(tabFolder); + + return container; + } + + /** + * Create an {@link InteractiveUIContent} object of a specific type of engine. + * + * @param registry + * Registry holding engines. + * @param tabComposite + * Holding composite. + * @param dataHolder + * Data that will be synchronized with the UI. + * @param + * type of engine. + * @return {@link InteractiveUIContent} for a specific type of engine. + */ + private InteractiveUIContent createEngineUIBuilder(IItemRegistry registry, Composite tabComposite, + DataHolder dataHolder) { + String preferenceKey = preferenceKey(registry); + IItemDescriptor defaultEngine = ItemUtil.getDefaultItemDescriptor(registry, preferenceKey); + InteractiveUIBuilder uiBuilder = new InteractiveUIBuilder(tabComposite, registry); + uiBuilder.setSimple(true).setDefaultCheck(Collections.singleton(defaultEngine)) + .setDefaultSelection(defaultEngine).setHoldingData(dataHolder); + return uiBuilder.build(); + } + + /** + * Returns the preference key for the given registry. + * + * @param registry + * The registry to get the preference key for. + * @return The preference key. + */ + private String preferenceKey(IItemRegistry registry) { + if (registry == MATCH_ENGINE_REGISTRY) { + return MATCH_ENGINE_DISABLE_ENGINES; + } else if (registry == DIFF_ENGINE_REGISTRY) { + return DIFF_ENGINES; + } else if (registry == REQ_ENGINE_REGISTRY) { + return REQ_ENGINES; + } else if (registry == EQUI_ENGINE_REGISTRY) { + return EQUI_ENGINES; + } else if (registry == CONFLICT_DETECTOR_REGISTRY) { + return CONFLICTS_DETECTOR; + } + throw new IllegalArgumentException("Unknown registry."); //$NON-NLS-1$ + } + + /** + * Create a tab to select one Conflict Detector. + * + * @param tabFolder + */ + private void createConflictDetectorTab(TabFolder tabFolder) { + Composite tabComposite = createTabSkeleton(tabFolder, + getString("EnginesPreferencePage.conflictDetector.tab.label"), //$NON-NLS-1$ + getString("EnginesPreferencePage.conflictDetectorIntro.text"));//$NON-NLS-1$ + + InteractiveUIContent interactiveContent = createEngineUIBuilder(CONFLICT_DETECTOR_REGISTRY, + tabComposite, conflictsDetectorData); + + interactiveUis.put(preferenceKey(CONFLICT_DETECTOR_REGISTRY), interactiveContent); + } + + /** + * Create a tab to select one Requirement Engine. + * + * @param tabFolder + */ + private void createReqEngineTab(TabFolder tabFolder) { + Composite tabComposite = createTabSkeleton(tabFolder, + getString("EnginesPreferencePage.requirementEngine.tab.label"), //$NON-NLS-1$ + getString("EnginesPreferencePage.reqEngineIntro.text")); //$NON-NLS-1$ + + InteractiveUIContent interactiveContent = createEngineUIBuilder(REQ_ENGINE_REGISTRY, tabComposite, + reqEngineData); + + interactiveUis.put(preferenceKey(REQ_ENGINE_REGISTRY), interactiveContent); + } + + /** + * Create a tab to select one Equivalence Engine. + * + * @param tabFolder + */ + private void createEquiEngineTab(TabFolder tabFolder) { + Composite tabComposite = createTabSkeleton(tabFolder, + getString("EnginesPreferencePage.equivalenceEngine.tab.label"), //$NON-NLS-1$ + getString("EnginesPreferencePage.equiEngineIntro.text")); //$NON-NLS-1$ + + InteractiveUIContent interactiveContent = createEngineUIBuilder(EQUI_ENGINE_REGISTRY, tabComposite, + equiEngineData); + + interactiveUis.put(preferenceKey(EQUI_ENGINE_REGISTRY), interactiveContent); + } + + /** + * Create a tab to select one Difference Engine. + * + * @param tabFolder + */ + private void createDiffEngineTab(TabFolder tabFolder) { + Composite tabComposite = createTabSkeleton(tabFolder, + getString("EnginesPreferencePage.differenceEngine.tab.label"), //$NON-NLS-1$ + getString("EnginesPreferencePage.diffEngineIntro.text")); //$NON-NLS-1$ + + InteractiveUIContent interactiveContent = createEngineUIBuilder(DIFF_ENGINE_REGISTRY, tabComposite, + diffEngineData); + + interactiveUis.put(preferenceKey(DIFF_ENGINE_REGISTRY), interactiveContent); + } + + /** + * Create a tab to disable/enable Match Engines. + * + * @param tabFolder + */ + private void createMatchEngineTab(TabFolder tabFolder) { + Composite tabComposite = createTabSkeleton(tabFolder, + getString("EnginesPreferencePage.matchEngine.tab.label"), //$NON-NLS-1$ + getString("EnginesPreferencePage.matchEngineIntro.text")); //$NON-NLS-1$ + + Map configuratorUIRegistry = EMFCompareRCPUIPlugin.getDefault() + .getMatchEngineConfiguratorRegistry(); + Set> activeItems = ItemUtil.getActiveItems(MATCH_ENGINE_REGISTRY, + EMFCompareRCPPlugin.PLUGIN_ID, MATCH_ENGINE_DISABLE_ENGINES); + + InteractiveUIBuilder builder = new InteractiveUIBuilder( + tabComposite, MATCH_ENGINE_REGISTRY); + builder.setConfiguratorUIRegistry(configuratorUIRegistry).setDefaultCheck(activeItems) + .setConfigurationNodeKey(MATCH_ENGINE_DISABLE_ENGINES).setHoldingData(matchEnginesData); + // Forbid unchecking all match engines + InteractiveUIContent uiContent = builder.build(); + uiContent.getViewer().addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (!event.getChecked()) { + // Prevent from nothing checked + if (((CheckboxTableViewer)event.getSource()).getCheckedElements().length == 0) { + ((CheckboxTableViewer)event.getSource()).setCheckedElements(new Object[] {element }); + MessageDialog.openWarning(getShell(), + EMFCompareRCPUIMessages + .getString("InteractiveUIContent.incorrectSelection.title"), //$NON-NLS-1$ + EMFCompareRCPUIMessages + .getString("InteractiveUIContent.incorrectSelection.message")); //$NON-NLS-1$ + } + } + + } + }); + // Save for reset default + interactiveUis.put(MATCH_ENGINE_DISABLE_ENGINES, uiContent); + } + + /** + * Create skeleton of a tab. + * + * @param tabFolder + * @param tabLabel + * @param introText + * Text use as description a tab + * @return Main composite of the tab + */ + private Composite createTabSkeleton(TabFolder tabFolder, String tabLabel, String introText) { + TabItem tbtmMain = new TabItem(tabFolder, SWT.NONE); + tbtmMain.setText(tabLabel); + Composite tabComposite = new Composite(tabFolder, SWT.NONE); + tbtmMain.setControl(tabComposite); + tabComposite.setLayout(new GridLayout(1, true)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1); + tabComposite.setLayoutData(layoutData); + Label descriptionText = new Label(tabComposite, SWT.WRAP); + descriptionText.setText(introText); + return tabComposite; + } + + @Override + public boolean performOk() { + setEnginesPreferences(); + storeConfigurations(); + return super.performOk(); + } + + /** + * Set all engines preferences. + */ + private void setEnginesPreferences() { + setEnginePreferences(DIFF_ENGINE_REGISTRY, diffEngineData); + setEnginePreferences(EQUI_ENGINE_REGISTRY, equiEngineData); + setEnginePreferences(REQ_ENGINE_REGISTRY, reqEngineData); + setEnginePreferences(CONFLICT_DETECTOR_REGISTRY, conflictsDetectorData); + setEnginePreferences(MATCH_ENGINE_REGISTRY, matchEnginesData, DefaultOption.ALL, + StoreOption.DISABLED_ITEMS); + } + + /** + * Store the value of the configuration of each engine into preferences. + */ + private void storeConfigurations() { + for (Entry interactiveContentEntry : interactiveUis.entrySet()) { + for (Entry configuratorEntry : interactiveContentEntry.getValue() + .getConfigurators().entrySet()) { + AbstractConfigurationUI configurator = configuratorEntry.getValue(); + configurator.storeConfiguration(); + } + } + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder traceMessage = new StringBuilder("Engines preference serialization:\n"); //$NON-NLS-1$ + String prefDelimiter = " :\n"; //$NON-NLS-1$ + String newLine = "\n"; //$NON-NLS-1$ + traceMessage.append(DIFF_ENGINES).append(prefDelimiter) + .append(getPreferenceStore().getString(DIFF_ENGINES)).append(newLine); + traceMessage.append(EQUI_ENGINES).append(prefDelimiter) + .append(getPreferenceStore().getString(EQUI_ENGINES)).append(newLine); + traceMessage.append(REQ_ENGINES).append(prefDelimiter) + .append(getPreferenceStore().getString(REQ_ENGINES)).append(newLine); + traceMessage.append(CONFLICTS_DETECTOR).append(prefDelimiter) + .append(getPreferenceStore().getString(CONFLICTS_DETECTOR)).append(newLine); + traceMessage.append(MATCH_ENGINE_DISABLE_ENGINES).append(prefDelimiter) + .append(getPreferenceStore().getString(MATCH_ENGINE_DISABLE_ENGINES)).append(newLine); + EMFCompareRCPPlugin.getDefault().log(IStatus.INFO, traceMessage.toString()); + } + } + + @Override + protected void performDefaults() { + resetDefaultPreferences(DIFF_ENGINE_REGISTRY, diffEngineData); + resetDefaultPreferences(REQ_ENGINE_REGISTRY, reqEngineData); + resetDefaultPreferences(EQUI_ENGINE_REGISTRY, equiEngineData); + resetDefaultPreferences(CONFLICT_DETECTOR_REGISTRY, conflictsDetectorData); + resetDefaultPreferences(MATCH_ENGINE_REGISTRY, matchEnginesData, DefaultOption.ALL, + StoreOption.DISABLED_ITEMS); + resetConfigurations(); + super.performDefaults(); + } + + /** + * Reset all configuration of each engine to its default value. + */ + private void resetConfigurations() { + for (Entry interactiveContentEntry : interactiveUis.entrySet()) { + for (AbstractConfigurationUI configurator : interactiveContentEntry.getValue().getConfigurators() + .values()) { + configurator.resetDefault(); + } + } + } + + /** + * Reset engine preference to default using highest rank strategy. + * + * @param registry + * @param preferenceKey + */ + private void resetDefaultPreferences(IItemRegistry registry, DataHolder dataObject) { + resetDefaultPreferences(registry, dataObject, DefaultOption.HIGHEST_RANKED, + StoreOption.ENABLED_ITEMS); + } + + /** + * Reset engine preference to default using the specified defaultOption. + * + * @param registry + * @param dataObject + * @param defaultOption + */ + private void resetDefaultPreferences(IItemRegistry registry, DataHolder dataObject, + DefaultOption defaultOption, StoreOption storeOption) { + InteractiveUIContent interactiveContent = interactiveUis.get(preferenceKey(registry)); + if (interactiveContent != null) { + Set> defaultEngines = getDefaultDescriptors(registry, defaultOption); + Set> defaultEnginesToSelect = getItemsToSelect(defaultEngines, registry, + storeOption); + interactiveContent.selectAll(defaultEnginesToSelect); + interactiveContent.checkElements(defaultEnginesToSelect); + dataObject.setData(defaultEnginesToSelect); + } + } + + /** + * Returns the items to select in the UI. + *

+ * This is equal to {@link #getItemsToStore(Set, IItemRegistry, StoreOption)}, which considers whether the + * {@link StoreOption#ENABLED_ITEMS} or {@link StoreOption#DISABLED_ITEMS} are stored, except that it + * returns all registered engines from the registry are returned, if + * engines is empty. + *

+ * + * @param engines + * @param registry + * @param storeOption + * @return + */ + private Set> getItemsToSelect(Set> engines, + IItemRegistry registry, StoreOption storeOption) { + Set> itemsToStore = getItemsToStore(engines, registry, storeOption); + if (StoreOption.DISABLED_ITEMS.equals(storeOption) && itemsToStore.isEmpty()) { + return Sets.newHashSet(registry.getItemDescriptors()); + } + return itemsToStore; + } + + /** + * Returns the configured default item descriptors or the highest ranked item descriptor if there is no + * default. + * + * @param registry + * The registry to obtain item descriptors from. + * @param defaultOption + * Option specifying what is the default if no other default is pre-configured (all or + * highest-ranked). + * @return The default item descriptors. + */ + private Set> getDefaultDescriptors(IItemRegistry registry, + DefaultOption defaultOption) { + final String defaultValue = getPreferenceStore().getDefaultString(preferenceKey(registry)); + final Set> defaultDescriptors = new LinkedHashSet<>(); + if (!Strings.isNullOrEmpty(defaultValue)) { + for (String engineId : defaultValue.split(ItemUtil.PREFERENCE_DELIMITER)) { + final IItemDescriptor itemDescriptor = registry.getItemDescriptor(engineId); + if (itemDescriptor != null) { + defaultDescriptors.add(itemDescriptor); + } + } + } + if (defaultDescriptors.isEmpty()) { + switch (defaultOption) { + case ALL: + defaultDescriptors.addAll(registry.getItemDescriptors()); + break; + case HIGHEST_RANKED: + // fall through + default: + defaultDescriptors.add(registry.getHighestRankingDescriptor()); + break; + } + } + return defaultDescriptors; + } + + /** + * Stores the engines specified in data for the items in the given registry. + *

+ * This method will store the enabled items considering the highest ranked item as the default. + *

+ * + * @param registry + * The registry. + * @param data + * The data holding the selected items. + */ + private void setEnginePreferences(IItemRegistry registry, DataHolder data) { + setEnginePreferences(registry, data, DefaultOption.HIGHEST_RANKED, StoreOption.ENABLED_ITEMS); + } + + /** + * Stores the engines specified in data for the items in the given registry. + * + * @param registry + * The registry. + * @param data + * The data holding the selected items. + * @param defaultOption + * The default option to consider when storing the preferences. + * @param storeOption + * The store option to consider when storing the preferences. + */ + private void setEnginePreferences(IItemRegistry registry, DataHolder data, + DefaultOption defaultOption, StoreOption storeOption) { + Set> selectedEngines = data.getData(); + Set> toStore = getItemsToStore(selectedEngines, registry, storeOption); + if (deviatesFromDefaults(toStore, registry, defaultOption, storeOption)) { + StringBuilder descriptorsKey = new StringBuilder(); + for (Iterator> iterator = toStore.iterator(); iterator.hasNext();) { + IItemDescriptor iItemDescriptor = iterator.next(); + descriptorsKey.append(iItemDescriptor.getID()); + if (iterator.hasNext()) { + descriptorsKey.append(ItemUtil.PREFERENCE_DELIMITER); + } + } + getPreferenceStore().setValue(preferenceKey(registry), descriptorsKey.toString()); + } else { + getPreferenceStore().setToDefault(preferenceKey(registry)); + } + } + + /** + * Returns the items to be stored to store selectedEngines considering the given + * storeOption. + * + * @param selectedEngines + * @param registry + * @param storeOption + * @return The items to be stored. + */ + private Set> getItemsToStore(Set> selectedEngines, + IItemRegistry registry, StoreOption storeOption) { + switch (storeOption) { + case DISABLED_ITEMS: + return Sets.difference(Sets.newHashSet(registry.getItemDescriptors()), selectedEngines); + case ENABLED_ITEMS: + // fall through + default: + return selectedEngines; + } + } + + /** + * Specifies whether the list itemsToStore are different from the defaults. + *

+ * This takes into account how the items should be stored, as specified by the storeOptions, + * as well as what the defaults are, as specified by the defaultOptions. + * + * @param itemsToStore + * @param registry + * @param defaultOption + * @param storeOption + * @return true if the items to store are different from the defaults and thus shall be + * stored, or false otherwise. + */ + private boolean deviatesFromDefaults(Set> itemsToStore, IItemRegistry registry, + DefaultOption defaultOption, StoreOption storeOption) { + Set> defaults = getDefaultDescriptors(registry, defaultOption); + return itemsToStore != null && !Sets.symmetricDifference(defaults, itemsToStore).isEmpty(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/FiltersPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/FiltersPreferencePage.java new file mode 100644 index 000000000..b94a8d872 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/FiltersPreferencePage.java @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.ALWAYS; +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.NEVER; +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.PROMPT; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +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.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant; +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.structuremergeviewer.filters.impl.DifferenceFilterManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.jface.databinding.viewers.IViewerObservableSet; +import org.eclipse.jface.databinding.viewers.ViewersObservables; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckboxTableViewer; +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.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +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.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * Preference page for {@link IDifferenceFilter}. + * + * @author Arthur Daussy + */ +public class FiltersPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** Preference page ID. */ + public static final String PAGE_ID = "org.eclipse.emf.compare.rcp.ui.preferencePage.filters"; //$NON-NLS-1$ + + /** Preference key holding synchronization behavior value. */ + public static final String SYNCHRONIZATION_BEHAVIOR = "org.eclipse.emf.compare.rcp.ui.filters.syncbehavior"; //$NON-NLS-1$ + + /** Width hint for introduction label. */ + private static final int INTRO_TEXT_WIDTH_HINT = 400; + + /** Values used for the combobox. */ + private static final List SYNC_VALUES = ImmutableList.of(ALWAYS, NEVER, PROMPT); + + /** Filter manager. Used to retrieve current and default configuration. */ + private DifferenceFilterManager filterManager = null; + + /** Interactive content holding UI components for enabled/disabled filters. */ + private InteractiveFilterUIContent defaultFilterInteractiveContent; + + /** Interactive content holding UI components for activated/deactivated filters. */ + private InteractiveFilterUIContent activateFilterInteractiveContent; + + /** The tab used to choose enabled filters. */ + private Composite enabledFilterTabComposite; + + /** The tab used to choose active filters. */ + private Composite activateFilterTabComposite; + + /** Combo holding synchronization behavior preferences. */ + private Combo combo; + + /** Field holding {@link SynchronizationBehavior} */ + private String synchronizationBehaviorValue; + + public void init(IWorkbench workbench) { + setPreferenceStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + } + + @Override + protected Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(container); + GridDataFactory.fillDefaults().grab(true, true).applyTo(container); + + createSynchronizationBehaviorContent(container); + setComboInput(getCurrentSynchronizationBehavior()); + + TabFolder tabFolder = new TabFolder(container, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).applyTo(tabFolder); + + // Create tab to choose filters that are enabled by default + createDefaultEnabledFilterTab(tabFolder); + // Create tab to activate or deactivate totally filters + createActivateFilterTab(tabFolder); + return container; + } + + /** + * Create a tab to choose which filters to enable by default. + * + * @param tabFolder + */ + private void createDefaultEnabledFilterTab(TabFolder tabFolder) { + enabledFilterTabComposite = createTabSkeleton(tabFolder, + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.select.tab.label"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.selectIntro.text")); //$NON-NLS-1$ + if (filterManager == null) { + filterManager = EMFCompareRCPUIPlugin.getDefault().getDifferenceFilterManager(); + } + defaultFilterInteractiveContent = new InteractiveFilterUIContent(enabledFilterTabComposite, + filterManager.getAllFilters(), filterManager.getCurrentByDefaultFilters(), false); + } + + /** + * Create a tab to select which filters to activate or deactivate. + * + * @param tabFolder + */ + private void createActivateFilterTab(TabFolder tabFolder) { + activateFilterTabComposite = createTabSkeleton(tabFolder, + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.activate.tab.label"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.activateIntro.text")); //$NON-NLS-1$ + if (filterManager == null) { + filterManager = EMFCompareRCPUIPlugin.getDefault().getDifferenceFilterManager(); + } + activateFilterInteractiveContent = new InteractiveFilterUIContent(activateFilterTabComposite, + filterManager.getAllFilters(), filterManager.getCurrentInactiveFilters(), true); + } + + /** + * Create skeleton of a tab. + * + * @param tabFolder + * @param tabLabel + * @param introText + * Text use as description a tab + * @return Main composite of the tab + */ + private Composite createTabSkeleton(TabFolder tabFolder, String tabLabel, String introText) { + TabItem tbtmMain = new TabItem(tabFolder, SWT.NONE); + tbtmMain.setText(tabLabel); + Composite tabComposite = new Composite(tabFolder, SWT.NONE); + tbtmMain.setControl(tabComposite); + GridLayout layout = new GridLayout(1, true); + tabComposite.setLayout(layout); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1); + tabComposite.setLayoutData(layoutData); + // Description text + Label introductionText = new Label(tabComposite, SWT.WRAP); + GridDataFactory.fillDefaults().grab(true, false).hint(INTRO_TEXT_WIDTH_HINT, SWT.DEFAULT) + .applyTo(introductionText); + introductionText.setText(introText); + return tabComposite; + } + + /** + * Content for synchronization behavior preferences. + * + * @param parent + */ + private void createSynchronizationBehaviorContent(Composite parent) { + Composite synchronizationComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(synchronizationComposite); + Label label = new Label(synchronizationComposite, SWT.WRAP); + label.setText(EMFCompareRCPUIMessages.getString("InteractiveFilterUIContent.sync.behavior.label")); //$NON-NLS-1$ + label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + combo = new Combo(synchronizationComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + for (String comboLabel : SYNC_VALUES) { + combo.add(comboLabel); + } + combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true)); + combo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (combo.equals(e.getSource())) { + synchronizationBehaviorValue = combo.getItem(combo.getSelectionIndex()); + } + } + + }); + } + + /** + * Select the correct behavior in the interactive UI. + * + * @param behavior + */ + public void setComboInput(String behavior) { + int index = 0; + for (String value : SYNC_VALUES) { + if (value.equals(behavior)) { + combo.select(index); + synchronizationBehaviorValue = behavior; + } + index++; + } + } + + /** + * Gets the current value of the filter synchronization behavior. + *

+ * This value can only be one of the following: + *

    + *
  • {@link MessageDialogWithToggle#PROMPT}
  • + *
  • {@link MessageDialogWithToggle#ALWAYS}
  • + *
  • {@link MessageDialogWithToggle#NEVER}
  • + *
+ *

+ * + * @return String. + */ + public String getCurrentSynchronizationBehavior() { + String value = getPreferenceStore().getString(SYNCHRONIZATION_BEHAVIOR); + if (value == null || !SYNC_VALUES.contains(value)) { + value = getDefaultSynchronizationBehavior(); + } + return value; + } + + /** + * @return The default value of filter synchronization behavior. + */ + public String getDefaultSynchronizationBehavior() { + return MessageDialogWithToggle.PROMPT; + } + + /** + * Set the current value of the filter synchronization behavior. + * + * @param newBehavior + * New value. + */ + public void setCurrentSynchronizationBehavior(String newBehavior) { + if (getDefaultSynchronizationBehavior().equals(newBehavior)) { + getPreferenceStore().setToDefault(SYNCHRONIZATION_BEHAVIOR); + } else { + getPreferenceStore().setValue(SYNCHRONIZATION_BEHAVIOR, newBehavior); + } + // Trace preferences values + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder builder = new StringBuilder(); + // Print each preferences + builder.append("Preference ").append(SYNCHRONIZATION_BEHAVIOR).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$ + String preferenceValue = getPreferenceStore().getString(SYNCHRONIZATION_BEHAVIOR); + builder.append(preferenceValue); + EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean performOk() { + filterManager.setCurrentByDefaultFilters(defaultFilterInteractiveContent.getCheckedFilter()); + filterManager.setCurrentActiveFilters(activateFilterInteractiveContent.getCheckedFilter()); + setCurrentSynchronizationBehavior(synchronizationBehaviorValue); + return super.performOk(); + } + + /** + * {@inheritDoc} + */ + @Override + protected void performDefaults() { + if (activateFilterTabComposite.isVisible()) { + activateFilterInteractiveContent.checkElements(filterManager.getAllFilters()); + } + if (enabledFilterTabComposite.isVisible()) { + defaultFilterInteractiveContent.checkElements(filterManager.getInitialByDefaultFilters()); + setComboInput(getDefaultSynchronizationBehavior()); + } + super.performDefaults(); + } + + /** + * Interactive UI for filter preference page. + * + * @author Arthur Daussy + */ + private static class InteractiveFilterUIContent { + + /** Height hint for the description label. */ + private static final int DESCRIPTION_LABEL_HEIGHT_HINT = 50; + + /** Width hint for configuration composite. */ + private static final int DESCRIPTION_LABEL_WIDTH_HINT = 400; + + /** Text that will be updated with the description of the viewer. */ + private final Label descriptionText; + + /** Viewer of {@link IDifferenceFilter}. */ + private CheckboxTableViewer viewer; + + /** DataHolder for enabled/disabled {@link IDifferenceFilter}. */ + private FilterDataHolder dataHolder = new FilterDataHolder(); + + /** DataHolder for activated/deactivated {@link IDifferenceFilter}. */ + private FilterDataHolder allFilters = new FilterDataHolder(); + + private InteractiveFilterUIContent(Composite parent, Collection filters, + Collection defaultCheck, boolean isDeactivateTab) { + super(); + Composite contentComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().extendedMargins(0, 0, 10, 0).applyTo(contentComposite); + contentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + Label introductionText = new Label(contentComposite, SWT.WRAP); + if (isDeactivateTab) { + introductionText.setText( + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.INTRO_DEACTIVATE_TEXT")); //$NON-NLS-1$ + } else { + introductionText.setText( + EMFCompareRCPUIMessages.getString("FiltersPreferencePage.INTRO_SELECT_TEXT")); //$NON-NLS-1$ + } + introductionText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); + // Engine chooser composite + Composite viewerComposite = new Composite(contentComposite, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(viewerComposite); + viewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + viewer = createViewer(viewerComposite); + // Descriptor engine Text + this.descriptionText = createDescriptionComposite(contentComposite); + + setViewerInput(Lists.newArrayList(filters)); + if (isDeactivateTab) { + SetView activatedFilters = Sets.difference(Sets.newLinkedHashSet(filters), + Sets.newLinkedHashSet(defaultCheck)); + bindAndInit(activatedFilters); + } else { + bindAndInit(Sets.newLinkedHashSet(defaultCheck)); + } + allFilters.setFilters(Sets.newLinkedHashSet(filters)); + } + + /** + * @return All checked {@link IDifferenceFilter}. + */ + public Set getCheckedFilter() { + return dataHolder.getFilters(); + } + + private void setViewerInput(List filters) { + Collections.sort(filters, new Comparator() { + + public int compare(IDifferenceFilter o1, IDifferenceFilter o2) { + if (o1 == o2) { + return 0; + } else if (o1 == null || o1.getLabel() == null) { + return -1; + } else if (o2 == null || o2.getLabel() == null) { + return 1; + } + return o1.getLabel().compareTo(o2.getLabel()); + } + }); + viewer.setInput(filters); + select(filters.iterator().next()); + } + + private CheckboxTableViewer createViewer(Composite viewerCompsite) { + CheckboxTableViewer descriptorViewer = CheckboxTableViewer.newCheckList(viewerCompsite, + SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); + descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); + descriptorViewer.setLabelProvider(new FilterLabelProvider()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + descriptorViewer.getControl().setLayoutData(gd); + setViewer(descriptorViewer); + return descriptorViewer; + } + + private void bindAndInit(Set defaultCheck) { + if (dataHolder != null) { + if (defaultCheck != null) { + dataHolder.setFilters(defaultCheck); + } + // Bind data + bindMultipleData(viewer, dataHolder); + } + } + + /** + * Bind UI to data object. + * + * @param engineBindingProperty + * @param descriptorViewer + * @param dataObject + */ + private void bindMultipleData(CheckboxTableViewer descriptorViewer, FilterDataHolder dataObject) { + DataBindingContext ctx = new DataBindingContext(); + // Bind the button with the corresponding field in data + IViewerObservableSet target = ViewersObservables.observeCheckedElements(descriptorViewer, + IDifferenceFilter.class); + IObservableSet model = PojoProperties.set(FilterDataHolder.class, FilterDataHolder.FIELD_NAME) + .observe(dataObject); + + ctx.bindSet(target, model); + } + + /** + * Check element in the viewer. + * + * @param checkedFilter + * Element to check. + */ + public void checkElements(Set checkedFilter) { + viewer.setCheckedElements(checkedFilter.toArray()); + dataHolder.setFilters(checkedFilter); + } + + /** + * Composite for description. This composite hold the text widget that will update with the current + * selection + * + * @param composite + * @return + */ + private Label createDescriptionComposite(Composite composite) { + Group descriptionComposite = new Group(composite, SWT.NONE); + descriptionComposite.setText( + EMFCompareRCPUIMessages.getString("InteractiveUIContent.descriptionComposite.label")); //$NON-NLS-1$ + GridLayoutFactory.swtDefaults().applyTo(descriptionComposite); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + Label engineDescriptionLabel = new Label(descriptionComposite, SWT.WRAP); + GridDataFactory.fillDefaults().grab(true, false) + .hint(DESCRIPTION_LABEL_WIDTH_HINT, DESCRIPTION_LABEL_HEIGHT_HINT) + .applyTo(engineDescriptionLabel); + return engineDescriptionLabel; + } + + /** + * Handle a selection in the viewer. Update related components. + * + * @param descriptor + */ + public void select(IDifferenceFilter descriptor) { + // Update viewer + viewer.setSelection(new StructuredSelection(descriptor), true); + String description = descriptor.getDescription(); + if (description != null) { + descriptionText.setText(description); + } else { + descriptionText.setText(""); //$NON-NLS-1$ + } + + } + + /** + * @param viewer + * A {@link StructuredViewer} of {@link IItemDescriptor} + */ + public void setViewer(CheckboxTableViewer inputViewer) { + this.viewer = inputViewer; + viewer.addSelectionChangedListener(new DescriptionListener()); + } + + /** + * Listener to update description text + * + * @author Arthur Daussy + */ + 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 IDifferenceFilter) { + IDifferenceFilter desc = (IDifferenceFilter)selected; + String description = desc.getDescription(); + if (description != null) { + descriptionText.setText(description); + } else { + descriptionText.setText(""); //$NON-NLS-1$ + } + } + } + + } + } + + /** + * Label provider for {@link IDifferenceFilter}. + * + * @author Arthur Daussy + */ + private static final class FilterLabelProvider extends LabelProvider { + /** + * {@inheritDoc} + */ + @Override + public String getText(Object element) { + if (element instanceof IDifferenceFilter) { + return ((IDifferenceFilter)element).getLabel(); + } + return super.getText(element); + } + } + + /** + * Data holder for checked {@link IDifferenceFilter}. + * + * @author Arthur Daussy + */ + private static final class FilterDataHolder { + + private static final String FIELD_NAME = "filters"; //$NON-NLS-1$ + + private Set filters; + + public Set getFilters() { + return filters; + } + + public void setFilters(Set filters) { + this.filters = filters; + } + + } + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java new file mode 100644 index 000000000..408fae996 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.ALWAYS; +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.NEVER; +import static org.eclipse.jface.dialogs.MessageDialogWithToggle.PROMPT; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant; +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.preferences.impl.GroupsInteractiveContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.ItemDescriptorLabelProvider; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +/** + * Preference page for group providers. + * + * @author Arthur Daussy + */ +public class GroupsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** Id of the preference page. */ + public static final String PAGE_ID = "org.eclipse.emf.compare.rcp.ui.preferencePage.groups"; //$NON-NLS-1$ + + /** Default value for the synchronization behavior for 2-way and 3-way comparison. */ + private static final String SYNC_DEFAULT_VALUE = MessageDialogWithToggle.PROMPT; + + /** List of all available values possible for synchronization behavior. */ + private static final List SYNC_VALUES = ImmutableList.of(ALWAYS, NEVER, PROMPT); + + /** Synchronization behavior for group 2 way comparison capable. */ + private static final String TWO_WAY_COMPARISON_SYNC_BEHAVIOR = "org.eclipse.emf.compare.rcp.ui.groups.2way.syncbehavior"; //$NON-NLS-1$ + + /** Synchronization behavior for group 3 way comparison capable. */ + private static final String THREE_WAY_COMPARISON_SYNC_BEHAVIOR = "org.eclipse.emf.compare.rcp.ui.groups.3ways.syncbehavior"; //$NON-NLS-1$ + + /** Combo holding syncrhonization behavior preferences. */ + private Combo combo; + + /** Field holding the synchronization behavior chosen by the user. */ + private String synchronizationBehaviorValue; + + /** UI content for two way comparison tab. */ + private GroupsInteractiveContent twoWayComparisonContent; + + /** UI content for three way comparison tab. */ + private GroupsInteractiveContent threeWayComparisonContent; + + /** {@link DifferenceGroupManager}. */ + private DifferenceGroupManager groupManager = new DifferenceGroupManager( + EMFCompareRCPUIPlugin.getDefault().getItemDifferenceGroupProviderRegistry(), + EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + + /** + * Gets the preference key for synchronization behavior. + * + * @param isThreeWay + * True if three way comparison. + * @return The key of the synchronization behavior for this type of comparison. + */ + public static String getGroupSynchronizationPreferenceKey(boolean isThreeWay) { + if (isThreeWay) { + return THREE_WAY_COMPARISON_SYNC_BEHAVIOR; + } else { + return TWO_WAY_COMPARISON_SYNC_BEHAVIOR; + } + } + + public void init(IWorkbench workbench) { + setPreferenceStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + } + + @Override + protected Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + GridLayoutFactory.fillDefaults().applyTo(container); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + createSynchronizationBehaviorContent(container); + + TabFolder tabFolder = new TabFolder(container, SWT.NONE); + tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + fillTwoWayComparisonTab(tabFolder); + fillThreeWayComparisonTab(tabFolder); + return container; + } + + /** + * Fills the tab for two way comparison. + * + * @param tabFolder + * Holding tab folder. + */ + private void fillTwoWayComparisonTab(TabFolder tabFolder) { + Composite tabSkeletonComposite = createTabSkeleton(tabFolder, + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.twoWayComparisonTab.label"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.viewerDescription.label")); //$NON-NLS-1$ + + List> currentGroupRanking = groupManager.getCurrentGroupRanking(false); + + twoWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, + currentGroupRanking.get(0)); + setComboInput(getCurrentSynchronizationBehavior(false)); + } + + /** + * Fills the tab for three way comparison. + * + * @param tabFolder + * Holding tab folder. + */ + private void fillThreeWayComparisonTab(TabFolder tabFolder) { + Composite tabSkeletonComposite = createTabSkeleton(tabFolder, + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.threeWayComparisonTab.label"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.viewerDescription.label")); //$NON-NLS-1$ + + List> currentGroupRanking = groupManager.getCurrentGroupRanking(true); + threeWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, + currentGroupRanking.get(0)); + setComboInput(getCurrentSynchronizationBehavior(true)); + } + + /** + * Creates an interactive content. + *

+ * Interactive content aims at handling all ui that is modified with user interaction. + *

+ * + * @param parent + * Parent Composite. + * @param input + * Input of the viewer. + * @param defaultSelection + * Default element that need to be selected. + * @return A {@link GroupsInteractiveContent} + */ + private GroupsInteractiveContent createInteractiveContent(Composite parent, + List> input, + IItemDescriptor defaultSelection) { + + final GroupsInteractiveContent interactiveUI = new GroupsInteractiveContent(parent); + createViewer(interactiveUI); + interactiveUI.setViewerInput(input); + interactiveUI.select(defaultSelection); + + return interactiveUI; + } + + /** + * Creates skeleton of a tab. + * + * @param tabFolder + * Holding tab folder. + * @param tabLabel + * Label of the tab. + * @param introText + * Text use as description a tab + * @return Main composite of the tab + */ + private Composite createTabSkeleton(TabFolder tabFolder, String tabLabel, String introText) { + TabItem tbtmMain = new TabItem(tabFolder, SWT.NONE); + tbtmMain.setText(tabLabel); + Composite tabComposite = new Composite(tabFolder, SWT.NONE); + tbtmMain.setControl(tabComposite); + tabComposite.setLayout(new GridLayout(1, true)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + tabComposite.setLayoutData(layoutData); + return tabComposite; + } + + /** + * Creates the list viewer holding items. + * + * @param interactiveUI + * {@link GroupsInteractiveContent} in which the viewer need to be set up. + */ + private void createViewer(final GroupsInteractiveContent interactiveUI) { + int style = SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE; + ListViewer descriptorViewer = new ListViewer(interactiveUI.getViewerComposite(), style); + interactiveUI.setViewer(descriptorViewer); + descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); + descriptorViewer.setLabelProvider(new ItemDescriptorLabelProvider()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + descriptorViewer.getControl().setLayoutData(gd); + } + + /** + * Content for synchronization behavior preferences. + * + * @param parent + * Main composite. + */ + private void createSynchronizationBehaviorContent(Composite parent) { + Composite synchronizationComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(synchronizationComposite); + Label label = new Label(synchronizationComposite, SWT.WRAP); + label.setText(EMFCompareRCPUIMessages.getString("GroupsInteractiveContent.SYNC_BEHAVIOR_LABEL")); //$NON-NLS-1$ + label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + combo = new Combo(synchronizationComposite, SWT.DROP_DOWN | SWT.READ_ONLY); + for (String comboLabel : SYNC_VALUES) { + combo.add(comboLabel); + } + combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true)); + combo.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (combo.equals(e.getSource())) { + synchronizationBehaviorValue = SYNC_VALUES.get(combo.getSelectionIndex()); + } + } + + }); + } + + /** + * Sets the combo to the given synchronization behavior. + * + * @param behavior + * Input. + */ + public void setComboInput(String behavior) { + int index = SYNC_VALUES.indexOf(behavior); + if (index != -1) { + combo.select(index); + synchronizationBehaviorValue = behavior; + } + } + + @Override + public boolean performOk() { + groupManager.setCurrentGroupRanking(twoWayComparisonContent.getOrderedItems(), false); + setCurrentSynchronizationBehavior(synchronizationBehaviorValue, false); + + groupManager.setCurrentGroupRanking(threeWayComparisonContent.getOrderedItems(), true); + setCurrentSynchronizationBehavior(synchronizationBehaviorValue, true); + return super.performOk(); + } + + @Override + protected void performDefaults() { + resetGroupPreference(false, twoWayComparisonContent); + resetGroupPreference(true, threeWayComparisonContent); + super.performDefaults(); + } + + /** + * Resets preferences for group. + *

+ * Resets group ranking to default. + *

+ *

+ * Resets synchronization behavior to its default value. + *

+ * + * @param isThreeWay + * Type of comparison. + * @param interactiveContent + * {@link GroupsInteractiveContent} + */ + private void resetGroupPreference(boolean isThreeWay, GroupsInteractiveContent interactiveContent) { + interactiveContent.setViewerInput(groupManager.getDefaultRankingConfiguration(isThreeWay)); + setComboInput(SYNC_DEFAULT_VALUE); + } + + /** + * Sets the current synchronization behavior value. + * + * @param newBehavior + *

+ * Should be one of the following value. + *

+ *
    + *
  • {@link MessageDialogWithToggle#PROMPT}
  • + *
  • {@link MessageDialogWithToggle#ALWAYS}
  • + *
  • {@link MessageDialogWithToggle#NEVER}
  • + *
+ * @param isThreeWay + * True if three way comparison. + */ + public void setCurrentSynchronizationBehavior(String newBehavior, boolean isThreeWay) { + Preconditions.checkArgument(SYNC_VALUES.contains(newBehavior)); + if (!SYNC_DEFAULT_VALUE.equals(newBehavior)) { + getPreferenceStore().putValue(getGroupSynchronizationPreferenceKey(isThreeWay), newBehavior); + } else { + getPreferenceStore().setToDefault(getGroupSynchronizationPreferenceKey(isThreeWay)); + } + // Trace preferences values + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder builder = new StringBuilder(); + // Print each preferences + builder.append("Preference ").append(getGroupSynchronizationPreferenceKey(isThreeWay)) //$NON-NLS-1$ + .append(":\n"); //$NON-NLS-1$ + String preferenceValue = getPreferenceStore() + .getString(getGroupSynchronizationPreferenceKey(isThreeWay)); + builder.append(preferenceValue); + EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); + } + } + + /** + * Gets the state of the the group synchronization behavior. + * + * @param isThreeWay + * True if three way comparison. + * @return Returns one of the following value. + *
    + *
  • {@link MessageDialogWithToggle#PROMPT}
  • + *
  • {@link MessageDialogWithToggle#ALWAYS}
  • + *
  • {@link MessageDialogWithToggle#NEVER}
  • + *
+ */ + public String getCurrentSynchronizationBehavior(boolean isThreeWay) { + String prefValue = getPreferenceStore().getString(getGroupSynchronizationPreferenceKey(isThreeWay)); + if (SYNC_VALUES.contains(prefValue)) { + return prefValue; + } else { + return SYNC_DEFAULT_VALUE; + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/LoggingPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/LoggingPreferencePage.java new file mode 100644 index 000000000..853edc375 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/LoggingPreferencePage.java @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2015, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + * Mathias Schaefer - preferences refactoring + * Simon Delisle - Change verification for integer fields + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_BACKUP_COUNT_KEY; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_BACKUP_DEFAULT; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILENAME_KEY; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILE_DEFAULT; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILE_MAX_SIZE_KEY; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILE_SIZE_DEFAULT; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_LEVEL_DEFAULT; +import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_LEVEL_KEY; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.service.prefs.BackingStoreException; + +/** + * Preference page used to configure logging in EMFCompare. + * + * @author Laurent Delaigue + */ +public class LoggingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + private Combo levelCombo; + + private Text fileField; + + private Text maxSizeField; + + private Text maxBackupField; + + private final String[] LOG_LEVELS = new String[] {"OFF", "ERROR", "INFO", "DEBUG" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + + /** + * Constructor. + */ + public LoggingPreferencePage() { + super(); + } + + /** + * Constructor. + * + * @param title + * . + * @param image + * . + */ + public LoggingPreferencePage(String title, ImageDescriptor image) { + super(title, image); + } + + /** + * Constructor. + * + * @param title + * . + */ + public LoggingPreferencePage(String title) { + super(title); + } + + /** + * {@inheritDoc} + */ + public void init(IWorkbench workbench) { + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, + EMFCompareRCPPlugin.PLUGIN_ID); + store.setSearchContexts(new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + setPreferenceStore(store); + } + + @Override + protected Control createContents(Composite parent) { + Composite loggingComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).applyTo(loggingComposite); + + new Label(loggingComposite, SWT.LEAD) + .setText(EMFCompareRCPUIMessages.getString("LoggingPreferencePage.log.level")); //$NON-NLS-1$ + levelCombo = new Combo(loggingComposite, SWT.DROP_DOWN); + levelCombo.setItems(LOG_LEVELS); + levelCombo.setLayoutData(getDefaultFieldGridData(100)); + + Label fileLabel = new Label(loggingComposite, SWT.LEAD); + fileLabel.setText(EMFCompareRCPUIMessages.getString("LoggingPreferencePage.log.file")); //$NON-NLS-1$ + fileField = new Text(loggingComposite, SWT.BORDER | SWT.SINGLE); + fileField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + Button fileButton = new Button(loggingComposite, SWT.PUSH); + fileButton.setText(EMFCompareRCPUIMessages.getString("LoggingPreferencePage.filebutton.label")); //$NON-NLS-1$ + fileButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dlg = new FileDialog(getShell(), SWT.SAVE); + File file = new File(fileField.getText()); + dlg.setFileName(file.getName()); + dlg.setFilterPath(file.getParent()); + String fileName = dlg.open(); + if (fileName != null) { + fileField.setText(fileName); + } + } + }); + + Label maxSizeLabel = new Label(loggingComposite, SWT.LEAD); + maxSizeLabel.setText(EMFCompareRCPUIMessages.getString("LoggingPreferencePage.log.file.size")); //$NON-NLS-1$ + maxSizeField = new Text(loggingComposite, SWT.BORDER | SWT.SINGLE); + maxSizeField.setLayoutData(getDefaultFieldGridData(80)); + maxSizeField.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + verifyIntegerFields(); + } + }); + + Label maxBackupLabel = new Label(loggingComposite, SWT.LEAD); + maxBackupLabel.setText(EMFCompareRCPUIMessages.getString("LoggingPreferencePage.log.backup.count")); //$NON-NLS-1$ + maxBackupField = new Text(loggingComposite, SWT.BORDER | SWT.SINGLE); + maxBackupField.setLayoutData(getDefaultFieldGridData(80)); + maxBackupField.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + verifyIntegerFields(); + } + }); + + refreshWidgets(); + + return loggingComposite; + } + + protected GridData getDefaultFieldGridData(int width) { + GridData gd = new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1); + gd.widthHint = width; + return gd; + } + + protected void savePreferences() throws BackingStoreException, IOException { + getPreferenceStore().setValue(LOG_FILENAME_KEY, fileField.getText()); + String item = levelCombo.getItem(levelCombo.getSelectionIndex()); + getPreferenceStore().setValue(LOG_LEVEL_KEY, item); + getPreferenceStore().setValue(LOG_BACKUP_COUNT_KEY, maxBackupField.getText()); + getPreferenceStore().setValue(LOG_FILE_MAX_SIZE_KEY, maxSizeField.getText()); + } + + protected void resetPreferences() { + getPreferenceStore().setToDefault(LOG_FILENAME_KEY); + getPreferenceStore().setToDefault(LOG_LEVEL_KEY); + getPreferenceStore().setToDefault(LOG_BACKUP_COUNT_KEY); + getPreferenceStore().setToDefault(LOG_FILE_MAX_SIZE_KEY); + } + + protected void refreshWidgets() { + IPreferencesService prefsService = Platform.getPreferencesService(); + String fileName = prefsService.getString(EMFCompareRCPPlugin.PLUGIN_ID, LOG_FILENAME_KEY, + LOG_FILE_DEFAULT, null); + String level = prefsService.getString(EMFCompareRCPPlugin.PLUGIN_ID, LOG_LEVEL_KEY, LOG_LEVEL_DEFAULT, + null); + int maxBackupCount = prefsService.getInt(EMFCompareRCPPlugin.PLUGIN_ID, LOG_BACKUP_COUNT_KEY, + LOG_BACKUP_DEFAULT, null); + int maxSizeInMB = prefsService.getInt(EMFCompareRCPPlugin.PLUGIN_ID, LOG_FILE_MAX_SIZE_KEY, + LOG_FILE_SIZE_DEFAULT, null); + levelCombo.select(Arrays.asList(LOG_LEVELS).indexOf(level)); + levelCombo.pack(); + fileField.setText(fileName); + maxBackupField.setText(Integer.toString(maxBackupCount)); + maxSizeField.setText(Integer.toString(maxSizeInMB)); + } + + @Override + public boolean performOk() { + try { + savePreferences(); + refreshWidgets(); + return super.performOk(); + } catch (IOException | BackingStoreException e) { + return false; + } + } + + @Override + protected void performDefaults() { + resetPreferences(); + refreshWidgets(); + super.performDefaults(); + } + + /** + * Verify if max size and max file fields are valid. It checks if the fields are integer and not empty. + */ + private void verifyIntegerFields() { + try { + Integer.parseInt(maxSizeField.getText()); + Integer.parseInt(maxBackupField.getText()); + setPreferencePageError(true, null); + } catch (Exception e) { + setPreferencePageError(false, + EMFCompareRCPUIMessages.getString("LoggingPreferencePage.error.message")); //$NON-NLS-1$ + } + } + + /** + * Set preference page error message and if this page is valid. + * + * @param isValid + * True if you can apply these preference + * @param errorMessage + * Error message to display or null to remove the message + */ + private void setPreferencePageError(boolean isValid, String errorMessage) { + setValid(isValid); + setErrorMessage(errorMessage); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java new file mode 100644 index 000000000..2a74ea95f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * 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.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +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.impl.InteractiveUIContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent.InteractiveUIBuilder; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +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 Arthur Daussy + */ +public class PostProcessorPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** Data holder. */ + private DataHolder dataHolder = new DataHolder(); + + /** {@link InteractiveUIContent}. */ + private InteractiveUIContent interactiveUI; + + /** + * Constructor. + */ + public PostProcessorPreferencePage() { + super(); + } + + /** + * Constructor. + * + * @param title + * . + * @param image + * . + */ + public PostProcessorPreferencePage(String title, ImageDescriptor image) { + super(title, image); + } + + /** + * Constructor. + * + * @param title + * . + */ + public PostProcessorPreferencePage(String title) { + super(title); + } + + /** + * {@inheritDoc} + */ + public void init(IWorkbench workbench) { + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, + EMFCompareRCPPlugin.PLUGIN_ID); + store.setSearchContexts(new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + setPreferenceStore(store); + } + + @Override + protected Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().equalWidth(true).applyTo(container); + // container.setLayout(new GridLayout(1, true)); + Label introductionText = new Label(container, SWT.WRAP); + introductionText.setText( + EMFCompareRCPUIMessages.getString("PostProcessorPreferencePage.preferencePage.description")); //$NON-NLS-1$ + + IItemRegistry postProcessorRegistryDescriptor = EMFCompareRCPPlugin + .getDefault().getPostProcessorDescriptorRegistry(); + Set> activesPostProcessor = ItemUtil.getActiveItems( + postProcessorRegistryDescriptor, EMFCompareRCPPlugin.PLUGIN_ID, + EMFComparePreferences.DISABLED_POST_PROCESSOR); + InteractiveUIBuilder postProcessorUIBuilder = new InteractiveUIBuilder( + container, postProcessorRegistryDescriptor); + Set> 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> postProcessorDescriptors = Sets.newLinkedHashSet( + EMFCompareRCPPlugin.getDefault().getPostProcessorDescriptorRegistry().getItemDescriptors()); + SetView> 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 newLine = "\n"; //$NON-NLS-1$ + traceMessage.append(EMFComparePreferences.DISABLED_POST_PROCESSOR).append(prefDelimiter) + .append(getPreferenceStore().getString(EMFComparePreferences.DISABLED_POST_PROCESSOR)) + .append(newLine); + EMFCompareRCPPlugin.getDefault().log(IStatus.INFO, traceMessage.toString()); + } + + return super.performOk(); + } + + @Override + protected void performDefaults() { + Set> 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. + */ + private void setEnginePreferences(String preferenceKey, + Set> currentSelectedEngines) { + if (currentSelectedEngines != null && currentSelectedEngines.size() > 0) { + Iterable identifiers = Iterables.transform(currentSelectedEngines, + new Function, String>() { + public String apply(IItemDescriptor desc) { + return desc.getID(); + } + }); + String descriptorsKey = Joiner.on(ItemUtil.PREFERENCE_DELIMITER).join(identifiers); + getPreferenceStore().setValue(preferenceKey, descriptorsKey); + } else { + getPreferenceStore().setToDefault(preferenceKey); + } + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java new file mode 100644 index 000000000..f9a23ae1c --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java @@ -0,0 +1,336 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences.impl; + +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; + +/** + * Interactive content used for {@link IDifferenceGroupProvider} preferences. + * + * @author Arthur Daussy + */ +public class GroupsInteractiveContent { + + /** Height hint for the description label. */ + private static final int DESCRIPTION_LABEL_HEIGHT_HINT = 40; + + /** Width hint for configuration composite. */ + private static final int DESCRIPTION_LABEL_WIDTH_HINT = 400; + + /** Down icon picture. */ + private static final String ENABLE_DOWN_IMG = "icons/full/pref16/down.gif"; //$NON-NLS-1$ + + /** Up icon picture. */ + private static final String ENABLE_UP_IMG = "icons/full/pref16/up.gif"; //$NON-NLS-1$ + + /** Label that will display the viewer's description. */ + private final Label descriptionText; + + /** List of descriptors. */ + private ArrayList> descriptors; + + /** Button to decrease the rank of a item. */ + private Button downButton; + + /** Button to increase the rank of an item. */ + private Button upButton; + + /** Viewer of {@link IItemDescriptor}. */ + private ListViewer viewer; + + /** Composite holding the viewer. */ + private final Composite viewerCompsite; + + /** + * Constructor. + * + * @param parent + * Main composite holding this group interactive content. + */ + public GroupsInteractiveContent(Composite parent) { + super(); + Composite containerComposite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(containerComposite); + containerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + Composite interactiveComposite = new Composite(containerComposite, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(2).applyTo(interactiveComposite); + interactiveComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + Label introductionText = new Label(interactiveComposite, SWT.WRAP); + introductionText + .setText(EMFCompareRCPUIMessages.getString("GroupsPreferencePage.viewerDescription.label")); //$NON-NLS-1$ + GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(introductionText); + // Engine chooser composite + this.viewerCompsite = new Composite(interactiveComposite, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(viewerCompsite); + viewerCompsite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + // Descriptor engine Label + createButtonComposite(interactiveComposite); + this.descriptionText = createDescriptionComposite(interactiveComposite); + } + + /** + * Creates the composite for up and down button. + * + * @param parent + * {@link Composite} + */ + private void createButtonComposite(Composite parent) { + Composite buttonComposite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1); + buttonComposite.setLayoutData(layoutData); + buttonComposite.setLayout(new RowLayout(SWT.VERTICAL)); + upButton = new Button(buttonComposite, SWT.NONE); + upButton.setImage(EMFCompareRCPUIPlugin.getImage(ENABLE_UP_IMG)); + upButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (upButton.equals(e.getSource())) { + IItemDescriptor selection = getCurrentSelection(); + int index = descriptors.indexOf(selection); + descriptors.remove(selection); + int newIndex = index - 1; + if (newIndex <= descriptors.size()) { + descriptors.add(newIndex, selection); + setViewerInput(descriptors); + select(selection); + } + } + } + }); + downButton = new Button(buttonComposite, SWT.NONE); + downButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (downButton.equals(e.getSource())) { + IItemDescriptor selection = getCurrentSelection(); + int index = descriptors.indexOf(selection); + descriptors.remove(selection); + int newIndex = index + 1; + if (newIndex <= descriptors.size()) { + descriptors.add(newIndex, selection); + setViewerInput(descriptors); + select(selection); + } + } + } + }); + + downButton.setImage(EMFCompareRCPUIPlugin.getImage(ENABLE_DOWN_IMG)); + + } + + /** + * Composite for description. This composite holds the text widget that will update with the current + * selection + * + * @param composite + * Parent Composite. + * @return Label holding the description. + */ + private Label createDescriptionComposite(Composite composite) { + Group descriptionComposite = new Group(composite, SWT.NONE); + descriptionComposite.setText( + EMFCompareRCPUIMessages.getString("InteractiveUIContent.descriptionComposite.label")); //$NON-NLS-1$ + GridLayoutFactory.swtDefaults().applyTo(descriptionComposite); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + + Label engineDescriptionLabel = new Label(descriptionComposite, SWT.WRAP); + GridDataFactory.fillDefaults().grab(true, false) + .hint(DESCRIPTION_LABEL_WIDTH_HINT, DESCRIPTION_LABEL_HEIGHT_HINT) + .applyTo(engineDescriptionLabel); + return engineDescriptionLabel; + } + + /** + * Gets the current selected descriptor. + * + * @return current selected descriptor. + */ + @SuppressWarnings("unchecked") + private IItemDescriptor getCurrentSelection() { + final ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + final IStructuredSelection structSelection = (IStructuredSelection)selection; + final Object first = structSelection.getFirstElement(); + if (first instanceof IItemDescriptor) { + return (IItemDescriptor)first; + } + } + return null; + } + + /** + * Gets {@link IItemDescriptor} of {IDifferenceGroupProvider.@link Descriptor} ordered by user. + * + * @return The ordered list of {@link IItemDescriptor}. + */ + public List> getOrderedItems() { + return descriptors; + } + + /** + * The composite holding the viewer. + * + * @return Compsite + */ + public Composite getViewerComposite() { + return viewerCompsite; + } + + /** + * Returns true if o is the first object of descriptors, false otherwise. + * + * @param o + * Object to test + * @return True if is first. + */ + private boolean isFirst(Object o) { + if (descriptors != null && !descriptors.isEmpty()) { + return descriptors.get(0).equals(o); + } + return false; + } + + /** + * Returns true if o is the last object of descriptor, false otherwise. + * + * @param o + * Object to test + * @return True if is last. + */ + private boolean isLast(Object o) { + if (descriptors != null && !descriptors.isEmpty()) { + return descriptors.get(descriptors.size() - 1).equals(o); + } + return false; + } + + /** + * Handles a selection in the viewer. Updates related components. + * + * @param descriptor + * The descriptor to select. + */ + public void select(IItemDescriptor descriptor) { + // Update viewer + viewer.setSelection(new StructuredSelection(descriptor), true); + updateLinkedElements(descriptor); + } + + /** + * Sets the input for interactive content. + * + * @param input + * Input of the viewsr. + */ + public void setViewerInput(List> input) { + if (viewer != null) { + this.descriptors = Lists.newArrayList(input); + viewer.setInput(descriptors); + } else { + EMFCompareRCPUIPlugin.getDefault().log(IStatus.ERROR, + "Please initialize the viewer before setting input"); //$NON-NLS-1$ + } + } + + /** + * Set the viewer. + * + * @param inputViewer + * A {@link ListViewer} of {@link IItemDescriptor} + */ + public void setViewer(ListViewer inputViewer) { + this.viewer = inputViewer; + viewer.addSelectionChangedListener(new DescriptionListener()); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + IItemDescriptor selection = getCurrentSelection(); + if (selection == null) { + upButton.setEnabled(false); + downButton.setEnabled(false); + } else { + upButton.setEnabled(!isFirst(selection)); + downButton.setEnabled(!isLast(selection)); + } + } + + }); + } + + /** + * Updates linked elements. + * + * @param descriptor + * Newly selected descriptor. + */ + private void updateLinkedElements(IItemDescriptor descriptor) { + // Update description + descriptionText.setText(descriptor.getDescription()); + } + + /** + * Listener to update description text. + * + * @author Arthur Daussy + */ + private final class DescriptionListener implements ISelectionChangedListener { + + /** + * {@inheritDoc} + */ + 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/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java new file mode 100644 index 000000000..004fec82e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java @@ -0,0 +1,728 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Simon Delisle - bug 495753 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences.impl; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; + +import java.util.Collection; +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.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.core.runtime.preferences.InstanceScope; +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.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.DataHolder; +import org.eclipse.jface.databinding.viewers.IViewerObservableSet; +import org.eclipse.jface.databinding.viewers.ViewersObservables; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.preference.IPreferenceStore; +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.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.ui.preferences.ScopedPreferenceStore; +import org.osgi.service.prefs.Preferences; + +/** + * A User interface that holds a viewer and satellites elements. + *

+ * 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. + *

+ *

+ * This viewer can have a satellite text field holding the description of the current selection. This field + * display the description for the current element. + *

+ *

+ * This class allows a user to select and check elements. + *

+ *

+ * It can also synchronize the state of checked element into a {@link DataHolder} + *

+ * + * @author Arthur Daussy + */ +public final class InteractiveUIContent { + + /** Width hint for configuration composite. */ + private static final int WIDTH_HINT_CONFIG_COMPOSITE = 400; + + /** Height hint for description composite. */ + private static final int DESCRIPTION_COMPOSITE_HEIGHT_HINT = 50; + + /** Width hint for description composite. */ + private static final int DESCRIPTION_COMPOSITE_WIDTH_HINT = 400; + + /** Text that will be updated with the description of the viewer. */ + private final Label 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 configurators = new HashMap(); + + /** + * Constructor. + * + * @param parent + * Composite parent holding this interactive content. + * @param hasDescription + * Set to true if this has a description label that react to viewer selection. + * @param hasConfiguration + * set to true if this has a configuration composite that react to viewer selection. + */ + 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; + } + GridLayoutFactory.fillDefaults().numColumns(numberOfColumns).applyTo(contentComposite); + contentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + // Engine chooser composite + this.viewerCompsite = new Composite(contentComposite, SWT.NONE); + GridLayoutFactory.fillDefaults().applyTo(viewerCompsite); + 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.defaultConfiguration.label")); //$NON-NLS-1$ + } else { + this.configurationComposite = null; + this.defaultComposite = null; + } + if (hasDescription) { + // Descriptor engine Text + this.descriptionText = createDescriptionComposite(parent); + } else { + this.descriptionText = null; + } + } + + /** + * Adds a configuration to this Interactive content. + * + * @param id + * Id of the item to configure + * @param configuratorfactory + * Factory for the configuration + * @param store + * Preference store that will hold this {@link IConfigurationUIFactory} value. + */ + public void addConfigurator(String id, IConfigurationUIFactory configuratorfactory, + IPreferenceStore store) { + AbstractConfigurationUI configurator = configuratorfactory.createUI(configurationComposite, SWT.NONE, + store); + configurators.put(id, configurator); + } + + /** + * Checks one element in the viewer. + * + * @param descriptor + * element to check. + */ + public void checkElement(IItemDescriptor descriptor) { + viewer.setCheckedElements(new Object[] {descriptor }); + } + + /** + * Checks multiple element in the viewer. (Only use if multiple selection is allowed) + * + * @param descriptors + * elements to check. + */ + public void checkElements(Collection> descriptors) { + viewer.setCheckedElements(descriptors.toArray()); + } + + /** + * Checks multiple element in the viewer. (Only use if multiple selection is allowed) + * + * @param descriptors + * elements to check. + */ + public void checkElements(IItemDescriptor[] descriptors) { + viewer.setCheckedElements(descriptors); + } + + /** + * Creates the composite that will hold all configurations for a tab. + * + * @param composite + * Main composite + * @return Group that will hold configurations in a stack layout. + */ + private Group createConfigComposite(Composite composite) { + Group confComposite = new Group(composite, SWT.NONE); + confComposite.setText( + EMFCompareRCPUIMessages.getString("InteractiveUIContent.configurationComposite.label")); //$NON-NLS-1$ + StackLayout layout = new StackLayout(); + layout.marginHeight = 10; + layout.marginWidth = 5; + confComposite.setLayout(layout); + GridData layoutData = new GridData(SWT.BEGINNING, SWT.FILL, false, true); + layoutData.widthHint = WIDTH_HINT_CONFIG_COMPOSITE; + confComposite.setLayoutData(layoutData); + return confComposite; + } + + /** + * Composite for description. This composite holds the text widget that will be updated with the current + * selection. + * + * @param composite + * Main composite. + * @return Label that will hold viewer selection description. + */ + private Label createDescriptionComposite(Composite composite) { + Group descriptionComposite = new Group(composite, SWT.NONE); + descriptionComposite.setText( + EMFCompareRCPUIMessages.getString("InteractiveUIContent.descriptionComposite.label")); //$NON-NLS-1$ + descriptionComposite.setLayout(new GridLayout(1, false)); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); + Label engineDescriptionLabel = new Label(descriptionComposite, SWT.WRAP); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1); + layoutData.heightHint = DESCRIPTION_COMPOSITE_HEIGHT_HINT; + layoutData.widthHint = DESCRIPTION_COMPOSITE_WIDTH_HINT; + engineDescriptionLabel.setLayoutData(layoutData); + return engineDescriptionLabel; + } + + /** + * @return A map of all configuration. + */ + public Map getConfigurators() { + return ImmutableMap.copyOf(configurators); + } + + /** + * Gets the viewer. + * + * @return The viewer. + */ + public CheckboxTableViewer getViewer() { + return viewer; + } + + /** + * Returns the composite that will hold the viewer. + * + * @return The composite holding the viewer. + */ + private Composite getViewerComposite() { + return viewerCompsite; + } + + /** + * Handles a selection in the viewer. Update related components. + * + * @param descriptor + * Item to select. + */ + public void select(IItemDescriptor descriptor) { + selectAll(Collections.singleton(descriptor)); + } + + /** + * Handles a selection in the viewer. Update related components. + * + * @param descriptor + * Item to select. + */ + public void selectAll(Collection> descriptors) { + // Update viewer + viewer.setSelection(new StructuredSelection(descriptors), true); + updateLinkedElements(descriptors.iterator().next()); + } + + /** + * Sets the viewer in the interactive content. + * + * @param inputViewer + * 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()); + } + + /** + * Updates the linked element in this interactive content. + * + * @param descriptor + * Item used as input to get information for satellite elements. + */ + private void updateLinkedElements(IItemDescriptor descriptor) { + // Update description + descriptionText.setText(descriptor.getDescription()); + if (configurationComposite != null) { + updateConfigurationComposite(descriptor); + } + } + + /** + * Updates the configuration composite. + * + * @param descriptor + * New 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. + *

+ * With this listener, only one element can be checked at a time + *

+ * + * @author Arthur Daussy + * @param + * Type of item. + */ + private static final class SingleCheckListener implements ICheckStateListener { + /** Data holder. */ + private final DataHolder dataObject; + + /** Viewer. */ + private final CheckboxTableViewer descriptorViewer; + + /** Shell. */ + private final Shell shell; + + /** + * Constructor. + * + * @param dataObject + * Data holder. + * @param descriptorViewer + * Viewer + * @param shell + * Shell. + */ + private SingleCheckListener(DataHolder dataObject, CheckboxTableViewer descriptorViewer, + Shell shell) { + this.dataObject = dataObject; + this.descriptorViewer = descriptorViewer; + this.shell = shell; + } + + /** + * {@inheritDoc} + */ + public void checkStateChanged(CheckStateChangedEvent event) { + Object element = event.getElement(); + if (event.getChecked()) { + if (element instanceof IItemDescriptor) { + @SuppressWarnings("unchecked") + IItemDescriptor descriptor = (IItemDescriptor)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.incorrectSelection.title"), //$NON-NLS-1$ + EMFCompareRCPUIMessages + .getString("InteractiveUIContent.incorrectSelection.message")); //$NON-NLS-1$ + } + } + + } + } + + /** + * Listener in charge of updating the configuration composite. + * + * @author Arthur Daussy + */ + private final class ConfigurationListener implements ISelectionChangedListener { + /** + * {@inheritDoc} + */ + 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 used to update description text. + * + * @author Arthur Daussy + */ + private final class DescriptionListener implements ISelectionChangedListener { + + /** + * {@inheritDoc} + */ + 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); + } + } + + } + } + + /** + * Builder for an Interactive UI. + * + * @author Arthur Daussy + * @param + * type of item in the viewer. + */ + public static class InteractiveUIBuilder { + + /** Holding composite of all the structure. */ + private Composite parent; + + /** Item registry holding input of the viewer. */ + private IItemRegistry registry; + + /** Key of the preference node where the configuration for an item is stored. */ + private String configurationNodeKey; + + /** Configuration UI registry. */ + private Map configurationUIRegistry; + + /** Set of elements to check by default. */ + private Set> defaultCheck; + + /** Element to select by default. */ + private IItemDescriptor defaultSelection; + + /** Object holding data representing the current status of the interactive content. */ + private DataHolder 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. + */ + public InteractiveUIBuilder(Composite parent, IItemRegistry registry) { + super(); + this.parent = parent; + this.registry = registry; + } + + /** + * Sets a dataHolder that will be synchronized with the checked element. + * + * @param newDataHolder + * DataHolder. + * @return {@link InteractiveUIBuilder} + */ + public InteractiveUIBuilder setHoldingData(DataHolder newDataHolder) { + this.dataHolder = newDataHolder; + return this; + } + + /** + * Node key used to get the {@link Preferences} to retrieve {@link IConfigurationUIFactory}. See + * {@link ItemUtil#getConfigurationPreferenceNode(String, String)} (needed if a + * ConfigurationUIRegistry has been provided) + * + * @param key + * . + * @return {@link InteractiveUIBuilder} + */ + public InteractiveUIBuilder setConfigurationNodeKey(String key) { + this.configurationNodeKey = key; + return this; + } + + /** + * Registry of {@link IConfigurationUIFactory} used to fill the configuration composite. + * + * @param configuratorUIRegistry + * . + * @return {@link InteractiveUIBuilder} + */ + public InteractiveUIBuilder setConfiguratorUIRegistry( + Map configuratorUIRegistry) { + this.configurationUIRegistry = configuratorUIRegistry; + return this; + } + + /** + * Sets the default element to check. (A singleton if "this" is set to simple + * {@link InteractiveUIBuilder#setSimple(boolean)} + * + * @param newDefaultCheck + * . + * @return InteractiveUIBuilder + */ + public InteractiveUIBuilder setDefaultCheck(Set> newDefaultCheck) { + this.defaultCheck = newDefaultCheck; + return this; + } + + /** + * Set the default element to select. + * + * @param newDefaultSelection + * . + * @return InteractiveUIBuilder + */ + public InteractiveUIBuilder setDefaultSelection(IItemDescriptor newDefaultSelection) { + this.defaultSelection = newDefaultSelection; + return this; + } + + /** + * Set to true if "this" needs to create a description field. + * + * @param newHasDescription + * . + * @return {@link InteractiveUIBuilder} + */ + public InteractiveUIBuilder setHasDescription(boolean newHasDescription) { + this.hasDescription = newHasDescription; + return this; + } + + /** + * Set to true if the viewer can only have only one element checked at a time. + * + * @param newIsSimple + * . + * @return {@link InteractiveUIBuilder} + */ + public InteractiveUIBuilder setSimple(boolean newIsSimple) { + this.isSimple = newIsSimple; + return this; + } + + /** + * Build a new {@link InteractiveUI}. + * + * @return InteractiveUIContent + */ + 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; + } + + /** + * Initializes the viewer. + * + * @param interactiveUI + * . + * @return CheckboxTableViewer + */ + 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 ItemDescriptorLabelProvider()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + descriptorViewer.getControl().setLayoutData(gd); + return descriptorViewer; + } + + /** + * Creates the configuration composite. + * + * @param interactiveUI + * . + */ + private void createConfigurationComposite(final InteractiveUIContent interactiveUI) { + // Init configuration elements + for (IItemDescriptor item : registry.getItemDescriptors()) { + String itemId = item.getID(); + IConfigurationUIFactory configuratorFactory = configurationUIRegistry.get(itemId); + if (configuratorFactory != null) { + // Preferences pref = ItemUtil.getConfigurationPreferenceNode(configurationNodeKey, + // itemId); + ScopedPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, + EMFCompareRCPPlugin.PLUGIN_ID); + store.setSearchContexts( + new IScopeContext[] {InstanceScope.INSTANCE, ConfigurationScope.INSTANCE }); + interactiveUI.addConfigurator(itemId, configuratorFactory, store); + } + } + } + + /** + * Initializes and binds interactive content with the data holder value. + * + * @param interactiveUI + * . + * @param descriptorViewer + * . + */ + private void bindAndInit(final InteractiveUIContent interactiveUI, + CheckboxTableViewer descriptorViewer) { + if (defaultSelection != null) { + interactiveUI.select(defaultSelection); + } + if (isSimple) { + if (defaultCheck != null) { + IItemDescriptor defaultCheckedElement = defaultCheck.iterator().next(); + interactiveUI.checkElement(defaultCheckedElement); + if (dataHolder != null) { + dataHolder.setData(Collections.singleton(defaultCheckedElement)); + } + } + descriptorViewer.addCheckStateListener(new SingleCheckListener(dataHolder, + descriptorViewer, Display.getDefault().getActiveShell())); + } else { + if (dataHolder != null) { + if (defaultCheck != null) { + dataHolder.setData(defaultCheck); + } + // Bind data + bindMultipleData(interactiveUI.getViewer(), dataHolder); + } + } + } + + /** + * Sets the viewer input. + * + * @param descriptorViewer + * . + */ + private void setViewerInput(CheckboxTableViewer descriptorViewer) { + List> itemDescriptors = registry.getItemDescriptors(); + Collections.sort(itemDescriptors); + descriptorViewer.setInput(itemDescriptors); + } + + /** + * Binds UI to data object. + * + * @param descriptorViewer + * . + * @param dataObject + * The data holder. + */ + private void bindMultipleData(CheckboxTableViewer descriptorViewer, final DataHolder 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, DataHolder.DATA_FIELD_NAME) + .observe(dataObject); + + ctx.bindSet(target, model); + } + + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java new file mode 100644 index 000000000..84d5c57cd --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.impl; + +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.jface.viewers.LabelProvider; + +/** + * Label provider for {@link IItemDescriptor}. + * + * @author Arthur Daussy + */ +public class ItemDescriptorLabelProvider extends LabelProvider { + /** + * {@inheritDoc} + */ + @Override + public String getText(Object element) { + if (element instanceof IItemDescriptor) { + IItemDescriptor desc = (IItemDescriptor)element; + return desc.getLabel(); + } + return super.getText(element); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterAction.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterAction.java new file mode 100644 index 000000000..c1a4afe5e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterAction.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.actions; + +import com.google.common.collect.Sets; + +import java.util.Set; + +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.preferences.FiltersPreferencePage; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions.ui.SynchronizerDialog; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +/** + * These will be the actual actions displayed in the filter menu. Their sole purpose is to provide a Predicate + * to the structure viewer's filter. + *

+ * Do note that each distinct {@link FilterAction} in the {@link FilterActionMenu filter menu} is considered + * as an "exclude" filter, and that they are OR'ed together (thus, any element must not meet the + * selected filters' criteria in order to be displayed). + *

+ * + * @author Laurent Goubet + * @since 4.0 + */ +public class FilterAction extends Action { + + /** The filter associated with this action. */ + private final IDifferenceFilter filter; + + /** The Filter that will be modified by the action. */ + private final StructureMergeViewerFilter structureMergeViewerFilter; + + /** Preferences holding the value of the synchronization behavior of filters. */ + private final IPreferenceStore preferences; + + /** {@link DifferenceFilterManager}. */ + private final DifferenceFilterManager filterManager; + + /** + * The "default" constructor for this action. + * + * @param text + * Will be used as the action's tooltip. + * @param structureMergeViewerFilter + * The viewer filter that this action will need to update. + * @param filter + * The filter associated with this action. + */ + public FilterAction(String text, StructureMergeViewerFilter structureMergeViewerFilter, + IDifferenceFilter filter) { + super(text, IAction.AS_CHECK_BOX); + this.structureMergeViewerFilter = structureMergeViewerFilter; + this.filter = filter; + this.preferences = EMFCompareRCPUIPlugin.getDefault().getPreferenceStore(); + this.filterManager = EMFCompareRCPUIPlugin.getDefault().getDifferenceFilterManager(); + } + + /** + * {@inheritDoc} + */ + @Override + public void runWithEvent(Event event) { + if (isChecked()) { + structureMergeViewerFilter.addFilter(filter); + } else { + structureMergeViewerFilter.removeFilter(filter); + } + handleSynchronization(event); + } + + /** + * Handle synchronization with {@link DifferenceFilterManager}. + * + * @param event + * Event. + */ + private void handleSynchronization(Event event) { + String sync = preferences.getString(FiltersPreferencePage.SYNCHRONIZATION_BEHAVIOR); + if ("".equals(sync)) { //$NON-NLS-1$ + sync = MessageDialogWithToggle.PROMPT; + } + final Shell shell = event.display.getActiveShell(); + if (MessageDialogWithToggle.PROMPT.equals(sync) && shell != null) { + shell.getDisplay().asyncExec(new SynchronizationBehaviorRunnable(shell)); + } else if (MessageDialogWithToggle.ALWAYS.equals(sync)) { + synchonizeFilters(); + } + } + + /** + * Synchronizes UI filter selection with the preferences. + */ + private void synchonizeFilters() { + Set byDefaultFilters = Sets + .newLinkedHashSet(filterManager.getCurrentByDefaultFilters()); + // Add newly activated filters + for (IDifferenceFilter activeFilter : structureMergeViewerFilter.getSelectedDifferenceFilters()) { + byDefaultFilters.add(activeFilter); + } + // Remove deactivated filters + for (IDifferenceFilter toDeactivateFilter : structureMergeViewerFilter + .getUnSelectedDifferenceFilters()) { + byDefaultFilters.remove(toDeactivateFilter); + } + filterManager.setCurrentByDefaultFilters(byDefaultFilters); + + } + + /** + * Runnable in charge of synchronizing selection in UI with the {@link DifferenceFilterManager}. + * + * @author Arthur Daussy + */ + private final class SynchronizationBehaviorRunnable implements Runnable { + /** Shell of this runnable. */ + private final Shell shell; + + /** + * Constructor. + * + * @param shell + * Shell for this runnable. + */ + private SynchronizationBehaviorRunnable(Shell shell) { + this.shell = shell; + } + + /** + * {@inheritDoc} + */ + public void run() { + MessageDialogWithToggle dialog = new SynchronizerDialog(shell, + EMFCompareRCPUIMessages.getString("FilterAction.synchronization.dialog.title"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("FilterAction.synchronization.dialog.message"), //$NON-NLS-1$ + FiltersPreferencePage.PAGE_ID); + + dialog.setPrefKey(FiltersPreferencePage.SYNCHRONIZATION_BEHAVIOR); + dialog.setPrefStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + if (dialog.open() == IDialogConstants.YES_ID) { + synchonizeFilters(); + } + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterActionMenu.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterActionMenu.java new file mode 100644 index 000000000..a69ee576d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/FilterActionMenu.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.structuremergeviewer.actions; + +import java.util.Collection; + +import org.eclipse.emf.compare.Comparison; +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.structuremergeviewer.filters.StructureMergeViewerFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * This will be displayed atop the structure viewer as the "filters" menu. + * + * @author Laurent Goubet + * @since 4.0 + */ +public class FilterActionMenu extends Action implements IMenuCreator { + /** The viewer filter that will be modified by this menu's actions. */ + private final StructureMergeViewerFilter structureMergeViewerFilter; + + /** Menu Manager that will contain our menu. */ + private final MenuManager menuManager; + + /** The registry that will be used to retrieve available filters. */ + private final Registry registry; + + /** + * Constructs our filtering menu. + * + * @param structureMergeViewerFilter + * The viewer filter for which we'll create actions. + * @param registry + * The registry that contains the filters. + */ + public FilterActionMenu(StructureMergeViewerFilter structureMergeViewerFilter, + IDifferenceFilter.Registry registry) { + super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$ + this.structureMergeViewerFilter = structureMergeViewerFilter; + this.registry = registry; + this.menuManager = new MenuManager(); + setMenuCreator(this); + setToolTipText(EMFCompareRCPUIMessages.getString("FilterActionMenu.tooltip")); //$NON-NLS-1$ + setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareRCPUIPlugin.PLUGIN_ID, + "icons/full/toolb16/filter.gif")); //$NON-NLS-1$ + } + + /** + * Create all of our filtering actions into the given menu. + * + * @param newScope + * The scope on which the filters will be applied. + * @param newComparison + * The comparison on which the filters will be applied. + */ + public void updateMenu(IComparisonScope newScope, Comparison newComparison) { + menuManager.removeAll(); + Collection filters = registry.getFilters(newScope, newComparison); + for (IDifferenceFilter filter : filters) { + if (structureMergeViewerFilter.getActiveDifferenceFilters().contains(filter)) { + FilterAction action = new FilterAction(filter.getLabel(), structureMergeViewerFilter, filter); + boolean selected = structureMergeViewerFilter.getSelectedDifferenceFilters().contains(filter); + action.setChecked(selected); + menuManager.add(action); + } + } + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#dispose() + */ + public void dispose() { + menuManager.dispose(); + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#getMenu(Control) + */ + public Menu getMenu(Control parent) { + return menuManager.createContextMenu(parent); + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#getMenu(Menu) + */ + public Menu getMenu(Menu parent) { + return null; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupAction.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupAction.java new file mode 100644 index 000000000..f0929d7f9 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupAction.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.actions; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +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.preferences.GroupsPreferencePage; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions.ui.SynchronizerDialog; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.StructureMergeViewerGrouper; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +/** + * This action will allow us to group differences by their kind. + * + * @author Laurent Goubet + * @since 4.0 + */ +public class GroupAction extends Action { + /** The viewer grouper that will be affected by this action. */ + private final StructureMergeViewerGrouper structureMergeViewerGrouper; + + /** The actual instance that will provide groups if this action is used. */ + private final IDifferenceGroupProvider provider; + + /** The group descriptor for this action. */ + private final IDifferenceGroupProvider.Descriptor descriptorGroupProvider; + + /** Holds true if the current comparison is a Three way comparison. */ + private final boolean isThreeWay; + + /** {@link DifferenceGroupManager}. */ + private final DifferenceGroupManager groupManager; + + /** Preferences holding synchronization behavior value. */ + private final IPreferenceStore preferences; + + /** + * Instantiates our action given its target grouper. + * + * @param structureMergeViewerGrouper + * @param dgp + * The group provider descriptor. + * @param gp + * The group provider created by the group provider descriptor. + * @param groupManager + * {@link DifferenceGroupManager} + * @param isThreeWay + * Set to true if the current comparison is a Three way comparison. + */ + public GroupAction(StructureMergeViewerGrouper structureMergeViewerGrouper, + IDifferenceGroupProvider.Descriptor dgp, IDifferenceGroupProvider gp, + DifferenceGroupManager groupManager, boolean isThreeWay) { + super(dgp.getLabel(), IAction.AS_RADIO_BUTTON); + this.structureMergeViewerGrouper = structureMergeViewerGrouper; + this.descriptorGroupProvider = dgp; + this.groupManager = groupManager; + this.isThreeWay = isThreeWay; + this.provider = gp; + this.preferences = EMFCompareRCPUIPlugin.getDefault().getPreferenceStore(); + } + + @Override + public boolean isEnabled() { + return provider != null; + } + + public Descriptor getDescriptorGroupProvider() { + return descriptorGroupProvider; + } + + @Override + public void runWithEvent(Event event) { + if (isChecked()) { + handleSynchronization(event); + structureMergeViewerGrouper.setProvider(provider); + } + } + + /** + * Handles the synchronization after a run. + * + * @param event + * Event of the action. + */ + private void handleSynchronization(Event event) { + final Shell shell = event.display.getActiveShell(); + String preferenceValue = preferences + .getString(GroupsPreferencePage.getGroupSynchronizationPreferenceKey(isThreeWay)); + if ("".equals(preferenceValue)) { //$NON-NLS-1$ + preferenceValue = MessageDialogWithToggle.PROMPT; + } + if (MessageDialogWithToggle.PROMPT.equals(preferenceValue)) { + shell.getDisplay().asyncExec(new SynchronizationRunnable(shell)); + } else if (MessageDialogWithToggle.ALWAYS.equals(preferenceValue)) { + setSelectedGroupAsDefault(); + } + } + + /** + * Sets the selected group as default group. + */ + private void setSelectedGroupAsDefault() { + List> currentState = groupManager.getCurrentGroupRanking(isThreeWay); + IItemDescriptor matchingItem = null; + Iterator> itemsIterator = currentState.iterator(); + while (itemsIterator.hasNext() && matchingItem == null) { + IItemDescriptor currentItem = itemsIterator.next(); + if (currentItem.getItem().equals(descriptorGroupProvider)) { + matchingItem = currentItem; + } + } + if (matchingItem != null) { + currentState.remove(matchingItem); + currentState.add(0, matchingItem); + groupManager.setCurrentGroupRanking(currentState, isThreeWay); + } else { + /* + * If not found then the group provider may have been removed from the registry. Just log warning. + */ + EMFCompareRCPUIPlugin.getDefault().log(IStatus.WARNING, + "Enable to set selected difference group provider as default group provider. The selected group provider is not in the registry anymore"); //$NON-NLS-1$ + } + } + + /** + * Runnable responsible for synchronizing the group with the {@link DifferenceGroupManager}. + * + * @author Arthur Daussy + */ + private final class SynchronizationRunnable implements Runnable { + /** Parent {@link Shell}. */ + private final Shell shell; + + /** + * Constructor. + * + * @param shell + * Parent shell. + */ + private SynchronizationRunnable(Shell shell) { + this.shell = shell; + } + + /** + * {@inheritDoc} + */ + public void run() { + MessageDialogWithToggle dialog = new SynchronizerDialog(shell, + EMFCompareRCPUIMessages.getString("GroupAction.synchronization.dialog.title"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("GroupAction.synchronization.dialog.message"), //$NON-NLS-1$ + GroupsPreferencePage.PAGE_ID); + + dialog.setPrefKey(GroupsPreferencePage.getGroupSynchronizationPreferenceKey(isThreeWay)); + dialog.setPrefStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + if (dialog.open() == IDialogConstants.YES_ID) { + setSelectedGroupAsDefault(); + } + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupActionMenu.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupActionMenu.java new file mode 100644 index 000000000..edc26e015 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/GroupActionMenu.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.actions; + +import org.eclipse.emf.compare.Comparison; +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.structuremergeviewer.groups.StructureMergeViewerGrouper; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +/** + * This menu will display actions that will allow the user to group differences together. + * + * @author Laurent Goubet + * @since 4.0 + */ +public class GroupActionMenu extends Action implements IMenuCreator { + /** The viewer grouper that will be affected by this menu's actions. */ + private final StructureMergeViewerGrouper structureMergeViewerGrouper; + + /** Menu Manager that will contain our menu. */ + private final MenuManager menuManager; + + /** The registry that will be used to retrieve the displayed group providers. */ + private final IDifferenceGroupProvider.Descriptor.Registry registry; + + /** + * Constructs our grouping menu. + * + * @param structureMergeViewerGrouper + * The viewer grouper that will be affected by this menu's actions. + * @param registry + * The registry that contains the group provider.. + */ + public GroupActionMenu(StructureMergeViewerGrouper structureMergeViewerGrouper, + IDifferenceGroupProvider.Descriptor.Registry registry) { + super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$ + this.registry = registry; + this.menuManager = new MenuManager(); + this.structureMergeViewerGrouper = structureMergeViewerGrouper; + setToolTipText(EMFCompareRCPUIMessages.getString("GroupActionMenu.tooltip")); //$NON-NLS-1$ + setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareRCPUIPlugin.PLUGIN_ID, + "icons/full/toolb16/group.gif")); //$NON-NLS-1$ + setMenuCreator(this); + } + + /** + * Create the grouping action in the given menu. + * + * @param scope + * The scope on which the groups will be applied. + * @param comparison + * The comparison which differences are to be split into groups. + */ + public void updateMenu(IComparisonScope scope, Comparison comparison) { + menuManager.removeAll(); + DifferenceGroupManager groupManager = new DifferenceGroupManager( + EMFCompareRCPUIPlugin.getDefault().getItemDifferenceGroupProviderRegistry(), + EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); + for (IDifferenceGroupProvider.Descriptor dgp : registry.getGroupProviders(scope, comparison)) { + IDifferenceGroupProvider gp = dgp.createGroupProvider(); + if (gp != null) { + final IAction action; + if (gp.getClass() == structureMergeViewerGrouper.getProvider().getClass()) { + action = new GroupAction(structureMergeViewerGrouper, dgp, + structureMergeViewerGrouper.getProvider(), groupManager, comparison.isThreeWay()); + action.setChecked(true); + } else { + action = new GroupAction(structureMergeViewerGrouper, dgp, gp, groupManager, + comparison.isThreeWay()); + } + menuManager.add(action); + } + } + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#dispose() + */ + public void dispose() { + menuManager.dispose(); + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#getMenu(Control) + */ + public Menu getMenu(Control parent) { + return menuManager.createContextMenu(parent); + } + + /** + * {@inheritDoc} + * + * @see IMenuCreator#getMenu(Menu) + */ + public Menu getMenu(Menu parent) { + return null; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/ui/SynchronizerDialog.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/ui/SynchronizerDialog.java new file mode 100644 index 000000000..03cdb2d0b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/actions/ui/SynchronizerDialog.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright (c) 2014, 2016 Obeo and others. + * 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 + * Stefan Dirix - bug 473985 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions.ui; + +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +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.Link; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.PreferencesUtil; + +/** + * Dialog used to ask user synchronization behavior. + * + * @author Arthur Daussy + */ +public class SynchronizerDialog extends MessageDialogWithToggle { + + /** Indentation of the preference page hyper link. */ + private static final int HYPERLINK_INDENT = 35; + + /** Index of the "No" button. Used to define a default selection. */ + private static final int NO_BUTTON_INDEX = 1; + + /** Labels used for simple preference synchronization. */ + private static String[] defaultButtonLabels = new String[] {IDialogConstants.YES_LABEL, + IDialogConstants.NO_LABEL, }; + + /** Id of the preference page. */ + private final String preferencePageID; + + /** + * Constructor. + * + * @param parentShell + * Parent shell + * @param title + * Title of the dialog + * @param message + * MEssage of the dialog + * @param preferencePageID + * Preference page id if the dialog should have a hyperlink to a preference page or + * null otherwise + */ + public SynchronizerDialog(Shell parentShell, String title, String message, String preferencePageID) { + super(parentShell, title, null, message, MessageDialog.CONFIRM, defaultButtonLabels, NO_BUTTON_INDEX, + EMFCompareRCPUIMessages.getString("SynchronizerDialog.notAskAgain.label"), false); //$NON-NLS-1$ + this.preferencePageID = preferencePageID; + + } + + /** + * {@inheritDoc} + */ + @Override + protected Control createCustomArea(Composite parent) { + // only add hyperlink if workbench is running since the preference dialog depends on it + if (preferencePageID != null && PlatformUI.isWorkbenchRunning()) { + Composite container = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, true); + container.setLayout(layout); + // Create hyperlink to preferences. + Link pageLink = new Link(container, SWT.NONE); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.horizontalIndent = HYPERLINK_INDENT; + pageLink.setLayoutData(layoutData); + pageLink.setText(EMFCompareRCPUIMessages.getString("SynchronizerDialog.hyperlink.message")); //$NON-NLS-1$ + // Open preference page on click + pageLink.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + buttonPressed(IDialogConstants.CANCEL_ID); + PreferencesUtil.createPreferenceDialogOn(getParentShell(), preferencePageID, null, null) + .open(); + } + }); + return container; + } + return super.createCustomArea(parent); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/StructureMergeViewerFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/StructureMergeViewerFilter.java new file mode 100644 index 000000000..b847a3650 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/StructureMergeViewerFilter.java @@ -0,0 +1,304 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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 + * Philip Langer - cache result + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters; + +import static com.google.common.base.Predicates.alwaysFalse; +import static com.google.common.base.Predicates.not; +import static com.google.common.base.Predicates.or; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Sets.newLinkedHashSet; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.eventbus.EventBus; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterChange; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.provider.GroupItemProviderAdapter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.ui.progress.PendingUpdateAdapter; + +/** + * This will be used by the structure viewer to filter out its list of differences according to a number of + * provided predicates. + *

+ * Note that this filter acts as an "OR" predicate between all provided ones, and that filters are + * "exclude" filters. Basically, that means if the user selects two filters, any difference that applies for + * any of these two filters will be hidden from the view, contrarily to "classic" {@link ViewerFilter} + * that act as "AND" predicates for "include" filters, forcing any displayed element to meet the criterion of + * all provided filters. + *

+ * + * @author Laurent Goubet + * @since 4.0 + */ +public class StructureMergeViewerFilter extends ViewerFilter { + + /** A predicate use by default that always returns false. */ + public static final Predicate DEFAULT_PREDICATE = alwaysFalse(); + + /** The set of predicates known by this filter. */ + private final Set> predicates; + + /** The set of selected filters known by this filter. */ + private final Set selectedDifferenceFilters; + + /** The set of unselected filters known by this filter. */ + private final Set unselectedDifferenceFilters; + + /** The set of active filters known by this filter. */ + private final Set activeDifferenceFilters; + + /** The {@link EventBus} associated with this filter. */ + private final EventBus eventBus; + + /** The cached values for {@link #select(Viewer, Object, Object)}. */ + private final Map selectedObjects; + + /** + * The predicate used by this StructureMergeViewerFilter. + */ + private final Predicate viewerPredicate = new Predicate() { + public boolean apply(EObject eObject) { + final boolean ret; + if (aggregatedPredicate.apply(eObject)) { + Collection eContents = eObject.eContents(); + if (!eContents.isEmpty() && eObject instanceof TreeNode) { + EObject data = ((TreeNode)eObject).getData(); + if (data instanceof Match || data instanceof Conflict || data instanceof MatchResource) { + ret = any(eContents, viewerPredicate); + } else { + ret = true; + } + } else { + ret = true; + } + } else { + ret = false; + } + return ret; + } + }; + + /** + * A predicate that aggregates the selected state predicates of selected filters and the unselected state + * predicates of unselected filters. + */ + private Predicate aggregatedPredicate; + + /** + * Constructs the difference filter. + * + * @param eventBus + * The {@link EventBus} which will be associated with this filter. + */ + public StructureMergeViewerFilter(EventBus eventBus) { + this.eventBus = eventBus; + this.predicates = newLinkedHashSet(); + this.selectedDifferenceFilters = newLinkedHashSet(); + this.unselectedDifferenceFilters = newLinkedHashSet(); + this.activeDifferenceFilters = newLinkedHashSet(); + this.aggregatedPredicate = DEFAULT_PREDICATE; + this.selectedObjects = newHashMap(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, + * java.lang.Object) + */ + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (predicates.isEmpty()) { + return true; + } + + Boolean cachedResult = selectedObjects.get(element); + if (cachedResult != null) { + return cachedResult.booleanValue(); + } + + final boolean result; + if (element instanceof GroupItemProviderAdapter) { + Collection children = ((GroupItemProviderAdapter)element).getChildren(element); + result = any(Iterables.filter(children, EObject.class), viewerPredicate); + } else if (element instanceof PendingUpdateAdapter) { + result = true; + } else if (element instanceof Adapter) { + Notifier notifier = ((Adapter)element).getTarget(); + if (notifier instanceof EObject) { + EObject eObject = (EObject)notifier; + result = viewerPredicate.apply(eObject); + } else { + result = true; + } + } else if (element instanceof EObject) { + result = viewerPredicate.apply((EObject)element); + } else { + result = true; + } + + selectedObjects.put(element, Boolean.valueOf(result)); + return result; + } + + /** + * Add the predicate of the given {@link IDifferenceFilter}. + * + * @param filter + * The given {@link IDifferenceFilter}. + */ + public void addFilter(IDifferenceFilter filter) { + boolean changed = predicates.remove(filter.getPredicateWhenUnselected()); + changed = predicates.add(filter.getPredicateWhenSelected()) || changed; + + changed = selectedDifferenceFilters.add(filter) || changed; + changed = unselectedDifferenceFilters.remove(filter) || changed; + + if (changed) { + clearCache(); + aggregatedPredicate = computeAggregatedPredicate(); + eventBus.post(new DifferenceFilterChange(aggregatedPredicate, selectedDifferenceFilters, + unselectedDifferenceFilters)); + } + } + + /** + * Computes the aggregated predicates composed of selected state predicates of selected filters and + * unselected state predicates of unselected filters. + * + * @return an aggregated predicates composed of selected state predicates of selected filters and + * unselected state predicates of unselected filters. + */ + private Predicate computeAggregatedPredicate() { + clearCache(); + return not(or(predicates)); + } + + /** + * Clears the cached results. + */ + private void clearCache() { + selectedObjects.clear(); + } + + /** + * Remove the predicate of the given {@link IDifferenceFilter}. + * + * @param filter + * The given {@link IDifferenceFilter}. + */ + public void removeFilter(IDifferenceFilter filter) { + boolean changed = predicates.add(filter.getPredicateWhenUnselected()); + changed |= predicates.remove(filter.getPredicateWhenSelected()); + + changed |= unselectedDifferenceFilters.add(filter); + changed |= selectedDifferenceFilters.remove(filter); + + if (changed) { + clearCache(); + aggregatedPredicate = computeAggregatedPredicate(); + eventBus.post(new DifferenceFilterChange(aggregatedPredicate, selectedDifferenceFilters, + unselectedDifferenceFilters)); + } + } + + /** + * Init this StructureMergeViewerFilter. + * + * @param selectedFilters + * the set of selected filters known by this filter. + * @param unselectedFilters + * the set of unselected filters known by this filter. + * @param activeFilters + * the set of activated filters known by this filter. + */ + public void init(Collection selectedFilters, + Collection unselectedFilters, Collection activeFilters) { + boolean changed = false; + + if (!predicates.isEmpty()) { + predicates.clear(); + changed = true; + } + + activeDifferenceFilters.addAll(activeFilters); + + for (IDifferenceFilter filter : selectedFilters) { + changed = predicates.add(filter.getPredicateWhenSelected()) || changed; + changed = selectedDifferenceFilters.add(filter) || changed; + } + for (IDifferenceFilter filter : unselectedFilters) { + changed = predicates.add(filter.getPredicateWhenUnselected()) || changed; + changed = unselectedDifferenceFilters.add(filter) || changed; + } + + if (changed) { + aggregatedPredicate = computeAggregatedPredicate(); + eventBus.post(new DifferenceFilterChange(aggregatedPredicate, selectedDifferenceFilters, + unselectedDifferenceFilters)); + } + } + + /** + * Returns the set of selected filters known by this filter. + * + * @return the selectedDifferenceFilters the set of selected filters known by this filter. + */ + public Set getSelectedDifferenceFilters() { + return selectedDifferenceFilters; + } + + /** + * Returns the set of activated filters known by this filter. + * + * @return the activatedDifferenceFilters the set of activated filters known by this filter. + */ + public Set getActiveDifferenceFilters() { + return activeDifferenceFilters; + } + + /** + * Returns the set of unselected filters known by this viewer. + * + * @return the unselectedDifferenceFilters the set of unselected filters known by this viewer. + */ + public Set getUnSelectedDifferenceFilters() { + return ImmutableSet.copyOf(unselectedDifferenceFilters); + } + + /** + * Returns the predicate that aggregates the selected state predicates of selected filters and the + * unselected state predicates of unselected filters. + * + * @return the predicate that aggregates the selected state predicates of selected filters and the + * unselected state predicates of unselected filters. + */ + public Predicate getAggregatedPredicate() { + return aggregatedPredicate; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java new file mode 100644 index 000000000..ea7140d79 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2013, 2016 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.structuremergeviewer.filters.impl; + +import static org.eclipse.emf.compare.ConflictKind.REAL; +import static org.eclipse.emf.compare.DifferenceKind.ADD; +import static org.eclipse.emf.compare.DifferenceKind.DELETE; +import static org.eclipse.emf.compare.DifferenceKind.MOVE; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasNoDirectOrIndirectConflict; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import com.google.common.collect.UnmodifiableIterator; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.match.MatchOfContainmentReferenceChangeAdapter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AbstractDifferenceFilter; +import org.eclipse.emf.compare.utils.MatchUtil; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * A filter used by default that filters out cascading differences (differences located under a Match that is + * either ADDed or DELETEd on the diff's side). The MOVE differences are not hidden by this filter. + * Differences hidden are all those that match the following criteria: + *
    + *
  • this.kind != MOVE
  • + *
  • this.conflict == null && this.'indirect real conflicts' is empty
  • + *
  • this.refines is empty
  • + *
  • this is located inside a TreeNode that represents a Match that is either ADDed or DELETEd, and for + * which the diff that represents this addition or deletion is not refined by this.
  • + *
+ * + * @author Axel Richard + * @since 4.0 + */ +public class CascadingDifferencesFilter extends AbstractDifferenceFilter { + + /** + * The predicate used by this filter when it is selected. + */ + private static final Predicate PREDICATE_WHEN_SELECTED = new Predicate() { + public boolean apply(EObject input) { + boolean ret = false; + if (input instanceof TreeNode) { + TreeNode treeNode = (TreeNode)input; + EObject data = treeNode.getData(); + if (data instanceof Diff && !(data instanceof ResourceAttachmentChange)) { + Diff diff = (Diff)data; + if (diff.getKind() != MOVE && hasNoDirectOrIndirectConflict(REAL).apply(diff) + && diff.getRefines().isEmpty()) { + TreeNode parent = treeNode.getParent(); + if (parent != null && parent.getData() instanceof Match) { + Match parentMatch = (Match)parent.getData(); + ret = isInsideAddOrDeleteTreeNode(diff, parent); + if (!ret && isAddOrDeleteMatch(parentMatch, diff.getSource())) { + ret = !Predicates + .and(Predicates.or(CONTAINMENT_REFERENCE_CHANGE, + REFINED_BY_CONTAINMENT_REF_CHANGE), ofKind(ADD, DELETE)) + .apply(diff); + } + } + } + } + } + return ret; + } + + private boolean isInsideAddOrDeleteTreeNode(Diff diff, TreeNode parent) { + boolean ret = false; + DifferenceSource side = diff.getSource(); + TreeNode grandParent = parent.getParent(); + Match grandParentMatch = null; + if (grandParent != null && grandParent.getData() instanceof Match) { + grandParentMatch = (Match)grandParent.getData(); + } + if (isAddOrDeleteMatch(grandParentMatch, side)) { + // The ancestor has been added/deleted, we must filter the current diff + // _unless_ it is refined by the diff that represents the grand-parent + // add/delete + Diff addOrDeleteDiff = findAddOrDeleteDiff(grandParentMatch, side); + if (addOrDeleteDiff != null) { + if (diff.getRefinedBy().contains(addOrDeleteDiff)) { + // recurse + ret = isInsideAddOrDeleteTreeNode(diff, grandParent); + } else { + ret = true; + } + } + } + return ret; + } + + private Diff findAddOrDeleteDiff(Match match, DifferenceSource side) { + final Iterable addOrDeleteContainmentDiffs = MatchUtil + .findAddOrDeleteContainmentDiffs(match); + if (addOrDeleteContainmentDiffs != null) { + final UnmodifiableIterator sideChanges = Iterators + .filter(addOrDeleteContainmentDiffs.iterator(), fromSide(side)); + if (sideChanges.hasNext()) { + return sideChanges.next(); + } + } + return null; + } + + /** + * Indicate whether a Match is that of an object that was either added or deleted on the given side. + * + * @param match + * The match + * @param side + * The side + * @return true if the matched object is present on side but not on origin or vice-versa. + * false if match is null. + */ + protected boolean isAddOrDeleteMatch(Match match, DifferenceSource side) { + if (match == null) { + return false; + } + Adapter adapter = EcoreUtil.getAdapter(match.eAdapters(), + MatchOfContainmentReferenceChangeAdapter.class); + return adapter != null; + } + }; + + private static final Predicate REFINED_BY_CONTAINMENT_REF_CHANGE = new Predicate() { + public boolean apply(Diff input) { + return Iterables.any(input.getRefinedBy(), CONTAINMENT_REFERENCE_CHANGE); + } + }; + + @Override + public Predicate getPredicateWhenSelected() { + return PREDICATE_WHEN_SELECTED; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterChange.java new file mode 100644 index 000000000..a0d63ddd2 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterChange.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.filters.impl; + +import com.google.common.base.Predicate; + +import java.util.Collection; +import java.util.Set; + +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange; +import org.eclipse.emf.ecore.EObject; + +/** + * The default implementation of {@link IDifferenceFilterChange}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class DifferenceFilterChange implements IDifferenceFilterChange { + + /** + * The predicate that aggregates the selected state predicates of selected filters and the unselected + * state predicates of unselected filters. + */ + private final Predicate predicate; + + /** + * The list of selected filters. + */ + private final Set selectedDifferenceFilters; + + /** + * The list of unselected filters. + */ + private final Set unselectedDifferenceFilters; + + /** + * Default Constructor. + * + * @param predicate + * a predicate that aggregates the selected state predicates of selected filters and the + * unselected state predicates of unselected filters. + * @param selectedDifferenceFilters + * the list of selected filters. + * @param unselectedDifferenceFilters + * the list of unselected filters. + */ + public DifferenceFilterChange(Predicate predicate, + Set selectedDifferenceFilters, + Set unselectedDifferenceFilters) { + this.predicate = predicate; + this.selectedDifferenceFilters = selectedDifferenceFilters; + this.unselectedDifferenceFilters = unselectedDifferenceFilters; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange#getPredicate() + */ + public Predicate getPredicate() { + return predicate; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange#getSelectedDifferenceFilters() + */ + public Collection getSelectedDifferenceFilters() { + return selectedDifferenceFilters; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterChange#getUnselectedDifferenceFilters() + */ + public Collection getUnselectedDifferenceFilters() { + return unselectedDifferenceFilters; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterExtensionRegistryListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterExtensionRegistryListener.java new file mode 100644 index 000000000..4f406abcd --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterExtensionRegistryListener.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.structuremergeviewer.filters.impl; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDeactivableDiffFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; + +/** + * Utility class to listen to the {@link IDifferenceFilter.Registry}. + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceFilterExtensionRegistryListener extends AbstractRegistryEventListener { + + /** TAG_FILTER_ACTION. */ + static final String TAG_FILTER_ACTION = "filter"; //$NON-NLS-1$ + + /** ATT_CLASS. */ + static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + /** ATT_LABEL. */ + static final String ATT_LABEL = "label"; //$NON-NLS-1$ + + /** ATT_LABEL. */ + static final String ATT_DESCRIPTION = "description"; //$NON-NLS-1$ + + /** ATT_ACTIVE. */ + static final String ATT_ACTIVE = "activeByDefault"; //$NON-NLS-1$ + + /** The DifferenceFilterManager in charge of managing filters. */ + private final DifferenceFilterManager filterRegistry; + + /** + * Default constructor. + * + * @param pluginID + * The namespace of the extension point to be monitored. + * @param extensionPointID + * The extension point ID to be monitored. + * @param log + * The log object to be used to log error and/or warning. + * @param filterManager + * The {@link DifferenceFilterManager} used to add/remove filter. + */ + public DifferenceFilterExtensionRegistryListener(String pluginID, String extensionPointID, ILog log, + DifferenceFilterManager filterManager) { + super(pluginID, extensionPointID, log); + this.filterRegistry = filterManager; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + final boolean valid; + if (element.getName().equals(TAG_FILTER_ACTION)) { + if (element.getAttribute(ATT_CLASS) == null) { + logMissingAttribute(element, ATT_CLASS); + valid = false; + } else if (element.getAttribute(ATT_LABEL) == null) { + logMissingAttribute(element, ATT_LABEL); + valid = false; + } else if (element.getAttribute(ATT_ACTIVE) == null) { + logMissingAttribute(element, ATT_ACTIVE); + valid = false; + } else { + valid = true; + } + } else { + valid = false; + } + return valid; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#addedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean addedValid(IConfigurationElement element) { + try { + IDifferenceFilter filter = (IDifferenceFilter)element.createExecutableExtension(ATT_CLASS); + filter.setLabel(element.getAttribute(ATT_LABEL)); + filter.setDescription(element.getAttribute(ATT_DESCRIPTION)); + if (Boolean.valueOf(element.getAttribute(ATT_ACTIVE)).booleanValue()) { + filter.setDefaultSelected(true); + } else { + filter.setDefaultSelected(false); + } + if (filter instanceof IDeactivableDiffFilter) { + ((IDeactivableDiffFilter)filter).setActive(true); + } + IDifferenceFilter previous = filterRegistry.add(filter); + if (previous != null) { + log(IStatus.WARNING, element, "The filter '" + filter.getClass().getName() //$NON-NLS-1$ + + "' is registered twice."); //$NON-NLS-1$ + } + } catch (CoreException e) { + log(element, e); + return false; + } + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + filterRegistry.remove(element.getAttribute(ATT_CLASS)); + return true; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterManager.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterManager.java new file mode 100644 index 000000000..17aac3e36 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterManager.java @@ -0,0 +1,365 @@ +/******************************************************************************* + * Copyright (c) 2014, 2106 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.structuremergeviewer.filters.impl; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; +import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDeactivableDiffFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.jface.preference.IPreferenceStore; + +/** + * Manager of filters. + *

+ * This manager handle addition and removal of filters + *

+ *

+ * It also allow to override registered filters with preferences. + *

+ * + * @author Arthur Daussy + */ +public class DifferenceFilterManager { + + /** Preference key for by default disabled filters. */ + private static final String BY_DEFAULT_DISABLED_FILTER = "org.eclipse.emf.compare.rcp.ui.filters.disabled"; //$NON-NLS-1$ + + /** Preference key for inactive (fully ignored) filters. */ + private static final String INACTIVE_FILTERS_PREF_KEY = "org.eclipse.emf.compare.rcp.ui.filters.inactive"; //$NON-NLS-1$ + + /** A map that associates the class name to their {@link IDifferenceFilter}s. */ + private final Map map; + + /** The {@link IPreferenceStore} holding the value for filter preferences. */ + private final IPreferenceStore preferenceStore; + + /** + * Predicate use to transform {@link DifferenceFilterDefaultConfiguration} to {@link IDifferenceFilter}. + */ + private final static Function TO_FILTER = new Function() { + + public IDifferenceFilter apply(DifferenceFilterDefaultConfiguration arg0) { + if (arg0 != null) { + return arg0.getFilter(); + } + return null; + } + }; + + /** + * Constructor. + * + * @param preferenceStore + * The {@link IPreferenceStore} holding the value for filter preferences. + */ + public DifferenceFilterManager(IPreferenceStore preferenceStore) { + map = Collections.synchronizedMap(new LinkedHashMap()); + this.preferenceStore = preferenceStore; + } + + /** + * Add a new filter. + * + * @param filter + * {@link IDifferenceFilter} + * @return The old {@link IDifferenceFilter} register with the same key. + */ + IDifferenceFilter add(IDifferenceFilter filter) { + Preconditions.checkNotNull(filter); + DifferenceFilterDefaultConfiguration oldValue = map.put(filter.getClass().getName(), + new DifferenceFilterDefaultConfiguration(filter, filter.defaultSelected())); + if (oldValue != null) { + return oldValue.getFilter(); + } + return null; + } + + /** + * Remove a filter. + * + * @param className + * The class name of the filter. + * @return The {@link IDifferenceFilter} that has been removed or null if none. + */ + IDifferenceFilter remove(String className) { + DifferenceFilterDefaultConfiguration oldValue = map.remove(className); + if (oldValue != null) { + return oldValue.getFilter(); + } + return null; + } + + /** + * Get all {@link IDifferenceFilter} that should be used by default for next comparison. + * + * @return A {@link Collection} of {@link IDifferenceFilter} that should be used by default for next + * comparison. + */ + public Set getCurrentByDefaultFilters() { + Set storedFilter = getDisabledFilters(); + if (storedFilter == null) { + return getInitialByDefaultFilters(); + } + return Sets.difference(getAllFilters(), storedFilter); + } + + /** + * Get all {@link IDifferenceFilter} that should be disabled for next comparison. + * + * @return A {@link Collection} of {@link IDifferenceFilter} that should be disabled for next comparison. + */ + public Collection getCurrentInactiveFilters() { + Set inactiveFilters = getInactiveFilters(); + if (inactiveFilters == null) { + return Collections.emptyList(); + } + return inactiveFilters; + } + + /** + * {@link Set} of {@link IDifferenceFilter} that are initially enabled by default. + *

+ * During the first addiction in the registry of these {@link IDifferenceFilter}, + * {@link IDifferenceFilter#defaultSelected()} was equal to true + *

+ * + * @return {@link Set} of {@link IDifferenceFilter} that are original enabled by default. + */ + public Set getInitialByDefaultFilters() { + Set result = Sets.newLinkedHashSet(); + for (DifferenceFilterDefaultConfiguration f : map.values()) { + if (f.isDefaultSelectedInitialValue()) { + result.add(f.getFilter()); + } + } + return result; + } + + /** + * Set the filters that should be used by default for next comparison. + * + * @param enabledFilter + * {@link Set} of {@link IDifferenceFilter} to set. + */ + public void setCurrentByDefaultFilters(Set enabledFilter) { + final Set disabledFilter; + if (enabledFilter == null) { + disabledFilter = getAllFilters(); + } else { + disabledFilter = Sets.difference(getAllFilters(), enabledFilter); + } + SetView initialDisabledFilter = Sets.difference(getAllFilters(), + getInitialByDefaultFilters()); + storeInPreferences(disabledFilter, initialDisabledFilter, BY_DEFAULT_DISABLED_FILTER); + // Trace preferences values + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder builder = new StringBuilder(); + // Print each preferences + builder.append("Preference ").append(BY_DEFAULT_DISABLED_FILTER).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$ + String preferenceValue = preferenceStore.getString(BY_DEFAULT_DISABLED_FILTER); + String[] groups = preferenceValue.split(ItemUtil.PREFERENCE_DELIMITER); + for (int rank = 0; rank < groups.length; rank++) { + builder.append(rank).append(". ").append(groups[rank]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + builder.append("\n\n"); //$NON-NLS-1$ + EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); + } + } + + /** + * Set the filters that should be active for the next comparison. + * + * @param activeFilters + * {@link Set} of {@link IDifferenceFilter} to set. + */ + public void setCurrentActiveFilters(Set activeFilters) { + final Set inactiveFilters; + Set deactivableFilters = Sets + .newLinkedHashSet(Iterables.filter(getAllFilters(), IDeactivableDiffFilter.class)); + if (activeFilters == null) { + inactiveFilters = deactivableFilters; + } else { + inactiveFilters = Sets.difference(deactivableFilters, activeFilters); + } + storeInPreferences(inactiveFilters, Collections. emptySet(), + INACTIVE_FILTERS_PREF_KEY); + // Trace preferences values + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder builder = new StringBuilder(); + // Print each preferences + builder.append("Preference ").append(INACTIVE_FILTERS_PREF_KEY).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$ + String preferenceValue = preferenceStore.getString(INACTIVE_FILTERS_PREF_KEY); + String[] groups = preferenceValue.split(ItemUtil.PREFERENCE_DELIMITER); + for (int rank = 0; rank < groups.length; rank++) { + builder.append(rank).append(". ").append(groups[rank]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + builder.append("\n\n"); //$NON-NLS-1$ + EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); + } + } + + /** + * Get all registered filter. + * + * @return {@link Set} of all filter. + */ + public Set getAllFilters() { + return Sets.newLinkedHashSet(Collections2.transform(map.values(), TO_FILTER)); + } + + /** + * A {@link Set} of disabled by default {@link IDifferenceFilter} from preferences. + *

+ * Those filter will not be activated by default for next comparison + *

+ * + * @return A {@link Set} of disabled by default {@link IDifferenceFilter} from preferences. + */ + private Set getDisabledFilters() { + String diffEngineKey = preferenceStore.getString(BY_DEFAULT_DISABLED_FILTER); + Set result = null; + if (diffEngineKey != null && !diffEngineKey.isEmpty()) { + String[] diffEngineKeys = diffEngineKey.split(ItemUtil.PREFERENCE_DELIMITER); + for (String nonTrimedKey : diffEngineKeys) { + String key = nonTrimedKey.trim(); + DifferenceFilterDefaultConfiguration descriptor = map.get(key); + if (descriptor != null) { + if (result == null) { + result = new LinkedHashSet(); + } + result.add(descriptor.getFilter()); + } + } + } + return result; + } + + /** + * A {@link Set} of deactivated {@link IDeactivableDiffFilter} from preferences. + *

+ * Those filters will be totally inactive for next comparisons. + *

+ * + * @return A {@link Set} of deactivated {@link IDeactivableDiffFilter} from preferences (Filters that do + * not implement {@link IDeactivableDiffFilter} cannot be deactivated). + */ + private Set getInactiveFilters() { + String diffEngineKey = preferenceStore.getString(INACTIVE_FILTERS_PREF_KEY); + Set result = null; + if (diffEngineKey != null && !diffEngineKey.isEmpty()) { + String[] diffEngineKeys = diffEngineKey.split(ItemUtil.PREFERENCE_DELIMITER); + for (String nonTrimedKey : diffEngineKeys) { + String key = nonTrimedKey.trim(); + DifferenceFilterDefaultConfiguration descriptor = map.get(key); + if (descriptor != null) { + IDifferenceFilter filter = descriptor.getFilter(); + if (filter instanceof IDeactivableDiffFilter) { + if (result == null) { + result = new LinkedHashSet(); + } + result.add((IDeactivableDiffFilter)filter); + } + } + } + } + return result; + } + + /** + * Store value in preferences. + * + * @param currentValue + * Value to store. + * @param defaultConf + * Default value. + */ + private void storeInPreferences(Set currentValue, + Set defaultConf, String prefKey) { + if (currentValue != null && !currentValue.equals(defaultConf)) { + Map toStore = Maps.filterValues(Maps.transformValues(map, TO_FILTER), + Predicates.in(currentValue)); + String preferenceValue = Joiner.on(ItemUtil.PREFERENCE_DELIMITER).join(toStore.keySet()); + preferenceStore.putValue(prefKey, preferenceValue); + } else { + preferenceStore.setToDefault(prefKey); + } + } + + /** + * Clear all registered {@link IDifferenceFilter}. + */ + public void clear() { + map.clear(); + } + + /** + * Wrapper of {@link IDifferenceFilter} used to keep track of the initial value of + * {@link IDifferenceFilter#defaultSelected()} to be able to restore it. + * + * @author Arthur Daussy + */ + private static class DifferenceFilterDefaultConfiguration { + + /** Base {@link IDifferenceFilter} */ + private IDifferenceFilter filter; + + /** Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition. */ + private boolean isDefaultSelectedInitialValue; + + /** + * Constructor. + * + * @param filter + * Base filter + * @param isByDefaultSelected + * Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition. + */ + public DifferenceFilterDefaultConfiguration(IDifferenceFilter filter, boolean isByDefaultSelected) { + super(); + this.filter = filter; + this.isDefaultSelectedInitialValue = isByDefaultSelected; + } + + /** + * @return Base filter. + */ + public IDifferenceFilter getFilter() { + return filter; + } + + /** + * @return Initial value of {@link IDifferenceFilter#defaultSelected()} during first addition. + */ + public boolean isDefaultSelectedInitialValue() { + return isDefaultSelectedInitialValue; + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterRegistryImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterRegistryImpl.java new file mode 100644 index 000000000..1b8e1415d --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/DifferenceFilterRegistryImpl.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.structuremergeviewer.filters.impl; + +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Lists.newArrayList; + +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDeactivableDiffFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry; +import org.eclipse.emf.compare.scope.IComparisonScope; + +/** + * The default implementation of the + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry}. + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceFilterRegistryImpl implements Registry { + + /** {@link DifferenceFilterManager} used to get active {@link IDifferenceFilter}. */ + private final DifferenceFilterManager filterManager; + + /** + * Constructs the registry. + */ + public DifferenceFilterRegistryImpl(DifferenceFilterManager filterManager) { + this.filterManager = filterManager; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#getFilters(org.eclipse.emf.compare.scope.IComparisonScope, + * org.eclipse.emf.compare.Comparison) + */ + public List getFilters(IComparisonScope scope, Comparison comparison) { + Collection filtersEnabledByDefault = filterManager.getCurrentByDefaultFilters(); + Collection inactiveFilters = filterManager.getCurrentInactiveFilters(); + Iterable matchingFilters = filter(filterManager.getAllFilters(), + isFilterActivable(scope, comparison)); + /* + * Set the value of default selected using filter manager. + */ + for (IDifferenceFilter filter : matchingFilters) { + if (filtersEnabledByDefault.contains(filter)) { + filter.setDefaultSelected(true); + } else { + filter.setDefaultSelected(false); + } + if (inactiveFilters.contains(filter)) { + ((IDeactivableDiffFilter)filter).setActive(false); + } else if (filter instanceof IDeactivableDiffFilter) { + ((IDeactivableDiffFilter)filter).setActive(true); + } + } + return newArrayList(matchingFilters); + } + + /** + * Returns a predicate that represents the activation condition based on the scope and comparison objects. + * + * @param scope + * The scope on which the group provider will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return A predicate that represents the activation condition based on the scope and comparison objects. + */ + static final Predicate isFilterActivable(final IComparisonScope scope, + final Comparison comparison) { + return new Predicate() { + /** + * {@inheritDoc} + * + * @see com.google.common.base.Predicate#apply(java.lang.Object) + */ + public boolean apply(IDifferenceFilter d) { + return d.isEnabled(scope, comparison); + } + }; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#add(org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter) + */ + public IDifferenceFilter add(IDifferenceFilter filter) { + Preconditions.checkNotNull(filter); + return filterManager.add(filter); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#remove(java.lang.String) + */ + public IDifferenceFilter remove(String className) { + return filterManager.remove(className); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#clear() + */ + public void clear() { + filterManager.clear(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/TechnicalitiesFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/TechnicalitiesFilter.java new file mode 100644 index 000000000..c660a761e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/TechnicalitiesFilter.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2016 Obeo and others. + * 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 + * Philip Langer - bug 501864 + * Tanja Mayerhofer - bug 501864 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl; + +import static com.google.common.base.Predicates.or; +import static com.google.common.collect.Iterators.any; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.canBeConsideredAsPseudoConflicting; + +import com.google.common.base.Predicate; + +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AbstractDifferenceFilter; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.FeatureMap; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + *

+ * A filter used by default that rejects all 'technical' differences. The technical differences are the diffs + * that apply on empty {@link MatchResource}s, on {@link FeatureMap} diffs, on identical elements and on + * pseudo-conflicts. + *

+ * This filter aggregates the former 4 corresponding filters. + * + * @author Mathieu Cartaud + */ +public class TechnicalitiesFilter extends AbstractDifferenceFilter { + + /** + * The predicate use to filter empty match resources. + */ + private static final Predicate PREDICATE_EMPTY_MATCH_RESOURCES = new Predicate() { + public boolean apply(EObject input) { + boolean ret = false; + if (input instanceof TreeNode) { + TreeNode treeNode = (TreeNode)input; + if (treeNode.getData() instanceof MatchResource) { + ret = treeNode.getChildren().isEmpty(); + } + } + return ret; + } + }; + + /** + * The predicate use to filter feature maps. + */ + private static final Predicate PREDICATE_FEATURE_MAP = new Predicate() { + public boolean apply(EObject input) { + boolean ret = false; + if (input instanceof TreeNode) { + EObject data = ((TreeNode)input).getData(); + if (data instanceof FeatureMapChange) { + ret = ((FeatureMapChange)data).getEquivalence() != null; + } + } + return ret; + } + }; + + /** + * The predicate use to filter pseudo conflicts. + */ + private static final Predicate PREDICATE_PSEUDO_CONFLICT = new Predicate() { + public boolean apply(EObject input) { + boolean ret = false; + if (input instanceof TreeNode) { + TreeNode treeNode = (TreeNode)input; + EObject data = treeNode.getData(); + if (data instanceof Diff) { + Diff diff = (Diff)data; + if (diff.getMatch().getComparison().isThreeWay()) { + ret = canBeConsideredAsPseudoConflicting().apply(diff); + } + } + } + return ret; + } + }; + + /** + * The predicate use to filter identical elements. + */ + private static final Predicate PREDICATE_IDENTICAL_ELEMENTS = new Predicate() { + public boolean apply(EObject input) { + if (input instanceof TreeNode) { + TreeNode treeNode = (TreeNode)input; + EObject data = treeNode.getData(); + if (data instanceof Match) { + return !any(treeNode.eAllContents(), DATA_IS_DIFF); + } + } + return false; + } + }; + + /** + * The predicate use by this filter when it is selected. + */ + @SuppressWarnings("unchecked") + private static final Predicate PREDICATE_WHEN_SELECTED = or( + PREDICATE_EMPTY_MATCH_RESOURCES, PREDICATE_FEATURE_MAP, PREDICATE_IDENTICAL_ELEMENTS, + PREDICATE_PSEUDO_CONFLICT); + + /** + * Predicate to know if the given TreeNode is a diff. + */ + private static final Predicate DATA_IS_DIFF = new Predicate() { + public boolean apply(EObject treeNode) { + return treeNode instanceof TreeNode && ((TreeNode)treeNode).getData() instanceof Diff; + } + }; + + @Override + public Predicate getPredicateWhenSelected() { + return PREDICATE_WHEN_SELECTED; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/StructureMergeViewerGrouper.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/StructureMergeViewerGrouper.java new file mode 100644 index 000000000..197deb9be --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/StructureMergeViewerGrouper.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.groups; + +import static com.google.common.collect.Sets.newLinkedHashSet; + +import com.google.common.collect.Lists; +import com.google.common.eventbus.EventBus; + +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupProviderChange; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.EmptyDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; + +/** + * This class will be used by the EMF Compare UI to group differences together in the structural differences + * tree viewer. + * + * @author Laurent Goubet + * @since 4.0 + */ +public final class StructureMergeViewerGrouper { + + /** An empty difference group provider. */ + private final IDifferenceGroupProvider empty; + + /** + * The currently selected group provider. This is what will compute and give us the groups we need to + * display. + */ + private IDifferenceGroupProvider provider; + + /** List of all TreeViewers on which this grouper is applied. */ + private final List viewers; + + /** The {@link EventBus} associated with this grouper. */ + private final EventBus eventBus; + + /** The set of registered group provider that has been set on this grouper. */ + private final Set registeredGroupProviders; + + /** + * Constructs the difference grouper. + * + * @param eventBus + * The {@link EventBus} which will be associated with this difference grouper. + */ + public StructureMergeViewerGrouper(EventBus eventBus) { + this.empty = new EmptyDifferenceGroupProvider(); + this.eventBus = eventBus; + this.provider = empty; + this.viewers = Lists.newArrayList(); + this.registeredGroupProviders = newLinkedHashSet(); + } + + /** + * Sets the instance that will provide the groups to be displayed in the structural differences view. + * + * @param provider + * The provider that will be use to compute the groups that are to be displayed in the UI. + */ + public void setProvider(IDifferenceGroupProvider provider) { + if (this.provider != provider) { + this.provider = provider; + refreshViewers(); + eventBus.post(new DifferenceGroupProviderChange(provider)); + } + } + + /** + * Get the {@link IDifferenceGroupProvider} associated to this StructureMergeViewerGrouper. + * + * @return the provider associated to this StructureMergeViewerGrouper + */ + public IDifferenceGroupProvider getProvider() { + return provider; + } + + /** + * Refreshes the viewers registered with this grouper. + */ + private void refreshViewers() { + for (StructuredViewer viewer : viewers) { + Adapter root = (Adapter)viewer.getInput(); + if (root != null) { + Notifier target = root.getTarget(); + registerDifferenceGroupProvider(target, provider); + } + } + } + + /** + * Registers the selected IDifferenceGroupProvider to the given Notifier. + * + * @param notifier + * the given Notifier. + * @param groupProvider + * the selected IDifferenceGroupProvider. + */ + protected void registerDifferenceGroupProvider(Notifier notifier, + IDifferenceGroupProvider groupProvider) { + List eAdapters = notifier.eAdapters(); + Adapter oldGroupProvider = EcoreUtil.getAdapter(eAdapters, IDifferenceGroupProvider.class); + if (oldGroupProvider != null) { + eAdapters.remove(oldGroupProvider); + } + eAdapters.add(groupProvider); + registeredGroupProviders.add(groupProvider); + } + + /** + * Install this grouper on the given viewer. + *

+ * Note that this will also install a dispose listener on that viewer in order to remove the grouper + * whenever the viewer is disposed. + *

+ * + * @param viewer + * The viewer on which the grouper will be installed. + */ + public void install(final StructuredViewer viewer) { + viewer.getControl().addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + uninstall(viewer); + } + }); + viewers.add(viewer); + } + + /** + * Uninstall this grouper from the given viewer. + * + * @param viewer + * The viewer from which the grouper should be removed. + */ + public void uninstall(StructuredViewer viewer) { + Object input = viewer.getInput(); + final Notifier notifier; + if (input instanceof Notifier) { + notifier = (Notifier)input; + } else if (input instanceof Adapter) { + notifier = ((Adapter)input).getTarget(); + } else { + notifier = null; + } + if (notifier != null) { + List eAdapters = notifier.eAdapters(); + Adapter groupProvider = EcoreUtil.getAdapter(eAdapters, IDifferenceGroupProvider.class); + if (provider != groupProvider) { + throw new IllegalStateException(); + } + eAdapters.remove(provider); + } + for (IDifferenceGroupProvider registeredGroupProvider : registeredGroupProviders) { + registeredGroupProvider.dispose(); + } + viewers.remove(viewer); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryImpl.java new file mode 100644 index 000000000..fe768111b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryImpl.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.extender; + +import static com.google.common.collect.Lists.newArrayList; + +import com.google.common.base.Preconditions; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender.Registry; + +/** + * The default implementation of the {@link Registry}. + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceGroupExtenderRegistryImpl implements Registry { + + /** A map that associates the class name to theirs {@link IDifferenceGroupExtender}s. */ + private final Map map; + + /** + * Constructs the registry. + */ + public DifferenceGroupExtenderRegistryImpl() { + map = new ConcurrentHashMap(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender.Registry#getExtenders() + */ + public List getExtenders() { + Iterable extenders = map.values(); + List ret = newArrayList(); + for (IDifferenceGroupExtender groupExtender : extenders) { + ret.add(groupExtender); + } + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender.Registry#add + * (org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender) + */ + public IDifferenceGroupExtender add(IDifferenceGroupExtender provider) { + Preconditions.checkNotNull(provider); + return map.put(provider.getClass().getName(), provider); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender.Registry#remove(java.lang.String) + * ) + */ + public IDifferenceGroupExtender remove(String className) { + return map.remove(className); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender + * .Registry#clear() + */ + public void clear() { + map.clear(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryListener.java new file mode 100644 index 000000000..03cf69819 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/extender/DifferenceGroupExtenderRegistryListener.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.extender; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender; + +/** + * Utility class to listen to the + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry} + * . + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceGroupExtenderRegistryListener extends AbstractRegistryEventListener { + + /** TAG_GROUP_PROVIDER. */ + static final String TAG_GROUP_PROVIDER = "differenceGroupExtender"; //$NON-NLS-1$ + + /** ATT_CLASS. */ + static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + /** The registry. */ + private final IDifferenceGroupExtender.Registry extendersRegistry; + + /** + * Default Constructor. + * + * @param pluginID + * The namespace of the extension point to be monitored. + * @param extensionPointID + * The extension point ID to be monitored + * @param log + * The log object to be used to log error and/or warning. + * @param registry + * The registry to listen. + */ + public DifferenceGroupExtenderRegistryListener(String pluginID, String extensionPointID, ILog log, + IDifferenceGroupExtender.Registry registry) { + super(pluginID, extensionPointID, log); + this.extendersRegistry = registry; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + final boolean valid; + + if (element.getName().equals(TAG_GROUP_PROVIDER)) { + if (element.getAttribute(ATT_CLASS) == null) { + logMissingAttribute(element, ATT_CLASS); + valid = false; + } else { + valid = true; + } + } else { + valid = false; + } + return valid; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#addedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean addedValid(IConfigurationElement element) { + try { + IDifferenceGroupExtender extender = (IDifferenceGroupExtender)element + .createExecutableExtension(ATT_CLASS); + IDifferenceGroupExtender previous = extendersRegistry.add(extender); + if (previous != null) { + log(IStatus.WARNING, element, "The difference group extender '" //$NON-NLS-1$ + + extender.getClass().getName() + "' is registered twice."); //$NON-NLS-1$ + } + } catch (CoreException e) { + log(element, e); + return false; + } + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + extendersRegistry.remove(element.getAttribute(ATT_CLASS)); + return true; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/BasicDifferenceGroupImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/BasicDifferenceGroupImpl.java new file mode 100644 index 000000000..e375b5406 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/BasicDifferenceGroupImpl.java @@ -0,0 +1,585 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.structuremergeviewer.groups.impl; + +import static com.google.common.collect.Collections2.filter; +import static com.google.common.collect.Iterators.any; +import static com.google.common.collect.Iterators.concat; +import static com.google.common.collect.Iterators.transform; +import static com.google.common.collect.Lists.newArrayList; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceState; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.provider.utils.ComposedStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString.Style; +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.structuremergeviewer.nodes.ConflictNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.DiffNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchResourceNode; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.extender.IDifferenceGroupExtender; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.swt.graphics.Image; + +/** + * This implementation of a {@link IDifferenceGroup} uses a predicate to filter the whole list of differences. + *

+ * This can be subclasses or used directly instead of {@link IDifferenceGroup}. + *

+ * + * @author Laurent Goubet + * @since 4.0 + */ +public class BasicDifferenceGroupImpl extends AdapterImpl implements IDifferenceGroup { + + /** + * Function that returns all contents of the given EObject. + */ + protected static final Function> E_ALL_CONTENTS = new Function>() { + public Iterator apply(EObject eObject) { + return eObject.eAllContents(); + } + }; + + /** The filter we'll use in order to filter the differences that are part of this group. */ + protected final Predicate filter; + + /** The name that the EMF Compare UI will display for this group. */ + protected final String name; + + /** The icon that the EMF Compare UI will display for this group. */ + protected final Image image; + + /** The list of children of this group. */ + protected List children; + + /** The comparison that is the parent of this group. */ + private final Comparison comparison; + + /** The registry of difference group extenders. */ + private final IDifferenceGroupExtender.Registry registry = EMFCompareRCPUIPlugin.getDefault() + .getDifferenceGroupExtenderRegistry(); + + /** The cross reference adapter that will be added to this group's children. */ + private final ECrossReferenceAdapter crossReferenceAdapter; + + /** + * Instantiates this group given the comparison and filter that should be used in order to determine its + * list of differences. + *

+ * This will use the default name and icon for the group. + *

+ * + * @param comparison + * The comparison that is the parent of this group. + * @param filter + * The filter we'll use in order to filter the differences that are part of this group. + * @param crossReferenceAdapter + * The cross reference adapter that will be added to this group's children. + */ + public BasicDifferenceGroupImpl(Comparison comparison, Predicate filter, + ECrossReferenceAdapter crossReferenceAdapter) { + this(comparison, filter, EMFCompareRCPUIMessages.getString("BasicDifferenceGroup.name"), //$NON-NLS-1$ + EMFCompareRCPUIPlugin.getImage("icons/full/toolb16/group.gif"), //$NON-NLS-1$ + crossReferenceAdapter); + } + + /** + * Instantiates this group given the comparison and filter that should be used in order to determine its + * list of differences. It will be displayed in the UI with the default icon and the given name. + * + * @param comparison + * The comparison that is the parent of this group. + * @param filter + * The filter we'll use in order to filter the differences that are part of this group. + * @param name + * The name that the EMF Compare UI will display for this group. + * @param crossReferenceAdapter + * The cross reference adapter that will be added to this group's children. + */ + public BasicDifferenceGroupImpl(Comparison comparison, Predicate filter, String name, + ECrossReferenceAdapter crossReferenceAdapter) { + this(comparison, filter, name, EMFCompareRCPUIPlugin.getImage("icons/full/toolb16/group.gif"), //$NON-NLS-1$ + crossReferenceAdapter); + } + + /** + * Instantiates this group given the comparison and filter that should be used in order to determine its + * list of differences. It will be displayed in the UI with the given icon and name. + * + * @param comparison + * The comparison that is the parent of this group. + * @param filter + * The filter we'll use in order to filter the differences that are part of this group. + * @param name + * The name that the EMF Compare UI will display for this group. + * @param image + * The icon that the EMF Compare UI will display for this group. + * @param crossReferenceAdapter + * Updated upstream The cross reference adapter that will be added to this group's children. + */ + public BasicDifferenceGroupImpl(Comparison comparison, Predicate filter, String name, + Image image, ECrossReferenceAdapter crossReferenceAdapter) { + this.comparison = comparison; + this.filter = filter; + this.name = name; + this.image = image; + this.crossReferenceAdapter = crossReferenceAdapter; + } + + /** + * Returns the comparison object. + * + * @return the comparison object. + */ + protected final Comparison getComparison() { + return comparison; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + */ + @Override + public boolean isAdapterForType(Object type) { + return type == IDifferenceGroup.class; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup#getName() + */ + public String getName() { + return name; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup#getStyledName() + */ + public IStyledString.IComposedStyledString getStyledName() { + final IStyledString.IComposedStyledString ret = new ComposedStyledString(); + Iterator eAllContents = concat(transform(getChildren().iterator(), E_ALL_CONTENTS)); + Iterator eAllData = transform(eAllContents, TREE_NODE_DATA); + boolean unresolvedDiffs = any(Iterators.filter(eAllData, Diff.class), + hasState(DifferenceState.UNRESOLVED)); + if (unresolvedDiffs) { + ret.append("> ", Style.DECORATIONS_STYLER); //$NON-NLS-1$ + } + ret.append(getName()); + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup#getImage() + */ + public Image getImage() { + return image; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup#getChildren() + */ + public List getChildren() { + if (children == null) { + buildSubTree(); + } + return children; + } + + /** + * Registers the CrossReferenceAdapter to all given notifiers. + * + * @param notifiers + * the list of notifiers. + */ + protected final void registerCrossReferenceAdapter(List notifiers) { + for (Notifier notifier : notifiers) { + // this cross referencer has to live as long as the objects on which it is installed. + notifier.eAdapters().add(crossReferenceAdapter); + } + } + + /** + * Unregisters the CrossReferenceAdapter from all given notifiers. + * + * @param notifiers + * the list of notifiers. + */ + protected final void unregisterCrossReferenceAdapter(List notifiers) { + for (Notifier notifier : notifiers) { + // this cross referencer has to live as long as the objects on which it is installed. + notifier.eAdapters().remove(crossReferenceAdapter); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup#dispose() + */ + public void dispose() { + if (children != null) { + unregisterCrossReferenceAdapter(children); + children = null; + } + } + + /** + * Builds the sub tree for this group. + */ + public void buildSubTree() { + children = createChildren(); + doBuildSubTrees(); + customize(children); + registerCrossReferenceAdapter(children); + setTarget(comparison); + } + + /** + * Perform the creation of the sub-trees of the group. + */ + protected void doBuildSubTrees() { + children.addAll(buildMatchTrees()); + children.addAll(buildMatchResourceTrees()); + } + + /** + * This creates the root-level children of the group. + * + * @return This default implementation returns a new ArrayList. It may be overridden by sub-classes. + */ + protected List createChildren() { + return newArrayList(); + } + + /** + * Compute a subTree for each root match of the comparison. + * + * @return the list of matchSubTrees + */ + protected List buildMatchTrees() { + final List matchTrees = new ArrayList(); + for (Match match : getComparison().getMatches()) { + MatchNode matchNode = buildTree(match); + if (matchNode != null) { + matchTrees.add(matchNode); + } + } + return matchTrees; + } + + /** + * Compute a tree for the given match. + * + * @param match + * The given match + * @return a list of subTree for this match, must not be null + */ + protected MatchNode buildTree(Match match) { + MatchNode result = null; + MatchNode matchNode = createMatchNode(match); + populateMatchNode(matchNode); + if (!matchNode.getChildren().isEmpty()) { + result = matchNode; + } + return result; + } + + /** + * Build the subtree for the given match. + * + * @param matchNode + * The root matchNode + * @return the computed matchNode + */ + protected void populateMatchNode(MatchNode matchNode) { + Match match = matchNode.getMatch(); + Multimap diffsBySubMatch = LinkedHashMultimap.create(); + for (Diff diff : filter(match.getDifferences(), filter)) { + // If a diff is part of a larger diff (is refined by), we don't want to add it to the tree. It + // will be added by the algorithm in a second step. This way we avoid duplication and all diffs + // that are part of a 'master' diff are grouped as children of this 'master' diff + if (mustDisplayAsDirectChildOfMatch(diff)) { + Match targetMatch = getTargetMatch(diff); + if (match == targetMatch) { + addDiffNode(matchNode, diff); + } else if (match.getSubmatches().contains(targetMatch)) { + diffsBySubMatch.put(targetMatch, diff); + } else if (targetMatch != null) { + MatchNode targetMatchNode = createMatchNode(targetMatch); + matchNode.addSubMatchNode(targetMatchNode); + addDiffNode(targetMatchNode, diff); + } + } + } + for (Match subMatch : match.getSubmatches()) { + MatchNode subMatchNode = createMatchNode(subMatch); + for (Diff subMatchDiff : diffsBySubMatch.get(subMatch)) { + addDiffNode(subMatchNode, subMatchDiff); + } + diffsBySubMatch.removeAll(subMatch); + populateMatchNode(subMatchNode); + if (!subMatchNode.getChildren().isEmpty()) { + matchNode.addSubMatchNode(subMatchNode); + } + } + } + + /** + * Provide the Match that should directly contain the given diff. If the given diff should not be a direct + * child of a Match, the method must return null. For a given strategy, a diff should only be + * displayed in the same Match (i.e. the {@link DiffNode}s that represent the diff should always be + * children of the {@link MatchNode}s that represent the returned Match. + * + * @param diff + * The difference + * @return The Match that is a direct parent of the given diff, can be null. + */ + protected Match getTargetMatch(Diff diff) { + if (mustDisplayAsDirectChildOfMatch(diff)) { + if (isContainmentRefChange(diff)) { + Match valueMatch = diff.getMatch().getComparison() + .getMatch(((ReferenceChange)diff).getValue()); + return valueMatch; // This match may not be a sub-match because the child may have moved + } else if (isContainmentRefChange(diff.getPrimeRefining())) { + Match valueMatch = diff.getMatch().getComparison() + .getMatch(((ReferenceChange)diff.getPrimeRefining()).getValue()); + return valueMatch; // This match may not be a sub-match because the child may have moved + } + return diff.getMatch(); + } + return null; + } + + /** + * Does the given difference have to be displayed as direct child of a Match? + * + * @param diff + * The diff + * @return true if the diff's node should be a child of a MatchNode. + */ + protected boolean mustDisplayAsDirectChildOfMatch(Diff diff) { + return diff.getRefines().isEmpty(); + } + + /** + * Is it a containment reference change? + * + * @param diff + * The diff + * @return true if the diff is a {@link ReferenceChange} whose {@link EReference} is a + * containment reference. + */ + protected boolean isContainmentRefChange(Diff diff) { + return diff instanceof ReferenceChange && ((ReferenceChange)diff).getReference().isContainment(); + } + + protected List buildMatchResourceTrees() { + final List matchResourceTrees = new ArrayList(); + if (getComparison().getMatchedResources().isEmpty()) { + return matchResourceTrees; + } + + final Iterable attachmentChanges = Iterables + .filter(getComparison().getDifferences(), ResourceAttachmentChange.class); + + final Multimap uriToRAC = LinkedHashMultimap.create(); + for (ResourceAttachmentChange attachmentChange : attachmentChanges) { + uriToRAC.put(attachmentChange.getResourceURI(), attachmentChange); + } + for (MatchResource matchResource : getComparison().getMatchedResources()) { + final Collection leftRAC = uriToRAC.get(matchResource.getLeftURI()); + final Collection rightRAC = uriToRAC.get(matchResource.getRightURI()); + final Collection originRAC = uriToRAC.get(matchResource.getOriginURI()); + final LinkedHashSet racForMatchResource = Sets.newLinkedHashSet(); + racForMatchResource.addAll(leftRAC); + racForMatchResource.addAll(rightRAC); + racForMatchResource.addAll(originRAC); + + MatchResourceNode matchNode = buildSubTree(matchResource, racForMatchResource); + if (matchNode != null) { + matchResourceTrees.add(matchNode); + } + + } + return matchResourceTrees; + } + + /** + * Build the sub tree of the given {@link MatchResource}. + * + * @param matchResource + * the given MatchResource. + * @return the sub tree of the given MatchResource. + */ + protected MatchResourceNode buildSubTree(MatchResource matchResource, + Set attachmentChanges) { + MatchResourceNode matchResourceNode = createMatchResourceNode(matchResource); + Collection filteredChanges = filter(attachmentChanges, filter); + for (ResourceAttachmentChange attachmentChange : filteredChanges) { + DiffNode diffNode = createDiffNode(attachmentChange); + matchResourceNode.addDiffNode(diffNode); + } + return matchResourceNode; + } + + /** + * Add the diff in the given match. This method handles refined diffs and allows to customize the result. + * + * @param matchNode + * The given match node + * @param diff + * The diff to add + */ + protected void addDiffNode(MatchNode matchNode, Diff diff) { + if (!(diff instanceof ResourceAttachmentChange)) { + DiffNode diffNode = createDiffNode(diff); + handleRefiningDiffs(diffNode); + matchNode.addDiffNode(diffNode); + } + } + + /** + * Create a diff node. + * + * @param diff + * The given diff + * @return the DiffNode + */ + protected DiffNode createDiffNode(Diff diff) { + DiffNode diffNode = new DiffNode(diff); + diffNode.eAdapters().add(this); + return diffNode; + } + + /** + * Create a match node. + * + * @param match + * The given match + * @return the MatchNode + */ + protected MatchNode createMatchNode(Match match) { + MatchNode matchNode = new MatchNode(match); + matchNode.eAdapters().add(this); + return matchNode; + } + + /** + * Create a conflict node. + * + * @param conflict + * The given conflict + * @return the ConflictNode + */ + protected ConflictNode createConflictNode(Conflict conflict) { + ConflictNode conflictNode = new ConflictNode(conflict); + conflictNode.eAdapters().add(this); + return conflictNode; + } + + /** + * Create a matchResource node. + * + * @param matchResource + * The given matchResource + * @return the MatchResourceNode + */ + protected MatchResourceNode createMatchResourceNode(MatchResource matchResource) { + MatchResourceNode matchResourceNode = new MatchResourceNode(matchResource); + matchResourceNode.eAdapters().add(this); + return matchResourceNode; + } + + /** + * Walk the given trees and customize each node in the tree, starting by the deeper nodes all the way up + * to the root nodes. This method calls itself recursively. + * + * @param nodes + * The list of nodes to customize. + */ + protected void customize(List nodes) { + for (TreeNode node : nodes) { + customize(node.getChildren()); + customize(node); + } + } + + /** + * Allow extenders to customize a TreeNode. + * + * @param treeNode + * the TreeNode to customize. + */ + protected void customize(TreeNode treeNode) { + for (IDifferenceGroupExtender ext : registry.getExtenders()) { + if (ext.handle(treeNode)) { + ext.addChildren(treeNode); + } + } + } + + /** + * Handle the diffs that refine the given diff. Refining diffs are added as children of the given diff, + * and so on recursively. + * + * @param diffNode + * The diff node to handle, which is not necessarily a child of a MatchNode since this method + * is called recursively. + */ + protected void handleRefiningDiffs(DiffNode diffNode) { + Diff diff = diffNode.getDiff(); + for (Diff refiningDiff : diff.getRefinedBy()) { + DiffNode refinedDiffNode = createDiffNode(refiningDiff); + diffNode.addRefinedDiffNode(refinedDiffNode); + handleRefiningDiffs(refinedDiffNode); + } + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ByResourceGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ByResourceGroupProvider.java new file mode 100644 index 000000000..f26ed2fde --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ByResourceGroupProvider.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2013, 2016 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.structuremergeviewer.groups.impl; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.DiffNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchResourceNode; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * This implementation of a + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider} will be used to + * group the differences by their Resource. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class ByResourceGroupProvider extends AbstractDifferenceGroupProvider { + + /** + * Specialized {@link BasicDifferenceGroupImpl} for Resources. + * + * @author Mikael Barbero + */ + public static class ResourceGroup extends BasicDifferenceGroupImpl { + private Set roots; + + /** + * {@inheritDoc}. + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl#BasicDifferenceGroupImpl(org.eclipse.emf.compare.Comparison) + */ + public ResourceGroup(Comparison comparison, ECrossReferenceAdapter crossReferenceAdapter) { + super(comparison, Predicates. alwaysTrue(), crossReferenceAdapter); + } + + @Override + public void buildSubTree() { + // Prepare our "roots" list + roots = new LinkedHashSet(); + for (Match match : getComparison().getMatches()) { + recursiveFindRoots(match); + } + super.buildSubTree(); + } + + private void recursiveFindRoots(Match match) { + if (hasRootSide(match)) { + roots.add(match); + } + for (Match subMatch : match.getSubmatches()) { + recursiveFindRoots(subMatch); + } + } + + /** + * Checks if the given match has a side which is the root of its resource. + * + * @param match + * The match. + * @return true if this match has a "root" side (even if its the root of a fragment), + * false otherwise. + */ + private boolean hasRootSide(Match match) { + boolean hasRoot = match.getLeft() instanceof InternalEObject + && ((InternalEObject)match.getLeft()).eDirectResource() != null; + hasRoot = hasRoot || match.getRight() instanceof InternalEObject + && ((InternalEObject)match.getRight()).eDirectResource() != null; + hasRoot = hasRoot || match.getOrigin() instanceof InternalEObject + && ((InternalEObject)match.getOrigin()).eDirectResource() != null; + return hasRoot; + } + + /** {@inheritDoc} */ + @Override + protected List buildMatchTrees() { + // All of our nodes will be under MatchResources for this group. + return new ArrayList(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl#buildSubTree(MatchResource, + * Set) + */ + @Override + protected MatchResourceNode buildSubTree(MatchResource matchResource, + Set attachmentChanges) { + MatchResourceNode matchResourceNode = createMatchResourceNode(matchResource); + + for (ResourceAttachmentChange attachmentChange : attachmentChanges) { + DiffNode diffNode = createDiffNode(attachmentChange); + matchResourceNode.addDiffNode(diffNode); + } + + for (Match match : roots) { + if (isUnderResourceWithURI(match.getLeft(), matchResource.getLeftURI()) + || isUnderResourceWithURI(match.getRight(), matchResource.getRightURI()) + || isUnderResourceWithURI(match.getOrigin(), matchResource.getOriginURI())) { + MatchNode matchNode = createMatchNode(match); + populateMatchNode(matchNode); + if (!matchNode.getChildren().isEmpty()) { + matchResourceNode.addMatchNode(matchNode); + } + } + } + + return matchResourceNode; + } + + /** + * Check if the resource of the given object as the same uri as the given uri. + * + * @param eObject + * the given object. + * @param uri + * the given uri. + * @return true if the resource of the given object as the same uri as the given uri, false otherwise. + */ + private boolean isUnderResourceWithURI(EObject eObject, String uri) { + if (eObject != null && uri != null) { + final Resource resource = eObject.eResource(); + return resource != null && uri.equals(resource.getURI().toString()); + } + return false; + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.AbstractBuildingDifferenceGroupProvider#buildGroups(org.eclipse.emf.compare.Comparison) + */ + @Override + protected Collection buildGroups(Comparison comparison2) { + ResourceGroup group = new ResourceGroup(comparison2, getCrossReferenceAdapter()); + group.buildSubTree(); + return ImmutableList.of(group); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ConflictNodeBuilder.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ConflictNodeBuilder.java new file mode 100644 index 000000000..9ede33baa --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ConflictNodeBuilder.java @@ -0,0 +1,90 @@ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl; + +import com.google.common.collect.Lists; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.ThreeWayComparisonGroupProvider.ConflictsGroupImpl; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.ConflictNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode; +import org.eclipse.emf.ecore.EObject; + +public class ConflictNodeBuilder { + + private final Conflict conflict; + + private final ConflictsGroupImpl group; + + private final Map matchNodes; + + public ConflictNodeBuilder(Conflict conflict, ConflictsGroupImpl group) { + this.conflict = conflict; + this.group = group; + matchNodes = new LinkedHashMap(); + } + + /** + * Build the node for the conflict. + * + * @return The node of the conflict, complete with all its children. + */ + public ConflictNode buildNode() { + ConflictNode conflictNode = group.createConflictNode(conflict); + for (Diff diff : conflict.getDifferences()) { + Match match = group.getTargetMatch(diff); + if (match != null) { + MatchNode matchNode = ensureMatchNode(match, conflictNode); + group.addDiffNode(matchNode, diff); + } + } + List nonRootMatches = Lists.newArrayListWithCapacity(matchNodes.size()); + outer: for (Match match : matchNodes.keySet()) { + EObject container = match.eContainer(); + while (container instanceof Match) { + if (matchNodes.containsKey(container)) { + nonRootMatches.add(match); + continue outer; + } + container = container.eContainer(); + } + } + for (Match match : nonRootMatches) { + MatchNode matchNode = matchNodes.get(match); + EObject container = match.eContainer(); + MatchNode childNode = matchNode; + boolean stop = false; + while (container instanceof Match && !stop) { + MatchNode hierarchyNode; + if (matchNodes.containsKey(container)) { + hierarchyNode = matchNodes.get(container); + stop = true; + } else { + hierarchyNode = group.createMatchNode((Match)container); + matchNodes.put((Match)container, hierarchyNode); + } + hierarchyNode.addSubMatchNode(childNode); + childNode = hierarchyNode; + container = container.eContainer(); + } + } + return conflictNode; + } + + private MatchNode ensureMatchNode(Match match, ConflictNode conflictNode) { + MatchNode node; + if (matchNodes.containsKey(match)) { + node = matchNodes.get(match); + } else { + node = group.createMatchNode(match); + conflictNode.addConflictingTree(node); + matchNodes.put(match, node); + } + return node; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DefaultGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DefaultGroupProvider.java new file mode 100644 index 000000000..7199cffb6 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DefaultGroupProvider.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.impl; + +import static com.google.common.base.Predicates.alwaysTrue; + +import com.google.common.collect.ImmutableList; + +import java.util.Collection; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; + +/** + * This implementation of a + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider} will be used as + * the default group provider. + * + * @author Axel Richard + * @since 4.0 + */ +public class DefaultGroupProvider extends AbstractDifferenceGroupProvider { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.AbstractBuildingDifferenceGroupProvider#buildGroups(org.eclipse.emf.compare.Comparison) + */ + @Override + protected Collection buildGroups(Comparison comparison2) { + BasicDifferenceGroupImpl group = new BasicDifferenceGroupImpl(getComparison(), alwaysTrue(), + getCrossReferenceAdapter()); + + group.buildSubTree(); + return ImmutableList.of(group); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupDescriptorWrapper.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupDescriptorWrapper.java new file mode 100644 index 000000000..1c10b6db9 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupDescriptorWrapper.java @@ -0,0 +1,88 @@ +/****************************************************************************** + * 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.structuremergeviewer.groups.impl; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.emf.compare.rcp.internal.extension.impl.AbstractItemDescriptor; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.ComparisonType; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; + +/** + * Implementation of {@link IDifferenceGroupProvider.Descriptor}. + * + * @author Arthur Daussy + */ +public class DifferenceGroupDescriptorWrapper extends AbstractItemDescriptor implements IDifferenceGroupProvider.Descriptor { + + /** {@link IConfigurationElement} used to instantiate the {@link IDifferenceGroupProvider}. */ + private final IConfigurationElement element; + + /** Type of comparison the {@link IDifferenceGroupProvider} can handle. */ + private final ComparisonType type; + + /** + * Constructor. + * + * @param label + * Human-readable label of the underlying group provider. + * @param description + * A more detailed description that can be displayed to the user for this group. + * @param elem + * {@link IConfigurationElement} used to instantiate the {@link IDifferenceGroupProvider} + * @param rank + * Rank of the descriptor + * @param comparisonType + * Type of comparison the wrapped {@link IDifferenceGroupProvider} can handle. + */ + public DifferenceGroupDescriptorWrapper(String label, String description, IConfigurationElement elem, + int rank, ComparisonType comparisonType) { + super(label, description, rank, + elem.getAttribute(DifferenceGroupProviderExtensionRegistryListener.ATT_CLASS)); + this.element = elem; + this.type = comparisonType; + } + + /** + * {@inheritDoc} + */ + public Descriptor getItem() { + return this; + } + + /** + * {@inheritDoc} + */ + public ComparisonType getType() { + return type; + } + + /** + * {@inheritDoc} + */ + public IDifferenceGroupProvider createGroupProvider() { + Object instance; + try { + instance = element + .createExecutableExtension(DifferenceGroupProviderExtensionRegistryListener.ATT_CLASS); + if (instance instanceof IDifferenceGroupProvider) { + IDifferenceGroupProvider groupProvider = (IDifferenceGroupProvider)instance; + return groupProvider; + } + } catch (CoreException e) { + EMFCompareRCPUIPlugin.getDefault().log(e); + } + return null; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java new file mode 100644 index 000000000..f3a321dd8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java @@ -0,0 +1,258 @@ +/****************************************************************************** + * 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.structuremergeviewer.groups.impl; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +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.tracer.TracingConstant; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.ComparisonType; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.preference.IPreferenceStore; + +/** + * This manager can be used to modify EMF Compare UI behavior regarding groups. + *

+ * This manager can override the rank of groups. For example, it can be used to define a default group that + * will be used by EMF Compare UI. + *

+ *

+ * This manager can define a synchronization behavior between a user selection of group in EMF Compare UI and + * the default group that is used by EMF Compare UI. + *

+ * + * @author Arthur Daussy + */ +public class DifferenceGroupManager { + + /** Predicate for 2-way {@link IDifferenceGroupProvider.Descriptor}. */ + private static final Predicate> TWO_WAY_FILTER = new Predicate>() { + + public boolean apply(IItemDescriptor descriptor) { + if (descriptor == null) { + return false; + } + ComparisonType type = descriptor.getItem().getType(); + return type == ComparisonType.BOTH || type == ComparisonType.TWO_WAY; + } + }; + + /** Predicate for 3-way {@link IDifferenceGroupProvider.Descriptor}. */ + private static final Predicate> THREE_WAY_FILTER = new Predicate>() { + + public boolean apply(IItemDescriptor descriptor) { + if (descriptor == null) { + return false; + } + ComparisonType type = descriptor.getItem().getType(); + return type == ComparisonType.BOTH || type == ComparisonType.THREE_WAY; + } + }; + + /** Ordered list of groups for two way comparison. */ + private static final String TWO_WAY_GROUP_RANKING = "org.eclipse.emf.compare.rcp.ui.groups.2way.ranking"; //$NON-NLS-1$ + + /** Ordered list of groups for three way comparison. */ + private static final String THREE_WAY_GROUP_RANKING = "org.eclipse.emf.compare.rcp.ui.groups.3way.ranking"; //$NON-NLS-1$ + + /** Registry of {@link IDifferenceGroupProvider.Descriptor}. */ + private final IItemRegistry registry; + + /** The {@link IPreferenceStore} holding the value for group preferences. */ + private final IPreferenceStore preferenceStore; + + /** + * Constructor. + * + * @param registry + * Registry of {@link IDifferenceGroupProvider.Descriptor}. + * @param preferenceStore + * The {@link IPreferenceStore} holding the value for group preferences. + */ + public DifferenceGroupManager(IItemRegistry registry, + IPreferenceStore preferenceStore) { + this.registry = registry; + this.preferenceStore = preferenceStore; + } + + /** + * Gets the current value of the group ranking. + * + * @param preferenceKey + * Preference key use to retrieve the value in preferences. + * @param defaultOrder + * The default ranking. + * @return A ordered {@link List} of {@link IItemDescriptor}. + */ + private List> getCurrent(String preferenceKey, + List> defaultOrder) { + return getOrderedItems(defaultOrder, registry, preferenceKey); + } + + /** + * Gets the current group order. + * + * @param isThreeWay + * True if three way comparison, false otherwise. + * @return Ordered {@link List} of {@link IDifferenceGroupProvider.Descriptor}. + */ + public List> getCurrentGroupRanking(boolean isThreeWay) { + return getCurrent(getGroupPreferenceKey(isThreeWay), getDefaultRankingConfiguration(isThreeWay)); + } + + /** + * Gets the default groups order. + * + * @param isThreeWay + * True if three way comparison, false otherwise. + * @return Ordered {@link List} of {@link IDifferenceGroupProvider.Descriptor}. + */ + public List> getDefaultRankingConfiguration( + boolean isThreeWay) { + final Iterable> groups; + if (isThreeWay) { + groups = Iterables.filter(registry.getItemDescriptors(), THREE_WAY_FILTER); + } else { + + groups = Iterables.filter(registry.getItemDescriptors(), TWO_WAY_FILTER); + } + List> result = Lists.newArrayList(groups); + Collections.sort(result); + return result; + } + + /** + * Gets the preference key for group ranking. + * + * @param isThreeWay + * True if three way comparison. + * @return They key of the group ranking preference for this type of comparison. + */ + private String getGroupPreferenceKey(boolean isThreeWay) { + if (isThreeWay) { + return THREE_WAY_GROUP_RANKING; + } else { + return TWO_WAY_GROUP_RANKING; + } + } + + /** + * Returns an ordered list of {@link IItemDescriptor}. The order of the list is either defined by the rank + * in the registry or from preference if the rank has been overloaded. If any descriptor has been added or + * removed since last modification of the preference, this method will merge the modification. + * + * @param orderedDefaultDescriptor + * List of ordered default {@link IItemDescriptor}. + * @param descriptorRegistry + * Registry of descriptor. + * @param orderedItemPreferenceKey + * Key in preferences where are stored the new order of descriptor + * @return Ordered list of descriptor. + * @param + * Descriptor type. + */ + private List> getOrderedItems(List> orderedDefaultDescriptor, + IItemRegistry descriptorRegistry, String orderedItemPreferenceKey) { + List> itemsDescriptor = ItemUtil.getItemsDescriptor(descriptorRegistry, + EMFCompareRCPUIPlugin.PLUGIN_ID, orderedItemPreferenceKey); + + if (itemsDescriptor == null) { + itemsDescriptor = orderedDefaultDescriptor; + } else { + HashSet> descriptorFromPrefSet = Sets.newLinkedHashSet(itemsDescriptor); + HashSet> defaultDescriptorSet = Sets + .newLinkedHashSet(orderedDefaultDescriptor); + + // Remove descriptor + SetView> descriptorToRemove = Sets.difference(descriptorFromPrefSet, + defaultDescriptorSet); + Iterables.removeAll(itemsDescriptor, descriptorToRemove); + + // Add new descriptor + SetView> descriptorToAdd = Sets.difference(defaultDescriptorSet, + descriptorFromPrefSet); + Iterables.addAll(itemsDescriptor, descriptorToAdd); + + } + return itemsDescriptor; + } + + /** + * Sets the ranking of Difference group provider. + * + * @param descriptors + * An ordered list of {@link IItemDescriptor}. + * @param isThreeWay + * True if three way comparison. + */ + public void setCurrentGroupRanking(List> descriptors, boolean isThreeWay) { + storeInPreferences(getGroupPreferenceKey(isThreeWay), descriptors, + getDefaultRankingConfiguration(isThreeWay)); + + // Trace preferences values + if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { + StringBuilder builder = new StringBuilder(); + // Print each preferences + builder.append("Preference ").append(getGroupPreferenceKey(isThreeWay)).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$ + String preferenceValue = preferenceStore.getString(getGroupPreferenceKey(isThreeWay)); + String[] groups = preferenceValue.split(ItemUtil.PREFERENCE_DELIMITER); + for (int rank = 0; rank < groups.length; rank++) { + builder.append(rank).append(". ").append(groups[rank]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + builder.append("\n\n"); //$NON-NLS-1$ + EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); + } + } + + /** + * Stores the value into preferences. + * + * @param preferenceKey + * Key of the preference + * @param currentValue + * Current value to store + * @param defaultConf + * Default value + */ + private void storeInPreferences(String preferenceKey, + List> currentValue, + List> defaultConf) { + if (currentValue != null && !currentValue.equals(defaultConf)) { + Iterable currentIDs = Iterables.transform(currentValue, + new Function, String>() { + + public String apply(IItemDescriptor arg0) { + return arg0.getID(); + } + }); + String preferenceValue = Joiner.on(ItemUtil.PREFERENCE_DELIMITER).join(currentIDs); + preferenceStore.putValue(preferenceKey, preferenceValue); + } else { + preferenceStore.setToDefault(preferenceKey); + } + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderChange.java new file mode 100644 index 000000000..444e1a5cd --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderChange.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.impl; + +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProviderChange; + +/** + * The default implementation of {@link IDifferenceGroupProviderChange}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class DifferenceGroupProviderChange implements IDifferenceGroupProviderChange { + + /** The selected IDifferenceGroupProvider. */ + private final IDifferenceGroupProvider differenceGroupProvider; + + /** + * Default constructor. + * + * @param differenceGroupProvider + * an IDifferenceGroupProvider. + */ + public DifferenceGroupProviderChange(IDifferenceGroupProvider differenceGroupProvider) { + this.differenceGroupProvider = differenceGroupProvider; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProviderChange#getDifferenceGroupProvider() + */ + public IDifferenceGroupProvider getDifferenceGroupProvider() { + return differenceGroupProvider; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderExtensionRegistryListener.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderExtensionRegistryListener.java new file mode 100644 index 000000000..6e663d323 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupProviderExtensionRegistryListener.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.groups.impl; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.ComparisonType; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; + +/** + * Utility class to listen to the {@link IDifferenceGroupProvider.Descriptor.Registry}. + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceGroupProviderExtensionRegistryListener extends AbstractRegistryEventListener { + + /** Default value for the rank attribute if not specified. */ + private static final int DEFAULT_RANK_VALUE = 0; + + /** TAG_GROUP_PROVIDER. */ + static final String TAG_GROUP_PROVIDER = "group"; //$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$ + + /** ATT_COMPARISON_TYPE. */ + static final String ATT_COMPARISON_TYPE = "type"; //$NON-NLS-1$ + + /** ATT_RANK. */ + static final String ATT_RANK = "rank"; //$NON-NLS-1$ + + /** ATT_CLASS. */ + static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + /** The IDifferenceGroupProvider.Descriptor.Registry to listen. */ + private final IItemRegistry groupProviderRegistry; + + /** + * Default constructor. + * + * @param pluginID + * The namespace of the extension point to be monitored. + * @param extensionPointID + * The extension point ID to be monitored. + * @param log + * The log object to be used to log error and/or warning. + * @param registry + * The {@link IDifferenceGroupProvider.Descriptor.Registry} to listen. + */ + public DifferenceGroupProviderExtensionRegistryListener(String pluginID, String extensionPointID, + ILog log, IItemRegistry registry) { + super(pluginID, extensionPointID, log); + this.groupProviderRegistry = registry; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#validateExtensionElement(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean validateExtensionElement(IConfigurationElement element) { + final boolean valid; + if (element.getName().equals(TAG_GROUP_PROVIDER)) { + if (element.getAttribute(ATT_CLASS) == null) { + logMissingAttribute(element, ATT_CLASS); + valid = false; + } else if (element.getAttribute(ATT_LABEL) == null) { + logMissingAttribute(element, ATT_LABEL); + valid = false; + } else if (element.getAttribute(ATT_RANK) != null) { + try { + Integer.valueOf(element.getAttribute(ATT_RANK)); + } catch (NumberFormatException e) { + log(element, e); + return false; + } + valid = true; + } else if (element.getAttribute(ATT_COMPARISON_TYPE) != null) { + try { + ComparisonType.valueOf(element.getAttribute(ATT_COMPARISON_TYPE)); + valid = true; + } catch (IllegalArgumentException e) { + log(element, e); + return false; + } + } else { + valid = true; + } + } else { + valid = false; + } + return valid; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#addedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean addedValid(IConfigurationElement element) { + String rankValue = element.getAttribute(ATT_RANK); + final int rank; + if (rankValue == null) { + rank = DEFAULT_RANK_VALUE; + } else { + rank = Integer.valueOf(rankValue).intValue(); + } + String typeAttribute = element.getAttribute(ATT_COMPARISON_TYPE); + final ComparisonType type; + if (typeAttribute != null) { + type = ComparisonType.valueOf(typeAttribute); + } else { + type = ComparisonType.BOTH; + } + String label = element.getAttribute(ATT_LABEL); + String description = element.getAttribute(ATT_DESCRIPTION); + DifferenceGroupDescriptorWrapper itemDescriptor = new DifferenceGroupDescriptorWrapper(label, + description, element, rank, type); + + IItemDescriptor previous = groupProviderRegistry.add(itemDescriptor); + if (previous != null) { + log(IStatus.WARNING, element, "The group provider descriptor'" + element.getAttribute(ATT_CLASS) //$NON-NLS-1$ + + "' is registered twice."); //$NON-NLS-1$ + } + return true; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener#removedValid(org.eclipse.core.runtime.IConfigurationElement) + */ + @Override + protected boolean removedValid(IConfigurationElement element) { + groupProviderRegistry.remove(element.getAttribute(ATT_CLASS)); + return true; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java new file mode 100644 index 000000000..3c4747864 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.groups.impl; + +import static com.google.common.collect.Lists.newArrayList; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; + +import org.eclipse.emf.compare.Comparison; +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; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.emf.compare.scope.IComparisonScope; + +/** + * Implementation of the {@link IDifferenceGroupProvider.Descriptor.Registry}. This implementation allow user + * to override ranking of each group using preferences. + * + * @author Axel Richard + * @since 4.0 + */ +public class DifferenceGroupRegistryImpl implements IDifferenceGroupProvider.Descriptor.Registry { + + /** A map that associates the class name to theirs {@link IDifferenceGroupProvider.Descriptor}s. */ + private final IItemRegistry registry; + + /** Group manager. */ + private DifferenceGroupManager groupManager; + + /** + * Constructs the registry. + * + * @param groupManager + * {@link DifferenceGroupManager} use to handle groups. + * @param registry + * Item registry where are stored all registered group. + */ + public DifferenceGroupRegistryImpl(DifferenceGroupManager groupManager, + IItemRegistry registry) { + this.groupManager = groupManager; + this.registry = registry; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry#getGroupProviders(IComparisonScope, + * Comparison) + */ + public List getGroupProviders(IComparisonScope scope, + Comparison comparison) { + if (comparison != null) { + List providers = newArrayList(); + List> groupProviderDescriptors = groupManager + .getCurrentGroupRanking(comparison.isThreeWay()); + ListIterator> groupIterator = groupProviderDescriptors.listIterator(); + while (groupIterator.hasNext()) { + IItemDescriptor desc = groupIterator.next(); + IDifferenceGroupProvider.Descriptor groupProviderDescriptor = desc.getItem(); + IDifferenceGroupProvider gp = groupProviderDescriptor.createGroupProvider(); + if (gp != null && isGroupProviderActivable(gp, scope, comparison)) { + providers.add(groupProviderDescriptor); + } + } + return ImmutableList.copyOf(providers); + } + return Collections.emptyList(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry#getDefaultGroupProvider(org.eclipse.emf.compare.scope.IComparisonScope, + * org.eclipse.emf.compare.Comparison) + */ + public IDifferenceGroupProvider.Descriptor getDefaultGroupProvider(IComparisonScope scope, + Comparison comparison) { + List descriptors = getGroupProviders(scope, comparison); + if (!descriptors.isEmpty()) { + return descriptors.get(0); + } + return null; + } + + /** + * Checks if the given IDifferenceGroupProvider is activable based on the scope and comparison objects. + * + * @param dgp + * the given IDifferenceGroupProvider. + * @param scope + * The scope on which the group provider will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return true, if it is activable, false otherwise. + */ + static final boolean isGroupProviderActivable(final IDifferenceGroupProvider dgp, + final IComparisonScope scope, final Comparison comparison) { + return dgp.isEnabled(scope, comparison); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry#add + * (org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor) + */ + public IDifferenceGroupProvider.Descriptor add(IDifferenceGroupProvider.Descriptor providerDescriptor, + String className) { + Preconditions.checkNotNull(providerDescriptor); + IDifferenceGroupProvider groupProvider = providerDescriptor.createGroupProvider(); + WrapperItemDescriptor descriptor = new WrapperItemDescriptor( + providerDescriptor.getLabel(), providerDescriptor.getDescription(), + providerDescriptor.getRank(), groupProvider.getClass().getName(), providerDescriptor); + + IItemDescriptor oldValue = registry.add(descriptor); + if (oldValue != null) { + return oldValue.getItem(); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry#remove(java.lang.String) + */ + public IDifferenceGroupProvider.Descriptor remove(String className) { + IItemDescriptor oldValue = registry.remove(className); + if (oldValue != null) { + return oldValue.getItem(); + } + return null; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor.Registry#clear() + */ + public void clear() { + registry.clear(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/EmptyDifferenceGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/EmptyDifferenceGroupProvider.java new file mode 100644 index 000000000..9dc550a20 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/EmptyDifferenceGroupProvider.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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.structuremergeviewer.groups.impl; + +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider; + +/** + * An empty difference group provider. + * + * @author Axel Richard + * @since 4.0 + */ +public class EmptyDifferenceGroupProvider extends AbstractDifferenceGroupProvider { + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/KindGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/KindGroupProvider.java new file mode 100644 index 000000000..3e68d2a1e --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/KindGroupProvider.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2012, 2016 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.structuremergeviewer.groups.impl; + +import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.util.Collection; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.DifferenceKind; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; + +/** + * This implementation of a + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider} will be used to + * group the differences by their {@link DifferenceKind kind} : additions, deletions, changes and moves. + * + * @author Laurent Goubet + * @since 4.0 + */ +public class KindGroupProvider extends AbstractDifferenceGroupProvider { + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.AbstractBuildingDifferenceGroupProvider#buildGroups(org.eclipse.emf.compare.Comparison) + */ + @Override + protected Collection buildGroups(Comparison comparison2) { + final BasicDifferenceGroupImpl additions = new BasicDifferenceGroupImpl(getComparison(), + ofKind(DifferenceKind.ADD), + EMFCompareRCPUIMessages.getString("KindGroupProvider.addition.label"), //$NON-NLS-1$ + getCrossReferenceAdapter()); + additions.buildSubTree(); + final BasicDifferenceGroupImpl deletions = new BasicDifferenceGroupImpl(getComparison(), + ofKind(DifferenceKind.DELETE), + EMFCompareRCPUIMessages.getString("KindGroupProvider.deletion.label"), //$NON-NLS-1$ + getCrossReferenceAdapter()); + deletions.buildSubTree(); + final BasicDifferenceGroupImpl changes = new BasicDifferenceGroupImpl(getComparison(), + ofKind(DifferenceKind.CHANGE), + EMFCompareRCPUIMessages.getString("KindGroupProvider.change.label"), //$NON-NLS-1$ + getCrossReferenceAdapter()); + changes.buildSubTree(); + final BasicDifferenceGroupImpl moves = new BasicDifferenceGroupImpl(getComparison(), + ofKind(DifferenceKind.MOVE), + EMFCompareRCPUIMessages.getString("KindGroupProvider.move.label"), //$NON-NLS-1$ + getCrossReferenceAdapter()); + moves.buildSubTree(); + + Collection groups = Lists.newArrayList(); + if (!additions.getChildren().isEmpty()) { + groups.add(additions); + } + if (!deletions.getChildren().isEmpty()) { + groups.add(deletions); + } + if (!changes.getChildren().isEmpty()) { + groups.add(changes); + } + if (!moves.getChildren().isEmpty()) { + groups.add(moves); + } + return ImmutableList.copyOf(groups); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ThreeWayComparisonGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ThreeWayComparisonGroupProvider.java new file mode 100644 index 000000000..1e3fc07d2 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/ThreeWayComparisonGroupProvider.java @@ -0,0 +1,432 @@ +/******************************************************************************* + * Copyright (c) 2013, 2016 Obeo and others. + * 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 + * Stefan Dirix - bug 488941 + * Simon Delisle, Edgar Mueller - bug 486923 + * Tanja Mayerhofer - bug 501864 + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.and; +import static com.google.common.base.Predicates.not; +import static com.google.common.base.Predicates.or; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterators.concat; +import static com.google.common.collect.Iterators.filter; +import static com.google.common.collect.Iterators.transform; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Maps.newHashMap; +import static java.util.Collections.unmodifiableSet; +import static org.eclipse.emf.compare.ConflictKind.PSEUDO; +import static org.eclipse.emf.compare.ConflictKind.REAL; +import static org.eclipse.emf.compare.internal.utils.DiffUtil.getRootRefinedDiffs; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.allAtomicRefining; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.anyRefining; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.containsConflictOfTypes; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; +import com.google.common.collect.Sets.SetView; +import com.google.common.collect.UnmodifiableIterator; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.emf.compare.DifferenceState; +import org.eclipse.emf.compare.impl.ConflictImpl; +import org.eclipse.emf.compare.provider.utils.ComposedStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString.Style; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.SideLabelProvider; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.ConflictNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.DiffNode; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.ecore.util.EcoreUtil; + +/** + * This implementation of a + * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider} will be used to + * group the differences by their {@link DifferenceSource side} : left, right and conflicts. + *

+ * The table below describes the location of a diff depending on its status and that of its refining diffs + * (whether all or some of them are in a real/pseudo conflict).
+ *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Real ConflictsPseudo-ConflictsNo Conflict
AllSomeAllSomeAll
Tech. filter ONConflictConflictConflict (hidden)SideSide
Tech. filter OFFConflictConflictConflictSideSide
+ *

+ * + * @author Axel Richard + * @since 4.0 + */ +public class ThreeWayComparisonGroupProvider extends AbstractDifferenceGroupProvider { + + /** + * The default predicate used to filter differences in difference groups. The predicate returns true for + * diffs that do not have a direct or indirect real conflict and that do not have only pseudo conflicts. + */ + public static final Predicate DEFAULT_DIFF_GROUP_FILTER_PREDICATE = and( + not(hasConflict(REAL, PSEUDO)), + not(or(anyRefining(hasConflict(REAL)), allAtomicRefining(hasConflict(PSEUDO))))); + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org + * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison) + */ + @Override + public boolean isEnabled(IComparisonScope scope, Comparison comparison) { + if (comparison != null && comparison.isThreeWay()) { + return true; + } + return false; + } + + /** + * Specialized {@link BasicDifferenceGroupImpl} for Conflicts. + * + * @author Axel Richard + */ + public static class ConflictsGroupImpl extends BasicDifferenceGroupImpl { + + /** + * The default predicate used to filter differences. + */ + private static final Predicate DEFAULT_CONFLICT_GROUP_FILTER_PREDICATE = hasConflict( + ConflictKind.REAL, ConflictKind.PSEUDO); + + /** + * Conflict groups to show in SMV. + */ + private final List compositeConflicts = newArrayList(); + + /** + * Maps conflicting differences to their composite conflicts. + */ + private final Map diffToCompositeConflictMap = newHashMap(); + + /** + * {@inheritDoc}. + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl#BasicDifferenceGroupImpl(org.eclipse.emf.compare.Comparison, + * java.lang.Iterable, com.google.common.base.Predicate, java.lang.String) + */ + public ConflictsGroupImpl(Comparison comparison, Predicate filter, String name, + ECrossReferenceAdapter crossReferenceAdapter) { + super(comparison, filter, name, crossReferenceAdapter); + } + + /** + * Instantiates this group given the comparison. It will use the default filter to determine its list + * of differences. It will be displayed in the UI with the default icon and the given name. + * + * @param comparison + * The comparison that is the parent of this group. + * @param name + * The name that the EMF Compare UI will display for this group. + * @param crossReferenceAdapter + * The cross reference adapter that will be added to this group's children. + */ + public ConflictsGroupImpl(Comparison comparison, String name, + ECrossReferenceAdapter crossReferenceAdapter) { + super(comparison, DEFAULT_CONFLICT_GROUP_FILTER_PREDICATE, name, crossReferenceAdapter); + } + + /** + * In conflicts, a special case must be handled for refining diffs: If they are not part of the same + * conflict then they should not be in the same group as the refined diff. + * + * @param diff + * The difference + * @return true if the diff refines nothing or if its conflict does not contain all the + * diffs it refines. + */ + @Override + protected boolean mustDisplayAsDirectChildOfMatch(Diff diff) { + return diff.getRefines().isEmpty() || (diff.getConflict() != null + && !diff.getConflict().getDifferences().containsAll(diff.getRefines())); + } + + @Override + protected void doBuildSubTrees() { + for (Conflict conflict : getComparison().getConflicts()) { + final CompositeConflict compositeConflict = new CompositeConflict(conflict); + compositeConflicts.add(compositeConflict); + joinOverlappingCompositeConflicts(compositeConflict); + updateDiffToCompositeConflictMap(compositeConflict); + } + + for (CompositeConflict conflict : compositeConflicts) { + final ConflictNodeBuilder builder = new ConflictNodeBuilder(conflict, this); + final ConflictNode conflictNode = builder.buildNode(); + children.add(conflictNode); + } + } + + /** + * Joins the given composite conflict with existing overlapping composite conflicts. + * + * @param compositeConflict + * The composite conflict into which overlapping composite conflicts should be joined + */ + private void joinOverlappingCompositeConflicts(final CompositeConflict compositeConflict) { + // determine composite conflicts to join + final Set compositeConflictsToJoin = new HashSet(); + for (Diff diff : compositeConflict.getDifferences()) { + if (diffToCompositeConflictMap.containsKey(diff)) { + compositeConflictsToJoin.add(diffToCompositeConflictMap.get(diff)); + } + } + // join conflict groups + for (CompositeConflict conflictGroupToJoin : compositeConflictsToJoin) { + compositeConflict.join(conflictGroupToJoin); + compositeConflicts.remove(conflictGroupToJoin); + } + } + + /** + * Updates the diff to composite conflict map with the given composite conflict. + * + * @param compositeConflict + * The composite conflict that should be added to the diff to composite conflict map + */ + private void updateDiffToCompositeConflictMap(final CompositeConflict compositeConflict) { + for (Diff diff : compositeConflict.getDifferences()) { + diffToCompositeConflictMap.put(diff, compositeConflict); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl#getStyledName() + */ + @Override + public IComposedStyledString getStyledName() { + final IStyledString.IComposedStyledString ret = new ComposedStyledString(); + Iterator eAllContents = concat(transform(getChildren().iterator(), E_ALL_CONTENTS)); + Iterator eAllData = transform(eAllContents, TREE_NODE_DATA); + UnmodifiableIterator eAllDiffData = filter(eAllData, Diff.class); + Collection diffs = Sets.newHashSet(eAllDiffData); + boolean unresolvedDiffs = any(diffs, and(hasState(DifferenceState.UNRESOLVED), + hasConflict(ConflictKind.REAL, ConflictKind.PSEUDO))); + if (unresolvedDiffs) { + ret.append("> ", Style.DECORATIONS_STYLER); //$NON-NLS-1$ + } + ret.append(getName()); + return ret; + } + + /** + * In the conflicts group, we want to be able to see the ResourceAttachmentChanges. + * + * @param matchNode + * The given match node + * @param diff + * The diff to add + */ + @Override + protected void addDiffNode(MatchNode matchNode, Diff diff) { + DiffNode diffNode = createDiffNode(diff); + handleRefiningDiffs(diffNode); + matchNode.addDiffNode(diffNode); + } + } + + /** + * This extension of {@link Conflict} is used to handle {@link Diff#getRefinedBy() refined} diffs and to + * join conflicts for the SMV. If refining diffs are part of a conflict, we show their refined diffs + * instead. As we show refined diffs instead of the refining diffs, multiple conflicts may consequently + * include the same refined diffs. To avoid that, this extension of a conflict also joins such overlapping + * conflicts. + * + * @author Tanja Mayerhofer + */ + public static class CompositeConflict extends ConflictImpl { + + /** The joined conflicts. */ + private Set conflicts = new LinkedHashSet(); + + /** The diffs of all composed conflicts. */ + private EList diffs = new BasicEList(); + + /** The conflict kind of this composite conflict. */ + private ConflictKind conflictKind = ConflictKind.REAL; + + /** + * Creates a new composite conflict for the given conflict. + * + * @param conflict + * The conflict to create a composite conflict for, must not be null and must + * have a non-null {@link Conflict#getKind() kind}. + */ + public CompositeConflict(Conflict conflict) { + conflicts.add(checkNotNull(conflict)); + conflictKind = checkNotNull(conflict.getKind()); + diffs.addAll(computeRefinedDiffs(conflict)); + } + + /** + * Computes the refined diffs of the conflict. In particular, refining diffs are replaced by refined + * diffs. + * + * @param conflict + * The conflict to compute its refined diffs for. + * @return The set of refined diffs of the conflict + */ + private Set computeRefinedDiffs(Conflict conflict) { + Set computedDiffs = new LinkedHashSet(); + for (Diff diff : conflict.getDifferences()) { + if (diff.getRefines().isEmpty()) { + computedDiffs.add(diff); + } else { + computedDiffs.addAll(getRootRefinedDiffs(diff)); + } + } + return computedDiffs; + } + + @Override + public ConflictKind getKind() { + return conflictKind; + } + + /** + * Returns an EList built by aggregating the diffs of all the aggregated conflicts. + *

+ * This list is not supposed to be used for update, since modifying this list will not modify the + * underlying conflicts. + *

+ */ + @Override + public EList getDifferences() { + return diffs; + } + + /** + * Returns an unmodifiable view of the joined conflicts. + * + * @return An unmodifiable view of the joined conflicts, never null nor empty. + */ + public Set getConflicts() { + return unmodifiableSet(conflicts); + } + + /** + * Joins the provided composite conflict with this composite conflict. + * + * @param conflict + * The conflict to be joined with this composite conflict + */ + public void join(CompositeConflict conflict) { + Set currentDiffSet = new LinkedHashSet(diffs); + Set otherDiffSet = new LinkedHashSet(conflict.getDifferences()); + SetView newDiffs = Sets.difference(otherDiffSet, currentDiffSet); + diffs.addAll(newDiffs); + if (conflicts.addAll(conflict.getConflicts()) && conflictKind != REAL) { + if (any(conflicts, containsConflictOfTypes(REAL))) { + conflictKind = REAL; + } else { + conflictKind = PSEUDO; + } + } + } + } + + @Override + protected Collection buildGroups(Comparison comparison2) { + Adapter adapter = EcoreUtil.getAdapter(getComparison().eAdapters(), SideLabelProvider.class); + + final String leftLabel; + final String rightLabel; + + if (adapter instanceof SideLabelProvider) { + SideLabelProvider labelProvider = (SideLabelProvider)adapter; + leftLabel = labelProvider.getLeftLabel(); + rightLabel = labelProvider.getRightLabel(); + } else { + leftLabel = EMFCompareRCPUIMessages.getString("ThreeWayComparisonGroupProvider.left.label"); //$NON-NLS-1$ + rightLabel = EMFCompareRCPUIMessages.getString("ThreeWayComparisonGroupProvider.right.label"); //$NON-NLS-1$ + } + + final ConflictsGroupImpl conflicts = new ConflictsGroupImpl(getComparison(), + EMFCompareRCPUIMessages.getString("ThreeWayComparisonGroupProvider.conflicts.label"), //$NON-NLS-1$ + getCrossReferenceAdapter()); + conflicts.buildSubTree(); + + final BasicDifferenceGroupImpl leftSide = new BasicDifferenceGroupImpl(getComparison(), + and(fromSide(DifferenceSource.LEFT), DEFAULT_DIFF_GROUP_FILTER_PREDICATE), leftLabel, + getCrossReferenceAdapter()); + leftSide.buildSubTree(); + + final BasicDifferenceGroupImpl rightSide = new BasicDifferenceGroupImpl(getComparison(), + and(fromSide(DifferenceSource.RIGHT), DEFAULT_DIFF_GROUP_FILTER_PREDICATE), rightLabel, + getCrossReferenceAdapter()); + rightSide.buildSubTree(); + + return ImmutableList.of(conflicts, leftSide, rightSide); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/GroupItemProviderAdapter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/GroupItemProviderAdapter.java new file mode 100644 index 000000000..5cdde49a8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/GroupItemProviderAdapter.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.provider; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.provider.EMFCompareEditPlugin; +import org.eclipse.emf.compare.provider.IItemDescriptionProvider; +import org.eclipse.emf.compare.provider.IItemStyledLabelProvider; +import org.eclipse.emf.compare.provider.spec.OverlayImageProvider; +import org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.provider.IEditingDomainItemProvider; +import org.eclipse.emf.edit.provider.IItemColorProvider; +import org.eclipse.emf.edit.provider.IItemFontProvider; +import org.eclipse.emf.edit.provider.IItemLabelProvider; +import org.eclipse.emf.edit.provider.IItemPropertySource; +import org.eclipse.emf.edit.provider.ITreeItemContentProvider; +import org.eclipse.emf.edit.provider.ItemProviderAdapter; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * An specific {@link ItemProviderAdapter} for groups. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class GroupItemProviderAdapter extends ItemProviderAdapter implements IEditingDomainItemProvider, ITreeItemContentProvider, IItemLabelProvider, IItemPropertySource, IItemColorProvider, IItemFontProvider, IItemStyledLabelProvider, IItemDescriptionProvider { + + /** The parent object. */ + private EObject parent; + + /** The group for which we want the item provider. */ + private IDifferenceGroup group; + + /** The overlay provider for the group. */ + private OverlayImageProvider overlayProvider; + + /** + * Constructor. + * + * @param adapterFactory + * the {@link AdapterFactory} needed to create the GroupItemProviderAdapter. + * @param parent + * the parent object of the group. + * @param group + * the IDifferenceGroup that will be used as item provider. + */ + public GroupItemProviderAdapter(AdapterFactory adapterFactory, EObject parent, IDifferenceGroup group) { + super(adapterFactory); + this.parent = parent; + this.group = group; + this.overlayProvider = new OverlayImageProvider(EMFCompareEditPlugin.INSTANCE); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.provider.IItemDescriptionProvider#getDescription(java.lang.Object) + */ + public String getDescription(Object object) { + return group.getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getImage(java.lang.Object) + */ + @Override + public Object getImage(Object object) { + return overlayProvider.getComposedImage(object, group.getImage()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getText(java.lang.Object) + */ + @Override + public String getText(Object object) { + return group.getName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object) + */ + @Override + public IComposedStyledString getStyledText(Object object) { + return group.getStyledName(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getParent(java.lang.Object) + */ + @Override + public Object getParent(Object object) { + return parent; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#hasChildren(java.lang.Object) + */ + @Override + public boolean hasChildren(Object object) { + return !group.getChildren().isEmpty(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object) + */ + @Override + public Collection getChildren(Object object) { + List children = group.getChildren(); + for (TreeNode child : children) { + Adapter groupItemProvider = EcoreUtil.getExistingAdapter(child, GroupItemProviderAdapter.class); + if (groupItemProvider == null) { + // store the parent for later retrieval + child.eAdapters().add(this); + } + } + return children; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#isAdapterForType(java.lang.Object) + */ + @Override + public boolean isAdapterForType(Object type) { + return type == GroupItemProviderAdapter.class; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeItemProviderAdapterFactorySpec.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeItemProviderAdapterFactorySpec.java new file mode 100644 index 000000000..a66d0258c --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeItemProviderAdapterFactorySpec.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2013, 2015 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.structuremergeviewer.groups.provider; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.provider.IItemDescriptionProvider; +import org.eclipse.emf.compare.provider.IItemStyledLabelProvider; +import org.eclipse.emf.compare.provider.ISemanticObjectLabelProvider; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter; +import org.eclipse.emf.edit.provider.IItemColorProvider; +import org.eclipse.emf.edit.provider.IItemFontProvider; +import org.eclipse.emf.edit.tree.provider.TreeItemProviderAdapterFactory; + +/** + * A specific implementation of {@link org.eclipse.emf.edit.tree.provider.TreeItemProviderAdapterFactory}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class TreeItemProviderAdapterFactorySpec extends TreeItemProviderAdapterFactory { + + /** An instance of {@code StructureMergeViewerFilter}. */ + private final StructureMergeViewerFilter filter; + + /** + * Constructor. + * + * @param filter + * The given StructureMergeViewerFilter + */ + public TreeItemProviderAdapterFactorySpec(StructureMergeViewerFilter filter) { + super(); + this.filter = filter; + supportedTypes.add(IItemFontProvider.class); + supportedTypes.add(IItemColorProvider.class); + supportedTypes.add(IItemStyledLabelProvider.class); + supportedTypes.add(IItemDescriptionProvider.class); + supportedTypes.add(ISemanticObjectLabelProvider.class); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.tree.provider.TreeItemProviderAdapterFactory#createTreeNodeAdapter() + */ + @Override + public Adapter createTreeNodeAdapter() { + return new TreeNodeItemProviderSpec(this, filter); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeNodeItemProviderSpec.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeNodeItemProviderSpec.java new file mode 100644 index 000000000..74d746f4b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/provider/TreeNodeItemProviderSpec.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * Copyright (c) 2013, 2015 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.structuremergeviewer.groups.provider; + +import static com.google.common.collect.Iterators.any; +import static com.google.common.collect.Iterators.filter; +import static com.google.common.collect.Iterators.transform; +import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState; + +import com.google.common.base.Predicate; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import com.google.common.collect.UnmodifiableIterator; + +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Conflict; +import org.eclipse.emf.compare.ConflictKind; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.DifferenceState; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.internal.EMFCompareEditMessages; +import org.eclipse.emf.compare.provider.ExtendedAdapterFactoryItemDelegator; +import org.eclipse.emf.compare.provider.IItemStyledLabelProvider; +import org.eclipse.emf.compare.provider.utils.ComposedStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString; +import org.eclipse.emf.compare.provider.utils.IStyledString.Style; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.edit.provider.IItemColorProvider; +import org.eclipse.emf.edit.provider.IItemFontProvider; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.emf.edit.tree.provider.TreeNodeItemProvider; + +/** + * A specific implementation of {@link TreeNodeItemProvider}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public class TreeNodeItemProviderSpec extends TreeNodeItemProvider implements IItemStyledLabelProvider, IItemColorProvider, IItemFontProvider { + + /** A map of IDifferenceGroupProvider, GroupItemProviderAdapter. */ + private Multimap groupItemProviderAdapters; + + /** An instance of {@code StructureMergeViewerFilter}. */ + private StructureMergeViewerFilter structureMergeViewerFilter; + + /** + * This constructs an instance from a factory. + * + * @param adapterFactory + * the given factory + * @param structureMergeViewerFilter + * the given structure merge viewer filter + */ + public TreeNodeItemProviderSpec(AdapterFactory adapterFactory, + StructureMergeViewerFilter structureMergeViewerFilter) { + super(adapterFactory); + this.structureMergeViewerFilter = structureMergeViewerFilter; + itemDelegator = new ExtendedAdapterFactoryItemDelegator(getRootAdapterFactory()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.tree.provider.TreeNodeItemProvider#getParent(java.lang.Object) + */ + @Override + public Object getParent(Object object) { + Object parent = null; + TreeNode treeNode = (TreeNode)object; + TreeNode superParent = (TreeNode)super.getParent(object); + if (superParent == null) { + GroupItemProviderAdapter groupItemProvider = (GroupItemProviderAdapter)EcoreUtil + .getExistingAdapter(treeNode, GroupItemProviderAdapter.class); + return groupItemProvider; + } else if (object instanceof GroupItemProviderAdapter) { + parent = ((GroupItemProviderAdapter)object).getParent(null); + } else { + parent = superParent; + } + return parent; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object) + */ + @Override + public Collection getChildren(Object object) { + TreeNode treeNode = (TreeNode)object; + EObject data = treeNode.getData(); + if (data instanceof Comparison) { + IDifferenceGroupProvider groupProvider = (IDifferenceGroupProvider)EcoreUtil + .getExistingAdapter(treeNode, IDifferenceGroupProvider.class); + if (groupProvider == null) { + return ImmutableList.of(); + } + Comparison comparison = (Comparison)data; + Collection groups = groupProvider.getGroups(comparison); + if (groups.isEmpty()) { + return ImmutableList.of(); + } else if (groups.size() == 1) { + // do not display group if there is only one. + return groups.iterator().next().getChildren(); + } else { + if (groupItemProviderAdapters == null) { + groupItemProviderAdapters = ArrayListMultimap.create(); + initMapping(groups, groupProvider, treeNode); + return groupItemProviderAdapters.get(groupProvider); + } else { + Collection adapters = groupItemProviderAdapters + .get(groupProvider); + if (adapters.isEmpty()) { + initMapping(groups, groupProvider, treeNode); + } + return adapters; + } + } + } else { + return super.getChildren(object); + } + } + + /** + * Init the mapping. + * + * @param groups + * the list of IDifferenceGroup to map with {@link GroupItemProviderAdapter}s. + * @param groupProvider + * the IDifferenceGroupProvider used to create a {@link GroupItemProviderAdapter}. + * @param treeNode + * the TreeNode used to create a {@link GroupItemProviderAdapter}. + */ + protected void initMapping(Collection groups, + IDifferenceGroupProvider groupProvider, TreeNode treeNode) { + for (IDifferenceGroup differenceGroup : groups) { + groupItemProviderAdapters.put(groupProvider, + new GroupItemProviderAdapter(adapterFactory, treeNode, differenceGroup)); + } + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object) + */ + @Override + public IComposedStyledString getStyledText(Object object) { + TreeNode treeNode = (TreeNode)object; + EObject data = treeNode.getData(); + ComposedStyledString styledString = new ComposedStyledString(); + final IComposedStyledString treeNodeText; + if (data instanceof Match) { + Iterator eAllContents = transform(treeNode.eAllContents(), + IDifferenceGroup.TREE_NODE_DATA); + Iterator allDifferences = filter(eAllContents, Diff.class); + if (any(allDifferences, hasState(DifferenceState.UNRESOLVED))) { + styledString.append("> ", Style.DECORATIONS_STYLER); //$NON-NLS-1$ + } + treeNodeText = ((ExtendedAdapterFactoryItemDelegator)itemDelegator) + .getStyledText(treeNode.getData()); + } else if (data instanceof Conflict) { + treeNodeText = getTreeNodeText(treeNode, (Conflict)data); + } else { + treeNodeText = ((ExtendedAdapterFactoryItemDelegator)itemDelegator) + .getStyledText(treeNode.getData()); + } + return styledString.append(treeNodeText); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getBackground(java.lang.Object) + */ + @Override + public Object getBackground(Object object) { + TreeNode treeNode = (TreeNode)object; + return itemDelegator.getBackground(treeNode.getData()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getForeground(java.lang.Object) + */ + @Override + public Object getForeground(Object object) { + TreeNode treeNode = (TreeNode)object; + return itemDelegator.getForeground(treeNode.getData()); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getBackground(java.lang.Object, int) + */ + @Override + public Object getBackground(Object object, int columnIndex) { + TreeNode treeNode = (TreeNode)object; + return itemDelegator.getBackground(treeNode.getData(), columnIndex); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getForeground(java.lang.Object, int) + */ + @Override + public Object getForeground(Object object, int columnIndex) { + TreeNode treeNode = (TreeNode)object; + return itemDelegator.getForeground(treeNode.getData(), columnIndex); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getFont(java.lang.Object) + */ + @Override + public Object getFont(Object object) { + TreeNode treeNode = (TreeNode)object; + return itemDelegator.getFont(treeNode.getData()); + } + + @Override + public void dispose() { + super.dispose(); + if (groupItemProviderAdapters != null) { + groupItemProviderAdapters.clear(); + } + } + + /** + * Due to filters (especially UML & Diagram Refined elements filters), refining & refined elements are + * store in the same conflicts. But refining & refined elements will never be displayed together. It leads + * to have a number of unresolved diffs that is confusing because it counts refining & refined unresolved + * diffs together. This method makes sure to only count visible unresolved nodes. + * + * @param conflict + * the conflict for which we want to get the text to display. + * @return the styled string. + */ + private IComposedStyledString getTreeNodeText(TreeNode treeNode, Conflict conflict) { + final ComposedStyledString ret = new ComposedStyledString(); + + Assert.isNotNull(structureMergeViewerFilter); + final Predicate unfilteredNode = structureMergeViewerFilter.getAggregatedPredicate(); + + final UnmodifiableIterator visibleNodes = Iterators.filter(treeNode.eAllContents(), + unfilteredNode); + + final Iterator eAllContents = transform(visibleNodes, IDifferenceGroup.TREE_NODE_DATA); + final Iterator allDifferences = filter(eAllContents, Diff.class); + final Collection d = Sets.newHashSet(allDifferences); + final int unresolvedDiffCount = Iterables + .size(Iterables.filter(d, hasState(DifferenceState.UNRESOLVED))); + + if (unresolvedDiffCount > 0) { + ret.append("> ", Style.DECORATIONS_STYLER); //$NON-NLS-1$ + } + + if (conflict.getKind() == ConflictKind.PSEUDO) { + ret.append(EMFCompareEditMessages.getString("pseudoconflict")); //$NON-NLS-1$ + } else { + ret.append(EMFCompareEditMessages.getString("conflict")); //$NON-NLS-1$ + } + + if (unresolvedDiffCount > 0) { + ret.append( + " [" //$NON-NLS-1$ + + EMFCompareEditMessages.getString("unresolved", //$NON-NLS-1$ + Integer.valueOf(unresolvedDiffCount), Integer.valueOf(d.size())) + + "]", //$NON-NLS-1$ + Style.DECORATIONS_STYLER); + } else { + ret.append(" [" + EMFCompareEditMessages.getString("resolved") + "]", Style.DECORATIONS_STYLER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + return ret; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/match/MatchOfContainmentReferenceChangeProcessor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/match/MatchOfContainmentReferenceChangeProcessor.java new file mode 100644 index 000000000..aa10b10ee --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/match/MatchOfContainmentReferenceChangeProcessor.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.match; + +import java.util.Iterator; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.match.MatchOfContainmentReferenceChangeAdapter; +import org.eclipse.emf.compare.utils.EMFComparePredicates; + +/** + * Process a comparison to detect {@link Match}es related to containment ReferenceChange. Add a + * {@link MatchOfContainmentReferenceChangeAdapter} on such Matches. + * + * @author Axel Richard + */ +public class MatchOfContainmentReferenceChangeProcessor { + /** + * Check for the given {@link Comparison}, if {@link Match}es are related to a containment + * ReferenceChange. If it is add a {@link MatchOfContainmentReferenceChangeAdapter} to these + * {@link Match}es. + * + * @param comp + * The {@link Comparison} to check. + */ + public void execute(Comparison comp) { + for (Diff diff : comp.getDifferences()) { + if (EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE.apply(diff)) { + Match match = comp.getMatch(((ReferenceChange)diff).getValue()); + boolean hasAdapter = false; + Iterator adapters = match.eAdapters().iterator(); + while (!hasAdapter && adapters.hasNext()) { + Adapter next = adapters.next(); + hasAdapter = next instanceof MatchOfContainmentReferenceChangeAdapter + && ((MatchOfContainmentReferenceChangeAdapter)next).getReferenceChange() == diff; + } + if (!hasAdapter) { + match.eAdapters() + .add(new MatchOfContainmentReferenceChangeAdapter((ReferenceChange)diff)); + } + } + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/ConflictNode.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/ConflictNode.java new file mode 100644 index 000000000..dccb81461 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/ConflictNode.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.nodes; + +import com.google.common.collect.Iterables; + +import org.eclipse.emf.compare.Conflict; + +/** + * This class is wrapper for TreeNode used to represent a conflict TreeNode. + * + * @author Mathieu Cartaud + * @since 4.3 + */ +public class ConflictNode extends TreeNodeImpl { + + /** + * Constructor. + * + * @param conflict + * The conflict represented by this TreeNode + */ + public ConflictNode(Conflict conflict) { + setData(conflict); + } + + /** + * Add the given MatchNode to the children of this ConflictNode. + * + * @param matchNode + * The MatchNode to add + * @return true if the MatchNode has been added + */ + public boolean addConflictingTree(MatchNode matchNode) { + return getChildren().add(matchNode); + } + + /** + * Remove the given MatchNode of the children of this ConflictNode. + * + * @param matchNode + * The MatchNode to remove + * @return true if the MatchNode has been removed + */ + public boolean removeConflictingTree(MatchNode matchNode) { + return getChildren().remove(matchNode); + } + + /** + * Getter for the conflict represented by this TreeNode. + * + * @return the conflict + */ + public Conflict getConflict() { + return (Conflict)getData(); + } + + /** + * Get all the match trees that are part of the conflict + * + * @return an iterable of all MatchNode that are part of the conflict + */ + public Iterable getConflictingTrees() { + return Iterables.filter(getChildren(), MatchNode.class); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/DiffNode.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/DiffNode.java new file mode 100644 index 000000000..f3b393b79 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/DiffNode.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.nodes; + +import com.google.common.collect.Iterables; + +import org.eclipse.emf.compare.Diff; + +/** + * This class is wrapper for TreeNode used to represent a diff TreeNode. + * + * @author Mathieu Cartaud + * @since 4.3 + */ +public class DiffNode extends TreeNodeImpl { + + /** + * Constructor. + * + * @param diff + * The diff represented by this TreeNode + */ + public DiffNode(Diff diff) { + setData(diff); + } + + /** + * Add the given DiffNode to the children of this DiffNode. This is intended to be used only for refined + * diffs. + * + * @param diffNode + * The DiffNode to add + * @return true if the DiffNode has been added + */ + public boolean addRefinedDiffNode(DiffNode diffNode) { + return getChildren().add(diffNode); + } + + /** + * Remove the given DiffNode of the children of this DiffNode. This is intended to be used only for + * refined diffs. + * + * @param diffNode + * The DiffNode to remove + * @return true if the DiffNode has been removed + */ + public boolean removeRefinedDiffNode(DiffNode diffNode) { + return getChildren().remove(diffNode); + } + + /** + * Getter for the diff represented by this TreeNode. + * + * @return the diff + */ + public Diff getDiff() { + return (Diff)getData(); + } + + /** + * Get all the refined DiffNode that are part of this DiffNode. + * + * @return an iterable of all refined DiffNode of this diff + */ + public Iterable getRefinedDiffs() { + return Iterables.filter(getChildren(), DiffNode.class); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchNode.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchNode.java new file mode 100644 index 000000000..686aeaac8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchNode.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.nodes; + +import com.google.common.collect.Iterables; + +import org.eclipse.emf.compare.Match; + +/** + * This class is wrapper for TreeNode used to represent a match TreeNode. + * + * @author Mathieu Cartaud + * @since 4.3 + */ +public class MatchNode extends TreeNodeImpl { + + /** + * Constructor. + * + * @param match + * The match represented by this TreeNode + */ + public MatchNode(Match match) { + setData(match); + } + + /** + * Add the given MatchNode to the children of this MatchNode. + * + * @param matchNode + * The MatchNode to add + * @return true if the MatchNode has been added + */ + public boolean addSubMatchNode(MatchNode matchNode) { + return getChildren().add(matchNode); + } + + /** + * Add the given DiffNode to the children of this MatchNode. + * + * @param diffNode + * The DiffNode to add + * @return true if the DiffNode has been added + */ + public boolean addDiffNode(DiffNode diffNode) { + return getChildren().add(diffNode); + } + + /** + * Remove the given MatchNode of the children of this MatchNode. + * + * @param matchNode + * The MatchNode to remove + * @return true if the MatchNode has been removed + */ + public boolean removeSubMatchNode(MatchNode matchNode) { + return getChildren().remove(matchNode); + } + + /** + * Remove the given DiffNode of the children of this MatchNode. + * + * @param diffNode + * The DiffNode to remove + * @return true if the DiffNode has been removed + */ + public boolean removeDiffNode(DiffNode diffNode) { + return getChildren().remove(diffNode); + } + + /** + * Getter for the match represented by this TreeNode. + * + * @return the match + */ + public Match getMatch() { + return (Match)getData(); + } + + /** + * Get all the match trees that are submatches of the match + * + * @return an iterable of all submatches + */ + public Iterable getSubMatchNodes() { + return Iterables.filter(getChildren(), MatchNode.class); + } + + /** + * Get all the diffs that are part of the match + * + * @return an iterable of all directly contained diffs + */ + public Iterable getDiffNodes() { + return Iterables.filter(getChildren(), DiffNode.class); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchResourceNode.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchResourceNode.java new file mode 100644 index 000000000..54d39554c --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/MatchResourceNode.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.nodes; + +import com.google.common.collect.Iterables; + +import org.eclipse.emf.compare.MatchResource; + +/** + * This class is wrapper for TreeNode used to represent a match resource TreeNode. + * + * @author Mathieu Cartaud + * @since 4.3 + */ +public class MatchResourceNode extends TreeNodeImpl { + + /** + * Constructor. + * + * @param matchResource + * The matchResource represented by this TreeNode + */ + public MatchResourceNode(MatchResource matchResource) { + setData(matchResource); + } + + /** + * Add the given DiffNode to the direct children of this MatchResourceNode. + * + * @param diffNode + * The DiffNode to add + * @return true if the MatchNode has been added + */ + public boolean addDiffNode(DiffNode diffNode) { + return getChildren().add(diffNode); + } + + /** + * Add the given MatchNode to the children of this MatchResourceNode. + * + * @param matchNode + * The MatchNode to add + * @return true if the MatchNode has been added + */ + public boolean addMatchNode(MatchNode matchNode) { + return getChildren().add(matchNode); + } + + /** + * Remove the given DiffNode of the direct children of this MatchResourceNode. + * + * @param diffNode + * The DiffNode to remove + * @return true if the DiffNode has been removed + */ + public boolean removeDiffNode(DiffNode diffNode) { + return getChildren().remove(diffNode); + } + + /** + * Remove the given MatchNode of the children of this MatchResourceNode. + * + * @param matchNode + * The MatchNode to remove + * @return true if the MatchNode has been removed + */ + public boolean removeMatchNode(MatchNode matchNode) { + return getChildren().remove(matchNode); + } + + /** + * Getter for the match resource represented by this TreeNode. + * + * @return the matchResource + */ + public MatchResource getMatchResource() { + return (MatchResource)getData(); + } + + /** + * Get all the match trees that are part of the MatchResource + * + * @return an iterable of all MatchNode that are part of the MatchResource + */ + public Iterable getMatches() { + return Iterables.filter(getChildren(), MatchNode.class); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/TreeNodeImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/TreeNodeImpl.java new file mode 100644 index 000000000..8bc8f2386 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/nodes/TreeNodeImpl.java @@ -0,0 +1,327 @@ +/** + * Copyright (c) 2002-2006 IBM Corporation and others. + * 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: + * IBM - Initial API and implementation + */ +package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.MinimalEObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.emf.edit.tree.TreePackage; + +/** + * An implementation of the model object 'Node'. + *

+ * The following features are implemented: + *

+ *
    + *
  • {@link org.eclipse.emf.edit.tree.impl.TreeNodeImpl#getParent Parent}
  • + *
  • {@link org.eclipse.emf.edit.tree.impl.TreeNodeImpl#getChildren Children}
  • + *
  • {@link org.eclipse.emf.edit.tree.impl.TreeNodeImpl#getData Data}
  • + *
+ *

+ * This class is an exact copy of org.eclipse.emf.edit.tree.impl.TreeNodeImpl, but inherits from + * MinimalEObjectImpl.Container instead of from EObjectImpl to improve efficiency in memory consumtion. + *

+ * + * @generated + */ +public class TreeNodeImpl extends MinimalEObjectImpl.Container implements TreeNode { + /** + * The cached value of the '{@link #getChildren() Children}' containment reference list. + * + * @see #getChildren() + * @generated + * @ordered + */ + protected EList children; + + /** + * The cached value of the '{@link #getData() Data}' reference. + * + * @see #getData() + * @generated + * @ordered + */ + protected EObject data; + + /** + * + * + * @generated modifiable + */ + protected TreeNodeImpl() { + super(); + } + + /** + * + * + * @generated + */ + @Override + protected EClass eStaticClass() { + return TreePackage.Literals.TREE_NODE; + } + + /** + * + * + * @generated + */ + public TreeNode getParent() { + if (eContainerFeatureID() != TreePackage.TREE_NODE__PARENT) { + return null; + } + return (TreeNode)eInternalContainer(); + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetParent(TreeNode newParent, NotificationChain msgs) { + msgs = eBasicSetContainer((InternalEObject)newParent, TreePackage.TREE_NODE__PARENT, msgs); + return msgs; + } + + /** + * + * + * @generated + */ + public void setParent(TreeNode newParent) { + if (newParent != eInternalContainer() + || (eContainerFeatureID() != TreePackage.TREE_NODE__PARENT && newParent != null)) { + if (EcoreUtil.isAncestor(this, newParent)) { + throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); + } + NotificationChain msgs = null; + if (eInternalContainer() != null) { + msgs = eBasicRemoveFromContainer(msgs); + } + if (newParent != null) { + msgs = ((InternalEObject)newParent).eInverseAdd(this, TreePackage.TREE_NODE__CHILDREN, + TreeNode.class, msgs); + } + msgs = basicSetParent(newParent, msgs); + if (msgs != null) { + msgs.dispatch(); + } + } else if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.SET, TreePackage.TREE_NODE__PARENT, newParent, + newParent)); + } + } + + /** + * + * + * @generated + */ + public EList getChildren() { + if (children == null) { + children = new EObjectContainmentWithInverseEList(TreeNode.class, this, + TreePackage.TREE_NODE__CHILDREN, TreePackage.TREE_NODE__PARENT); + } + return children; + } + + /** + * + * + * @generated + */ + public EObject getData() { + if (data != null && data.eIsProxy()) { + InternalEObject oldData = (InternalEObject)data; + data = eResolveProxy(oldData); + if (data != oldData) { + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.RESOLVE, TreePackage.TREE_NODE__DATA, + oldData, data)); + } + } + } + return data; + } + + /** + * + * + * @generated + */ + public EObject basicGetData() { + return data; + } + + /** + * + * + * @generated + */ + public void setData(EObject newData) { + EObject oldData = data; + data = newData; + if (eNotificationRequired()) { + eNotify(new ENotificationImpl(this, Notification.SET, TreePackage.TREE_NODE__DATA, oldData, + data)); + } + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + if (eInternalContainer() != null) { + msgs = eBasicRemoveFromContainer(msgs); + } + return basicSetParent((TreeNode)otherEnd, msgs); + case TreePackage.TREE_NODE__CHILDREN: + return ((InternalEList)(InternalEList)getChildren()).basicAdd(otherEnd, + msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + return basicSetParent(null, msgs); + case TreePackage.TREE_NODE__CHILDREN: + return ((InternalEList)getChildren()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + @Override + public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) { + switch (eContainerFeatureID()) { + case TreePackage.TREE_NODE__PARENT: + return eInternalContainer().eInverseRemove(this, TreePackage.TREE_NODE__CHILDREN, + TreeNode.class, msgs); + } + return super.eBasicRemoveFromContainerFeature(msgs); + } + + /** + * + * + * @generated + */ + @Override + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + return getParent(); + case TreePackage.TREE_NODE__CHILDREN: + return getChildren(); + case TreePackage.TREE_NODE__DATA: + if (resolve) { + return getData(); + } + return basicGetData(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + setParent((TreeNode)newValue); + return; + case TreePackage.TREE_NODE__CHILDREN: + getChildren().clear(); + getChildren().addAll((Collection)newValue); + return; + case TreePackage.TREE_NODE__DATA: + setData((EObject)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + setParent((TreeNode)null); + return; + case TreePackage.TREE_NODE__CHILDREN: + getChildren().clear(); + return; + case TreePackage.TREE_NODE__DATA: + setData((EObject)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case TreePackage.TREE_NODE__PARENT: + return getParent() != null; + case TreePackage.TREE_NODE__CHILDREN: + return children != null && !children.isEmpty(); + case TreePackage.TREE_NODE__DATA: + return data != null; + } + return super.eIsSet(featureID); + } + +} // TreeNodeImpl diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/MergeViewerUtil.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/MergeViewerUtil.java new file mode 100644 index 000000000..7e7060aa7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/MergeViewerUtil.java @@ -0,0 +1,447 @@ +/******************************************************************************* + * Copyright (c) 2012, 2017 Obeo and others. + * 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.util; + +import static com.google.common.collect.Iterables.any; +import static org.eclipse.emf.compare.merge.AbstractMerger.isInTerminalState; + +import com.google.common.base.Predicate; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.AttributeChange; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.FeatureMapChange; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.MatchResource; +import org.eclipse.emf.compare.ReferenceChange; +import org.eclipse.emf.compare.ResourceAttachmentChange; +import org.eclipse.emf.compare.internal.merge.IMergeData; +import org.eclipse.emf.compare.internal.merge.MergeMode; +import org.eclipse.emf.compare.internal.merge.MergeOperation; +import org.eclipse.emf.compare.rcp.ui.internal.configuration.IEMFCompareConfiguration; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.utils.IEqualityHelper; +import org.eclipse.emf.compare.utils.ReferenceUtil; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.FeatureMap; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * @author Mikael Barbero + */ +public final class MergeViewerUtil { + + private MergeViewerUtil() { + } + + public static List getValues(Diff diff, MergeViewerSide side) { + Match ownerMatch = diff.getMatch(); + EObject eObject = getEObject(ownerMatch, side); + EStructuralFeature affectedFeature = getAffectedFeature(diff); + return ReferenceUtil.getAsList(eObject, affectedFeature); + } + + public static List getFeatureValues(Match match, EStructuralFeature feature, MergeViewerSide side) { + final EObject eObject = getEObject(match, side); + return ReferenceUtil.getAsList(eObject, feature); + } + + public static EObject getEObject(Match match, MergeViewerSide side) { + final EObject eObject; + switch (side) { + case ANCESTOR: + eObject = match.getOrigin(); + break; + case LEFT: + eObject = match.getLeft(); + break; + case RIGHT: + eObject = match.getRight(); + break; + default: + throw new IllegalStateException(); + } + return eObject; + } + + public static EObject getBestSideEObject(Match match, MergeViewerSide side) { + final MergeViewerSide[] sideLookupOrder; + if (side == MergeViewerSide.ANCESTOR) { + sideLookupOrder = new MergeViewerSide[] {MergeViewerSide.ANCESTOR, MergeViewerSide.LEFT, + MergeViewerSide.RIGHT, }; + } else { + sideLookupOrder = new MergeViewerSide[] {side, side.opposite(), MergeViewerSide.ANCESTOR, }; + } + + EObject objectOnSide = null; + for (int i = 0; i < sideLookupOrder.length && objectOnSide == null; i++) { + objectOnSide = MergeViewerUtil.getEObject(match, sideLookupOrder[i]); + } + return objectOnSide; + } + + public static EStructuralFeature getAffectedFeature(Diff diff) { + final EStructuralFeature feature; + if (diff instanceof ReferenceChange) { + feature = ((ReferenceChange)diff).getReference(); + } else if (diff instanceof AttributeChange) { + feature = ((AttributeChange)diff).getAttribute(); + } else if (diff instanceof FeatureMapChange) { + feature = ((FeatureMapChange)diff).getAttribute(); + } else { + feature = null; + } + return feature; + } + + /** + * Returns either {@link ReferenceChange#getValue()}, {@link AttributeChange#getValue()} or a + * {@link FeatureMapChange#getValue()} depending on the runtime type of the give {@code diff} or null + * otherwise. + * + * @param diff + * @return + */ + public static Object getDiffValue(Diff diff) { + final Object ret; + if (diff instanceof ReferenceChange) { + ret = ((ReferenceChange)diff).getValue(); + } else if (diff instanceof AttributeChange) { + ret = ((AttributeChange)diff).getValue(); + } else if (diff instanceof FeatureMapChange) { + Object entry = ((FeatureMapChange)diff).getValue(); + if (entry instanceof FeatureMap.Entry) { + ret = ((FeatureMap.Entry)entry).getValue(); + } else { + ret = null; + } + } else { + ret = null; + } + return ret; + } + + public static Object getValueFromDiff(final Diff diff, MergeViewerSide side) { + Object diffValue = getDiffValue(diff); + EStructuralFeature feature = getAffectedFeature(diff); + Match ownerMatch = diff.getMatch(); + Object ret = matchingValue(diffValue, ownerMatch, feature, side, ownerMatch.getComparison()); + return ret; + } + + private static Object matchingValue(Object object, Match ownerMatch, EStructuralFeature feature, + MergeViewerSide side, Comparison comparison) { + final Object ret; + if (object instanceof EObject) { + final Match matchOfValue = comparison.getMatch((EObject)object); + if (matchOfValue != null) { + ret = getEObject(matchOfValue, side); + } else { + ret = matchingValue(object, getFeatureValues(ownerMatch, feature, side), comparison); + } + } else { + ret = matchingValue(object, getFeatureValues(ownerMatch, feature, side), comparison); + } + return ret; + } + + private static Object matchingValue(Object value, List in, Comparison comparison) { + Object ret = null; + IEqualityHelper equalityHelper = comparison.getEqualityHelper(); + Iterator valuesIterator = in.iterator(); + while (valuesIterator.hasNext() && ret == null) { + Object object = valuesIterator.next(); + if (equalityHelper.matchingValues(object, value)) { + ret = object; + } + } + return ret; + } + + /** + * Returns the current resource on the given side of the given comparison. + * + * @param comparison + * The given comparison. + * @param side + * The given side. + * @param diff + * The given diff (a {@link ResourceAttachmentChange}. + * @return The current resource on the given side of the given comparison. + */ + public static Resource getResource(Comparison comparison, MergeViewerSide side, Diff diff) { + if (!(diff instanceof ResourceAttachmentChange)) { + return null; + } + Resource resource = getResourceViaMatch(side, (ResourceAttachmentChange)diff); + + if (resource == null) { + resource = getResourceViaMatchResource(comparison, side, (ResourceAttachmentChange)diff); + } + + return resource; + } + + /** + * Returns the current resource on the given side of the given {@link ResourceAttachmentChange}. The + * resource is obtained via the match of the given {@link ResourceAttachmentChange}. + * + * @param side + * The given side. + * @param diff + * The given {@link ResourceAttachmentChange}. + * @return The current resource on the given side of the given comparison. + */ + private static Resource getResourceViaMatch(MergeViewerSide side, ResourceAttachmentChange diff) { + Resource resource = null; + final Match match = diff.getMatch(); + switch (side) { + case ANCESTOR: + EObject origin = match.getOrigin(); + if (origin == null) { + return null; + } + resource = ((InternalEObject)origin).eDirectResource(); + break; + case LEFT: + EObject left = match.getLeft(); + if (left == null) { + return null; + } + resource = ((InternalEObject)left).eDirectResource(); + break; + case RIGHT: + EObject right = match.getRight(); + if (right == null) { + return null; + } + resource = ((InternalEObject)right).eDirectResource(); + break; + default: + throw new IllegalStateException(); + } + + return resource; + } + + /** + * Returns the current resource on the given side of the given {@link ResourceAttachmentChange}. The + * resource is obtained via the {@link MatchResource} that corresponds to the URI of the given + * {@link ResourceAttachmentChange}. + * + * @param comparison + * The given comparison. + * @param side + * The given side. + * @param diff + * The given {@link ResourceAttachmentChange}. + * @return The current resource on the given side of the given comparison. + */ + private static Resource getResourceViaMatchResource(Comparison comparison, MergeViewerSide side, + ResourceAttachmentChange diff) { + Resource resource = null; + Collection matchResources = comparison.getMatchedResources(); + String diffResourceURI = diff.getResourceURI(); + + for (MatchResource matchResource : matchResources) { + switch (side) { + case ANCESTOR: + resource = matchResource.getOrigin(); + break; + case LEFT: + resource = matchResource.getLeft(); + break; + case RIGHT: + resource = matchResource.getRight(); + break; + default: + throw new IllegalStateException(); + } + if (resource != null && diffResourceURI != null) { + URI resourceURI = resource.getURI(); + if (diffResourceURI.equals(resourceURI.toString())) { + return resource; + } else if (side == MergeViewerSide.RIGHT + && (diffResourceURI.equals(matchResource.getLeftURI()) + || diffResourceURI.equals(matchResource.getOriginURI()))) { + return resource; + } else if (side == MergeViewerSide.LEFT + && (diffResourceURI.equals(matchResource.getRightURI()) + || diffResourceURI.equals(matchResource.getOriginURI()))) { + return resource; + } else if (side == MergeViewerSide.ANCESTOR + && (diffResourceURI.equals(matchResource.getLeftURI()) + || diffResourceURI.equals(matchResource.getRightURI()))) { + return resource; + } + } + } + return resource; + } + + /** + * Returns the contents of the current resource on the given side of the given comparison. + * + * @param comparison + * The given comparison. + * @param side + * The given side. + * @return The contents of the current resource on the given side of the given comparison. + */ + public static List getResourceContents(Comparison comparison, MergeViewerSide side, Diff diff) { + Resource resource = getResource(comparison, side, diff); + if (resource != null) { + return resource.getContents(); + } + return Collections.emptyList(); + + } + + /** + * @param diff + * @param side + * @return + */ + public static Object getResourceAttachmentChangeValue(ResourceAttachmentChange diff, + MergeViewerSide side) { + final Object ret; + Match match = diff.getMatch(); + switch (side) { + case ANCESTOR: + ret = match.getOrigin(); + break; + case LEFT: + ret = match.getLeft(); + break; + case RIGHT: + ret = match.getRight(); + break; + default: + throw new IllegalStateException(); + } + return ret; + } + + public static Object getValueFromResourceAttachmentChange(final ResourceAttachmentChange diff, + Comparison comparison, MergeViewerSide side) { + Object diffValue = getResourceAttachmentChangeValue(diff, side); + Object ret = matchingValue(diffValue, comparison, side); + return ret; + } + + public static Object matchingValue(Object object, Comparison comparison, MergeViewerSide side) { + final Object ret; + if (object instanceof EObject) { + final Match matchOfValue = comparison.getMatch((EObject)object); + if (matchOfValue != null) { + switch (side) { + case ANCESTOR: + ret = matchOfValue.getOrigin(); + break; + case LEFT: + ret = matchOfValue.getLeft(); + break; + case RIGHT: + ret = matchOfValue.getRight(); + break; + default: + throw new IllegalStateException(); + } + } else { + ret = matchingValue(object, comparison, + getResourceContents(comparison, side, (ResourceAttachmentChange)object)); + } + } else { + ret = matchingValue(object, comparison, getResourceContents(comparison, side, null)); + } + return ret; + } + + public static Object matchingValue(Object value, Comparison comparison, List in) { + Object ret = null; + IEqualityHelper equalityHelper = comparison.getEqualityHelper(); + Iterator valuesIterator = in.iterator(); + while (valuesIterator.hasNext() && ret == null) { + Object object = valuesIterator.next(); + if (equalityHelper.matchingValues(object, value)) { + ret = object; + } + } + return ret; + } + + /** + * Returns true if the given diff is displayed in an group as provided by the {@code groupProvider} and + * not filtered by the given filter {@code predicate}. + * + * @param diff + * the {@link Diff} to check. + * @param groupProvider + * the {@link IDifferenceGroupProvider}. + * @param predicate + * the filter {@link Predicate}. + * @return {@code true} if the given {@code diff} is visible in the given {@code groupProvider}, + * {@code false} otherwise. + */ + public static boolean isVisibleInMergeViewer(Diff diff, IDifferenceGroupProvider groupProvider, + Predicate predicate) { + Iterable nodes = groupProvider.getTreeNodes(diff); + return any(nodes, predicate); + } + + /** + * Checks if the given diff is considered as a mark as merged diff. + * + * @see MergeOperation + * @param diff + * the given Diff. + * @param item + * the given IMergeViewerItem associated with the diff. + * @param compareConfiguration + * the compare configuration object to use with this viewer. + * @return true, if the given diff is considered as a mark as merged diff, false otherwise. + */ + public static boolean isMarkAsMerged(Diff diff, IMergeViewerItem item, + IEMFCompareConfiguration compareConfiguration) { + final boolean markAsMerged; + if (isInTerminalState(diff)) { + IMergeData mergeData = (IMergeData)EcoreUtil.getExistingAdapter(diff, IMergeData.class); + if (mergeData != null) { + boolean leftEditable = compareConfiguration.isLeftEditable(); + boolean rightEditable = compareConfiguration.isRightEditable(); + MergeMode mergeMode = MergeMode.getMergeMode(diff, leftEditable, rightEditable); + MergeOperation mergeAction = mergeMode.getMergeAction(diff, leftEditable, rightEditable); + if (mergeAction == MergeOperation.MARK_AS_MERGE) { + markAsMerged = true; + } else { + markAsMerged = false; + } + } else { + markAsMerged = false; + } + } else { + markAsMerged = false; + } + return markAsMerged; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/ResourceUIUtil.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/ResourceUIUtil.java new file mode 100644 index 000000000..e05b1e662 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/ResourceUIUtil.java @@ -0,0 +1,698 @@ +/******************************************************************************* + * Copyright (c) 2015 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.util; + +import static com.google.common.collect.Iterables.filter; +import static java.util.Collections.emptyList; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import java.util.Collection; +import java.util.Map.Entry; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.Match; +import org.eclipse.emf.compare.graph.IGraphView; +import org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch; +import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.item.impl.MergeViewerItem; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * This class will be used to provide various utilities aimed at NotLoadedFragment manipulation. + * + * @author Axel Richard + */ +public class ResourceUIUtil { + + /** ID of the graph of EMF resources used by EMFCompare to compute the logical model. */ + public static final String RESOURCES_GRAPH_ID = "org.eclipse.emf.compare.resources.graph"; //$NON-NLS-1$ + + /** + * Function that retrieve the data of the given TreeNode. + */ + private static Function TREE_NODE_DATA = new Function() { + public EObject apply(EObject node) { + final EObject data; + if (node instanceof TreeNode) { + data = ((TreeNode)node).getData(); + } else { + data = node; + } + return data; + } + }; + + /** + * Get the graph of resources' URI for the models involved in the current comparison. + * + * @return the graph if it exists, null otherwise. + */ + public static IGraphView getResourcesURIGraph() { + return EMFCompareRCPPlugin.getDefault().getGraphView(RESOURCES_GRAPH_ID); + } + + /** + * Check if the given URI correspond to the root resource of a model. In this case a root resource is a + * piece of a whole model that is not a fragment of the model. + * + * @param uri + * the given URI. + * @return true if the given URI is root resource of a model, false otherwise. + */ + public static boolean isRootResource(URI uri) { + return !isFragment(uri); + } + + /** + * Check if the given URI correspond to a fragment of model. In this case a fragment is a piece of a whole + * model that is not the root resource of the model. + * + * @param uri + * the given URI. + * @return true if the given URI is a fragment of a model, false otherwise. + */ + public static boolean isFragment(URI uri) { + final IGraphView graph = getResourcesURIGraph(); + if (uri != null && graph != null) { + URI parentData = graph.getParentData(uri); + if (parentData != null) { + return true; + } + } + return false; + } + + /** + * Check if the given match is a root match of its comparison model and is a fragment. In this case a + * fragment is a piece of a whole model that is not the root resource of the model. + * + * @param rootMatch + * the given match. + * @param side + * the side for which we want to know if it is a fragment or not. + * @return true if the given match is a root match of its comparison model and is a fragment, + * false otherwise. + */ + public static boolean isFragment(Match rootMatch, MergeViewerSide side) { + if (rootMatch != null && rootMatch.eContainer() instanceof Comparison) { + URI uri = getDataURI(rootMatch, side); + return isFragment(uri); + } + return false; + } + + /** + * Check if the given URI corresponds to a fragment of model that is at the first level of the model, in + * other words a fragment that is directly under a root resource. In this case a fragment is a piece of a + * whole model that is not the root resource of the model. + *

+ * If the given fragment (represented by the given URI) has several parents, this method will return + * false. + *

+ * + * @param uri + * the given URI. + * @return true if the given URI is a fragment of a model, false otherwise. + */ + public static boolean isFirstLevelFragment(URI uri) { + final IGraphView graph = getResourcesURIGraph(); + if (uri != null && graph != null) { + URI parentData = graph.getParentData(uri); + if (parentData != null) { + URI parent = parentData.trimFragment(); + return !isFragment(parent); + } + } + return false; + } + + /** + * Get the root resource of the whole model that contains the given fragment (represented by its uri). + *

+ * If at some point of the process a fragment has several parents, this method will return + * null. + *

+ * + * @param uri + * the given URI. + * @return the root resource of the whole model that contains the given fragment if found, + * null otherwise. + */ + public static URI getRootResourceURI(URI uri) { + final URI uriRoot; + final IGraphView graph = getResourcesURIGraph(); + if (uri != null && graph != null) { + URI parentData = graph.getParentData(uri); + if (parentData == null) { + uriRoot = uri; + } else { + URI parent = parentData.trimFragment(); + uriRoot = getRootResourceURI(parent); + } + } else { + uriRoot = null; + } + return uriRoot; + } + + /** + * Get the first loaded parent resource URI of the given resource (represented by its URI) contained in + * the given ResourceSet. + *

+ * If at some point of the process the current resource (represented by its URI) has several parents, this + * method will return null. + * + * @param rs + * the ResourceSet in which the first loaded parent must be found. + * @param uri + * the URI of the resource for which we want to get its first loaded parent. + * @return the URI of the first loaded resource parent if found, null otherwise. + */ + public static URI getParentResourceURI(ResourceSet rs, URI uri) { + final URI parentURI; + final Entry entry = getResourceParent(rs, uri); + if (entry != null) { + final Resource resource = entry.getValue(); + if (resource != null) { + parentURI = entry.getKey().trimFragment(); + } else { + parentURI = null; + } + } else { + parentURI = null; + } + return parentURI; + } + + /** + * Get the parent of the given resource (represented by its URI) contained in the given ResourceSet. + *

+ * If the given resource (represented by its URI) has several parents, this method will return + * null. + *

+ * + * @param rs + * the ResourceSet in which the parent must be found. + * @param uri + * the URI of the resource for which we want to get its parent. + * @return the parent of the given resource (represented by its URI) if found, null + * otherwise. + */ + public static Resource getParent(ResourceSet rs, URI uri) { + final Resource resource; + final IGraphView graph = getResourcesURIGraph(); + if (uri != null && graph != null) { + URI parentData = graph.getParentData(uri); + if (parentData != null) { + resource = rs.getResource(parentData.trimFragment(), false); + } else { + resource = null; + } + } else { + resource = null; + } + return resource; + } + + /** + * Get the first loaded EObject parent of the given resource (represented by its URI) contained in the + * given ResourceSet. + *

+ * If at some point of the process the current resource (represented by its URI) has several parents, this + * method will return null. + * + * @param rs + * the ResourceSet in which the first loaded parent must be found. + * @param uri + * the URI of the resource for which we want to get its first loaded parent. + * @return the first loaded EObject parent of the given resource (represented by its URI) if found, + * null otherwise. + */ + public static EObject getEObjectParent(ResourceSet rs, URI uri) { + final EObject eObject; + final Entry entry = getResourceParent(rs, uri); + if (entry != null) { + final Resource resource = entry.getValue(); + if (resource != null) { + eObject = resource.getEObject(entry.getKey().fragment()); + } else { + eObject = null; + } + } else { + eObject = null; + } + return eObject; + } + + /** + * Get the first loaded parent of the given resource (represented by its URI) contained in the given + * ResourceSet. + *

+ * If at some point of the process the current resource (represented by its URI) has several parents, this + * method will return null. + * + * @param rs + * the ResourceSet in which the first loaded parent must be found. + * @param uri + * the URI of the resource for which we want to get its first loaded parent. + * @return an entry composed with the first loaded EObject parent of the given resource (represented by + * its URI) and the Resource associated if found, null otherwise. + */ + private static Entry getResourceParent(ResourceSet rs, URI uri) { + Entry entry = null; + final IGraphView graph = getResourcesURIGraph(); + if (uri != null && graph != null) { + URI parentData = graph.getParentData(uri); + if (parentData != null) { + URI parent = parentData.trimFragment(); + Resource resourceParent = rs.getResource(parent, false); + if (resourceParent != null) { + entry = Maps.immutableEntry(parentData, resourceParent); + } else { + entry = getResourceParent(rs, parent); + } + } + } + return entry; + } + + /** + * Search from the given list of TreeNodes (and recursively on its children), the one that is associated + * to the given Match. + * + * @param nodes + * the given list of TreeNodes. + * @param match + * the given Match. + * @return the TreeNode that is associated to the given Match. + */ + public static TreeNode getTreeNode(Collection nodes, Match match) { + for (TreeNode treeNode : nodes) { + EObject data = TREE_NODE_DATA.apply(treeNode); + if (data.equals(match)) { + return treeNode; + } + } + for (TreeNode treeNode : nodes) { + TreeNode treeNode2 = getTreeNode(treeNode.getChildren(), match); + if (treeNode2 != null) { + return treeNode2; + } + } + return null; + } + + /** + * Get from the given list of TreeNodes, the one that has its data's resource's URI (TreeNode -> Match -> + * EObject -> Resource -> URI) corresponding to the given URI. + * + * @param nodes + * the given list of TreeNodes. + * @param uri + * the given URI. + * @return the TreeNode that has its data's resource's URI corresponding to the given URI, or null if no + * one match. + */ + public static TreeNode getTreeNodeFromURI(Collection nodes, URI uri) { + for (TreeNode treeNode : nodes) { + EObject data = TREE_NODE_DATA.apply(treeNode); + URI dataURI = getDataURI((Match)data); + if (uri.equals(dataURI)) { + return treeNode; + } + } + return null; + } + + /** + * Get the Resource's URI of the data associated to the given Match + * + * @param match + * the given Match. + * @return the Resource's URI of the data associated to the given Match. + */ + public static URI getDataURI(Match match) { + final URI uri; + final Resource resource; + if (match.getLeft() != null) { + resource = match.getLeft().eResource(); + } else if (match.getRight() != null) { + resource = match.getRight().eResource(); + } else if (match.getOrigin() != null) { + resource = match.getOrigin().eResource(); + } else { + resource = null; + } + if (resource != null) { + uri = resource.getURI(); + } else { + uri = null; + } + return uri; + } + + /** + * Get the Resource's URIs of the data associated to the given list of Matches. + * + * @param matches + * the given list of Matches. + * @param side + * the given side of the comparison. + * @return the Resource's URIs of the data associated to the given list of Matches. + */ + public static Collection getDataURIs(Collection matches, MergeViewerSide side) { + final Collection uris = Lists.newArrayList(); + for (Match match : matches) { + URI dataURI = getDataURI(match, side); + if (dataURI != null) { + uris.add(dataURI); + } + } + return uris; + } + + /** + * Get the Resource's URI of the data associated to the given Match, and for the given side of the + * comparison. . + * + * @param match + * the given Match. + * @param side + * the given side of the comparison. + * @return the Resource's URI of the data associated to the given Match. + */ + public static URI getDataURI(Match match, MergeViewerSide side) { + final URI uri; + final Resource resource; + if (MergeViewerSide.LEFT == side && match.getLeft() != null) { + resource = match.getLeft().eResource(); + } else if (MergeViewerSide.RIGHT == side && match.getRight() != null) { + resource = match.getRight().eResource(); + } else if (MergeViewerSide.ANCESTOR == side && match.getOrigin() != null) { + resource = match.getOrigin().eResource(); + } else { + resource = null; + } + if (resource != null) { + uri = resource.getURI(); + } else { + uri = null; + } + return uri; + } + + /** + * Get the Resource's ResourceSet of the data associated to the given Match. + * + * @param match + * the given Match. + * @return the Resource's ResourceSet of the data associated to the given Match. + */ + public static ResourceSet getDataResourceSet(Match match) { + final ResourceSet rs; + final Resource resource; + if (match.getLeft() != null) { + resource = match.getLeft().eResource(); + } else if (match.getRight() != null) { + resource = match.getRight().eResource(); + } else if (match.getOrigin() != null) { + resource = match.getOrigin().eResource(); + } else { + resource = null; + } + if (resource != null) { + rs = resource.getResourceSet(); + } else { + rs = null; + } + return rs; + } + + /** + * Get the Resource's ResourceSet of the data associated to the given Match, and for the given side of the + * comparison. + * + * @param match + * the given Match. + * @param side + * the given side of the comparison. + * @return the Resource's ResourceSet of the data associated to the given Match. + */ + public static ResourceSet getDataResourceSet(Match match, MergeViewerSide side) { + final ResourceSet rs; + final Resource resource; + if (MergeViewerSide.LEFT == side && match != null && match.getLeft() != null) { + resource = match.getLeft().eResource(); + } else if (MergeViewerSide.RIGHT == side && match != null && match.getRight() != null) { + resource = match.getRight().eResource(); + } else if (MergeViewerSide.ANCESTOR == side && match != null && match.getOrigin() != null) { + resource = match.getOrigin().eResource(); + } else { + resource = null; + } + if (resource != null) { + rs = resource.getResourceSet(); + } else { + rs = null; + } + return rs; + } + + /** + * Check if the given list of TreeNodes contains at least two nodes that have NotLoadedFragmentMatch for + * data. + * + * @param nodes + * the given list of TreeNodes. + * @return true if the given list of TreeNodes contains at least two nodes that have + * NotLoadedFragmentMatch for data, false otherwise. + */ + public static boolean containsNotLoadedFragmentNodes(Collection nodes) { + int notLoadedFragments = 0; + for (TreeNode node : nodes) { + EObject data = TREE_NODE_DATA.apply(node); + if (data instanceof NotLoadedFragmentMatch) { + notLoadedFragments++; + } + } + return notLoadedFragments > 1; + } + + /** + * Get from the given list of {@link IMergeViewerItem}s, the NotLoadedFragmentMatchs. + * + * @param items + * the given list of IMergeViewerItems. + * @return a list of Match. + */ + public static Collection getNotLoadedFragmentMatches(Collection items) { + final Collection notLoadedFragmentMatches = Lists.newArrayList(); + for (IMergeViewerItem item : items) { + // If an IMergeViewerItem contains NotLoadedFragmentMatch, this is the same NotLoadedFragmentMatch + // on left, right and ancestor sides. + Object left = item.getLeft(); + if (left instanceof NotLoadedFragmentMatch) { + notLoadedFragmentMatches.add((NotLoadedFragmentMatch)left); + } + } + return notLoadedFragmentMatches; + } + + /** + * Get the resource's name associated with the data of the given NotLoadedFragmentMatch. If it is a + * NotLoadedFragmentMatch containing others NotLoadedFragmentMatch, then it returns an empty string. + * + * @param match + * the given NotLoadedFragmentMatch. + * @return the resource's name associated with the data of the given NotLoadedFragmentMatch. + */ + public static String getResourceName(NotLoadedFragmentMatch match) { + final String name; + Collection children = match.getChildren(); + if (Iterables.size(children) == 1) { + URI uri = getDataURI(children.iterator().next()); + name = uri.lastSegment(); + } else { + name = ""; //$NON-NLS-1$ + } + return name; + } + + /** + * Filters, from the root matches of the given comparison, those who will children matches of the given + * match if all fragments of the whole models involved in comparison had been loaded, for the given side + * of the comparison. + * + * @param comparison + * the given comparison, cannot be null. + * @param match + * the given match, can be null. + * @param side + * the given side of the comparison. + * @return a list of Matches. + */ + public static Collection getChildrenMatchWithNotLoadedParent(Comparison comparison, Match match, + MergeViewerSide side) { + if (match == null) { + return emptyList(); + } + final Collection childrenMatches = Sets.newLinkedHashSet(); + final Collection matches = comparison.getMatches(); + final IGraphView graph = getResourcesURIGraph(); + if (graph == null) { + return childrenMatches; + } + ResourceSet rs = getDataResourceSet(match, side); + if (rs == null) { + return childrenMatches; + } + for (Match rootMatch : matches) { + if (isFragment(rootMatch, side)) { + URI uri = getDataURI(rootMatch, side); + Resource resourceParent = getParent(rs, uri); + URI parentData = graph.getParentData(uri); + boolean _continue = true; + while (resourceParent == null && _continue == true) { + if (parentData != null) { + resourceParent = getParent(rs, parentData.trimFragment()); + parentData = graph.getParentData(parentData.trimFragment()); + } else { + _continue = false; + } + } + if (resourceParent != null && parentData != null) { + EObject eObjectParent = resourceParent.getEObject(parentData.fragment()); + Match matchParent = match.getComparison().getMatch(eObjectParent); + if (matchParent != null && matchParent.equals(match)) { + childrenMatches.add(rootMatch); + } + } + } + } + return childrenMatches; + } + + /** + * Check if the given URI is a child (directly or not) of one of the given list of URIs. + * + * @param uri + * the given URI. + * @param uris + * the given list of URIs. + * @return true if the given URI is a child (directly or not) of one of the given list of URIs, false + * otherwise. + */ + public static boolean isChildOf(URI uri, Collection uris) { + final IGraphView graph = getResourcesURIGraph(); + URI parentData = graph.getParentData(uri); + while (parentData != null) { + URI parent = parentData.trimFragment(); + if (uris.contains(parent)) { + return true; + } + parentData = graph.getParentData(parent); + } + return false; + } + + /** + * Constructs a {@link org.eclipse.emf.compare.match.impl.NotLoadedFragmentMatch} from the given + * {@link org.eclipse.emf.compare.Match} and then return the + * {@link org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem} corresponding to this + * NotLoadedFragmentMatch. + * + * @param match + * the given Match. + * @param side + * the side of the Match. + * @param comparison + * the comparison object that contains the Match. + * @param adapterFactory + * the adapter factory used to create the merge viewer item. + * @return an IMergeViewerItem. + */ + public static IMergeViewerItem createItemForNotLoadedFragmentMatch(Match match, MergeViewerSide side, + Comparison comparison, AdapterFactory adapterFactory) { + final MergeViewerItem.Container container; + ResourceSet rs = getDataResourceSet(match, side); + URI uri = getDataURI(match, side); + EObject firstLoadedParent = getEObjectParent(rs, uri); + if (firstLoadedParent == null) { + NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch(match); + container = new MergeViewerItem.Container(comparison, null, notLoadedFragmentMatch, + notLoadedFragmentMatch, notLoadedFragmentMatch, side, adapterFactory); + } else if (isRootResource(firstLoadedParent.eResource().getURI())) { + Match matchParent = comparison.getMatch(firstLoadedParent); + if (matchParent != null) { + if (!comparison.getMatches().contains(matchParent)) { + container = new MergeViewerItem.Container(comparison, null, match.getLeft(), + match.getRight(), match.getOrigin(), side, adapterFactory); + } else { + container = null; + } + } else { + NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch(match); + container = new MergeViewerItem.Container(comparison, null, notLoadedFragmentMatch, + notLoadedFragmentMatch, notLoadedFragmentMatch, side, adapterFactory); + } + } else { + container = null; + } + return container; + } + + /** + * Adds a new parent container to the given list of IMergeViewerItems if needed and returns it. If the + * given items don't need a new parent, return null. + * + * @param items + * the given IMergeViewerItems. + * @param side + * the side of the Match. + * @param comparison + * the comparison object that contains the Match. + * @param adapterFactory + * the adapter factory used to create the merge viewer item. + * @return an IMergeViewerItem, or null. + */ + public static IMergeViewerItem addNewContainerForNotLoadedFragmentMatches( + Collection items, MergeViewerSide side, Comparison comparison, + AdapterFactory adapterFactory) { + final MergeViewerItem.Container newContainer; + final Collection notLoadedFragmentMatches = getNotLoadedFragmentMatches(items); + if (notLoadedFragmentMatches.size() > 1) { + // Need to replace by top-container NotLoadedFragment item + NotLoadedFragmentMatch notLoadedFragmentMatch = new NotLoadedFragmentMatch( + notLoadedFragmentMatches); + for (NotLoadedFragmentMatch match : filter(notLoadedFragmentMatches, + NotLoadedFragmentMatch.class)) { + match.setName(getResourceName(match)); + } + newContainer = new MergeViewerItem.Container(comparison, null, notLoadedFragmentMatch, + notLoadedFragmentMatch, notLoadedFragmentMatch, side, adapterFactory); + } else { + newContainer = null; + } + return newContainer; + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/SWTUtil.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/SWTUtil.java new file mode 100644 index 000000000..28becce16 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/SWTUtil.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2013, 2017 Obeo and others. + * 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 + * Philip Langer - check if control is disposed before redraw + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.util; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; + +/** + * Utility class for running operation in the UI-Thread if not already within it. + * + * @author Mikael Barbero + */ +public final class SWTUtil { + + private SWTUtil() { + // prevent instantiation. + } + + /** + * Causes the run() method of the runnable to be invoked by the user-interface thread at the next + * reasonable opportunity. The caller of this method continues to run in parallel, and is not notified + * when the runnable has completed. + * + * @param runnable + * runnable code to run on the user-interface thread. + */ + public static void safeAsyncExec(final Runnable runnable) { + if (Display.getCurrent() != null) { + Display.getCurrent().asyncExec(runnable); + } else { + Display.getDefault().asyncExec(runnable); + } + } + + /** + * Causes the run() method of the runnable to be invoked by the user-interface thread at the next + * reasonable opportunity. The thread which calls this method is suspended until the runnable completes. + * + * @param runnable + * runnable code to run on the user-interface thread. + */ + public static void safeSyncExec(final Runnable runnable) { + if (Display.getCurrent() != null) { + runnable.run(); + } else { + Display.getDefault().syncExec(runnable); + } + } + + /** + * Run {@link Viewer#refresh()} on the given viewer. + * + * @param viewer + * the viewer to refresh. + * @param async + * whether the thread which calls this method is not suspended until the runnable completes. + * @param checkDisposed + * whether the viewer's control dispose state has to be checked before refresh. + */ + public static void safeRefresh(final Viewer viewer, boolean async, final boolean checkDisposed) { + Runnable runnable = new Runnable() { + public void run() { + if (checkDisposed) { + Control control = viewer.getControl(); + if (control != null && !control.isDisposed()) { + viewer.refresh(); + } + } else { + viewer.refresh(); + } + } + }; + if (async) { + safeAsyncExec(runnable); + } else { + safeSyncExec(runnable); + } + } + + /** + * Run {@link Control#redraw()} on the given viewer. + * + * @param redraw + * the control to redraw. + * @param async + * whether the thread which calls this method is not suspended until the runnable completes. + */ + public static void safeRedraw(final Control control, boolean async) { + Runnable runnable = new Runnable() { + public void run() { + if (!control.isDisposed()) { + control.redraw(); + } + } + }; + if (async) { + safeAsyncExec(runnable); + } else { + safeSyncExec(runnable); + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/ICompareColor.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/ICompareColor.java new file mode 100644 index 000000000..967135cc1 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/ICompareColor.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer; + +import org.eclipse.emf.compare.Diff; +import org.eclipse.swt.graphics.Color; + +/** + * Implementation of this interface will return color of decorator of {@link Diff difference}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface ICompareColor { + + /** + * Return the color of the background of the decorator of the given {@code diff}. + * + * @param diff + * the diff to be decorated. + * @param isThreeWay + * are we comparing three models. + * @param isIgnoreAncestor + * if the ancestor has to be ignored (i.e. ignore the isThreeWay parameter). + * @param selected + * if the given {@code diff} is selected in the viewer. + * @return the background color. + */ + Color getFillColor(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected); + + /** + * Return the color of the stroke of the decorator of the given {@code diff}. + * + * @param diff + * the diff to be decorated. + * @param isThreeWay + * are we comparing three models. + * @param isIgnoreAncestor + * if the ancestor has to be ignored (i.e. ignore the isThreeWay parameter). + * @param selected + * if the given {@code diff} is selected in the viewer. + * @return the background color. + */ + Color getStrokeColor(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected); + + /** + * Get the color for Required change. + * + * @return + */ + Color getRequiredFillColor(); + + /** + * Get the color for Required change border items. This color is computed from + * {@link ICompareColor#getRequiredFillColor()} + * + * @return + */ + Color getRequiredStrokeColor(); + + /** + * Get the color for Unmergeable difference. + * + * @return + */ + Color getUnmergeableFillColor(); + + /** + * Get the color for Unmergeable difference border items. This color is computed from + * {@link ICompareColor#getUnmergeableFillColor()} + * + * @return + */ + Color getUnmergeableStrokeColor(); + + /** + * Dispose all {@link Color} resources. + */ + void dispose(); + + /** + * A provider of ICompareColor. + * + * @author Mikael Barbero + * @since 4.0 + */ + public interface Provider { + + /** + * Returns the ICompareColor. + * + * @return the ICompareColor. + */ + ICompareColor getCompareColor(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/IMergeViewer.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/IMergeViewer.java new file mode 100644 index 000000000..73f37e704 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/IMergeViewer.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer; + +import org.eclipse.emf.compare.DifferenceSource; +import org.eclipse.jface.viewers.IInputSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Control; + +/** + * A specific {@link IInputSelectionProvider} for EMF Compare. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface IMergeViewer extends IInputSelectionProvider { + + /** + * {@inheritDoc} + */ + MergeViewerSide getSide(); + + /** + * Returns the primary control associated with this viewer. + * + * @return the SWT control which displays this viewer's content + */ + Control getControl(); + + /** + * Refreshes this viewer completely with information freshly obtained from this viewer's model. + */ + void refresh(); + + /** + * Sets or clears the input for this viewer. + * + * @param input + * the input of this viewer, or null if none + */ + void setInput(Object input); + + /** + * Sets a new selection for this viewer and optionally makes it visible. + *

+ * Subclasses must implement this method. + *

+ * + * @param selection + * the new selection + * @param reveal + * true if the selection is to be made visible, and false otherwise + */ + void setSelection(ISelection selection, boolean reveal); + + /** + * An enum that represents the side of the viewer and provides utilty methods to manage sides. + * + * @author Mikael Barbero + * @since 4.0 + */ + enum MergeViewerSide { + + /** Values: left side, right side, ancestor side. */ + LEFT, RIGHT, ANCESTOR; + + /** + * Get the opposite side of this side. + * + * @return the opposite side of this side. + */ + public MergeViewerSide opposite() { + final MergeViewerSide opposite; + switch (this) { + case LEFT: + opposite = RIGHT; + break; + case RIGHT: + opposite = LEFT; + break; + case ANCESTOR: + opposite = ANCESTOR; + break; + default: + throw new IllegalStateException(); // happy compiler :) + } + return opposite; + } + + /** + * Get the side value from the given {@link DifferenceSource}. + * + * @param source + * the given DifferenceSource. + * @return the side value from the given DifferenceSource. + */ + public static MergeViewerSide getValueFrom(DifferenceSource source) { + switch (source) { + case LEFT: + return LEFT; + case RIGHT: + return RIGHT; + default: + throw new IllegalStateException(); + } + } + + /** + * Converts this side to DifferenceSource. + * + * @return the DifferenceSource equivalent to this side. + */ + public DifferenceSource convertToDifferenceSource() { + switch (this) { + case LEFT: + return DifferenceSource.LEFT; + case RIGHT: + return DifferenceSource.RIGHT; + default: + throw new IllegalStateException(); + } + } + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/IMergeViewerItem.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/IMergeViewerItem.java new file mode 100644 index 000000000..350a1305b --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/IMergeViewerItem.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.mergeviewer.item; + +import com.google.common.base.Predicate; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.Diff; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.ecore.EObject; + +/** + * An IMergeViewerItem associate a Diff and its left side, right side and ancestor side values. An + * IMergeViewerItem also known its parent. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface IMergeViewerItem extends Adapter { + + /** + * A predicate to know if the given Item is an insertion point. + */ + Predicate IS_INSERTION_POINT = new Predicate() { + public boolean apply(IMergeViewerItem item) { + return item.isInsertionPoint(); + } + }; + + /** + * The Diff associated with the Item. + * + * @return the Diff associated with the Item. + */ + Diff getDiff(); + + /** + * Returns the left side value of the Diff. + * + * @return the left side value of the Diff. + */ + Object getLeft(); + + /** + * Returns the right side value of the Diff. + * + * @return the right side value of the Diff. + */ + Object getRight(); + + /** + * Returns the ancestor side value of the Diff. + * + * @return the ancestor side value of the Diff. + */ + Object getAncestor(); + + /** + * Returns the appropriate value according to the given side. + * + * @param side + * the given side. + * @return the appropriate value according to the given side. + */ + Object getSideValue(MergeViewerSide side); + + /** + * Returns the side of the Diff. + * + * @return the side of the Diff. + */ + MergeViewerSide getSide(); + + /** + * Returns true if the Item is an insertion point, false otherwise. + * + * @return true if the Item is an insertion point, false otherwise. + */ + boolean isInsertionPoint(); + + /** + * Returns the parent of this element. If the object is the root of a hierarchy null is + * returned. + * + * @return the parent of this element, or null if the element has no parent + */ + Container getParent(); + + /** + * An IMergeViewerItem.Container knows its children. + * + * @author Mikael Barbero + * @since 4.0 + * @deprecated IMergeViewerItem.Container is no longer needed since its functionality is now provided by + * {@link org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemContentProvider + * IMergeViewerItemContentProvider}. Use an {@link IMergeViewerItem} instead. + */ + @Deprecated + interface Container extends IMergeViewerItem { + /** + * Returns whether this container has at least one child. In some cases this methods avoids having to + * call the potential more costly getChildren method. + * + * @param group + * the active group provider. + * @param predicate + * the active predicate. + * @return true if this container has at least one child + */ + boolean hasChildren(IDifferenceGroupProvider group, Predicate predicate); + + /** + * Returns the children of this container. If this container has no children an empty array is + * returned (not null). + * + * @param group + * the active group provider. + * @param predicate + * the active predicate. + * @return the children of this container as an array + */ + IMergeViewerItem[] getChildren(IDifferenceGroupProvider group, Predicate predicate); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemContentProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemContentProvider.java new file mode 100644 index 000000000..4e2475a3f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemContentProvider.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Alexandra Buzila - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider; + +import org.eclipse.jface.viewers.ITreeContentProvider; + +/** + * Interface for specialized {@link ITreeContentProvider tree content providers} for the comparison content + * merge viewer. + * + * @author Stefan Dirix + * @since 4.4 + */ +public interface IMergeViewerItemContentProvider extends IOptionalProvider { + + /** + * Determine the parent of the given {@code object}. + * + * @param object + * the {@link Object} for which the parent is to be determined. + * @param configuration + * the {@link IMergeViewerItemProviderConfiguration}. + * @return the determined parent object, {@code null} if there is none. + */ + public Object getParent(Object object, IMergeViewerItemProviderConfiguration configuration); + + /** + * Determine the children of the given {@code object} + * + * @param object + * the {@link Object} for which the children are to be determined. + * @param configuration + * the {@link IMergeViewerItemProviderConfiguration}. + * @return an array with the determined children, an empty array if there are none. + */ + public Object[] getChildren(Object object, IMergeViewerItemProviderConfiguration configuration); + + /** + * Indicates whether the given {@code object} has children. + * + * @param object + * the {@link Object} for which it is indicated whether it has children. + * @param configuration + * the {@link IMergeViewerItemProviderConfiguration}. + * @return {@code true} if the given object has children, {@code false} otherwise. + */ + public boolean hasChildren(Object object, IMergeViewerItemProviderConfiguration configuration); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProvider.java new file mode 100644 index 000000000..694b136fd --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider; + +import java.util.List; + +import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem; + +/** + * The contract for providers responsible for determining root elements in merge viewers. Typically these are + * {@link IMergeViewerItem}s but they not necessarily have to be. + * + * @author Stefan Dirix + * @since 4.4 + */ +public interface IMergeViewerItemProvider extends IOptionalProvider { + + /** + * Determine the root merge viewer items for the given {@code object}. + * + * @param object + * the {@link Object} for which the root merge viewer items are to be determined. + * @param configuration + * the {@link IMergeViewerItemProviderConfiguration}. + * @return a list of the root elements. + */ + public List getMergeViewerItems(Object object, + IMergeViewerItemProviderConfiguration configuration); + + /** + * Determine the merge viewer item which shall be selected. + * + * @param object + * the {@link Object} for which the selected merge viewer item is to be determined. + * @param configuration + * the {@link IMergeViewerItemProviderConfiguration}. + * @return the merge viewer item to select. + */ + public Object getItemToSelect(Object object, IMergeViewerItemProviderConfiguration configuration); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProviderConfiguration.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProviderConfiguration.java new file mode 100644 index 000000000..313a1602f --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IMergeViewerItemProviderConfiguration.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider; + +import com.google.common.base.Predicate; + +import org.eclipse.emf.common.notify.AdapterFactory; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.ecore.EObject; + +/** + * The configuration used by {@link IMergeViewerItemContentProvider}s. + * + * @author Stefan Dirix + * @since 4.4 + */ +public interface IMergeViewerItemProviderConfiguration { + + /** + * Get the {@link AdapterFactory}. + * + * @return the {@link AdapterFactory}, + */ + public AdapterFactory getAdapterFactory(); + + /** + * Get the {@link IDifferenceGroupProvider}. + * + * @return the {@link IDifferenceGroupProvider}. + */ + public IDifferenceGroupProvider getDifferenceGroupProvider(); + + /** + * Get the difference filter {@link Predicate}. + * + * @return the difference filter {@link Predicate}. + */ + public Predicate getDifferenceFilterPredicate(); + + /** + * Get the {@link Comparison}. + * + * @return the {@link Comparison}. + */ + public Comparison getComparison(); + + /** + * Get the {@link MergeViewerSide}. + * + * @return the {@link MergeViewerSide}. + */ + public MergeViewerSide getSide(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IOptionalProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IOptionalProvider.java new file mode 100644 index 000000000..31c2d9884 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/item/provider/IOptionalProvider.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2016 EclipseSource Muenchen GmbH and others. + * 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: + * Stefan Dirix - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider; + +/** + * A contract for a provider which can indicate whether it wants to handle a certain object. + * + * @author Stefan Dirix + * @since 4.4 + */ +public interface IOptionalProvider { + /** + * Indicates whether this provider wants to handle the given {@code object}. + * + * @param object + * the {@link Object}. + * @return {@code true} if the provider wants to handle the given {@code object}, {@code false} otherwise. + */ + boolean canHandle(Object object); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AbstractDifferenceFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AbstractDifferenceFilter.java new file mode 100644 index 000000000..5571f165a --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AbstractDifferenceFilter.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2013, 2016 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.structuremergeviewer.filters; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; + +/** + * An abstract filter implementation. + * + * @author Axel Richard + * @since 4.0 + */ +public abstract class AbstractDifferenceFilter implements IDeactivableDiffFilter { + + /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */ + protected String label; + + /** {@link IDifferenceFilter#getDescription()} */ + protected String description; + + /** The initial activation state of the filter. */ + protected boolean activeByDefault; + + /** + * Whether this filter is active. A filter that is not active will not be used at all nor displayed in the + * compare editor. + */ + private boolean active; + + /** + * Constructs the filter with the appropriate predicate. + */ + public AbstractDifferenceFilter() { + super(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicateWhenSelected() + */ + public abstract Predicate getPredicateWhenSelected(); + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicateWhenUnselected() + */ + public Predicate getPredicateWhenUnselected() { + return Predicates.alwaysFalse(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getLabel() + */ + public String getLabel() { + return label; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setLabel(java.lang.String) + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * {@inheritDoc} + */ + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#defaultSelected() + */ + public boolean defaultSelected() { + return activeByDefault; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDeactivableDiffFilter#isActive() + * @since 4.3 + */ + public boolean isActive() { + return active; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#setDefaultSelected(boolean) + */ + public void setDefaultSelected(boolean active) { + this.activeByDefault = active; + } + + /** + * @since 4.3 + */ + public void setActive(boolean active) { + this.active = active; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#isEnabled(org.eclipse.emf.compare.scope.IComparisonScope, + * org.eclipse.emf.compare.Comparison) + */ + public boolean isEnabled(IComparisonScope scope, Comparison comparison) { + return true; + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDeactivableDiffFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDeactivableDiffFilter.java new file mode 100644 index 000000000..7cd769ea7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDeactivableDiffFilter.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2016 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.structuremergeviewer.filters; + +/** + * A {@link IDifferenceFilter} that can be fully deactivated in the preferences. + * + * @author Laurent Delaigue + * @since 4.3 + */ +public interface IDeactivableDiffFilter extends IDifferenceFilter { + + /** + * Whether the filter is enabled, i.e. will be taken into account in computations and displayed in the UI. + * + * @return The enablement of the filter. + */ + boolean isActive(); + + /** + * Set the activation of the filter. + * + * @param active + * Whether the filter should be active + */ + void setActive(boolean active); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java new file mode 100644 index 000000000..7d817d4ba --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.filters; + +import com.google.common.base.Predicate; + +import java.util.Collection; + +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; + +/** + * Instances of this class will be used by EMF Compare in order to provide difference filter facilities to the + * structural differences view. + * + * @author Axel Richard + * @since 4.0 + */ +public interface IDifferenceFilter { + + /** + * Returns the predicate that will filter out objects in the structural differences view when this filter + * will be selected. + * + * @return the predicate that will filter out objects in the structural differences view when this filter + * will be selected. + */ + Predicate getPredicateWhenSelected(); + + /** + * Returns the predicate that will filter out objects in the structural differences view when this filter + * will be unselected. + * + * @return the predicate that will filter out objects in the structural differences view when this filter + * will be unselected. + */ + Predicate getPredicateWhenUnselected(); + + /** + * A human-readable label for this filter. This will be displayed in the EMF Compare UI. + * + * @return The label for this filter. + */ + String getLabel(); + + /** + * Set the label for this filter. This will be displayed in the EMF Compare UI. + * + * @param label + * A human-readable label for this filter. + */ + void setLabel(String label); + + /** + * A human-readable description for this filter. This will be displayed in the EMF Compare UI. + * + * @return Description or null + */ + String getDescription(); + + /** + * Set the description for this filter. This will be displayed in the EMF Compare UI. + * + * @param description + * A human-readable description for this filter. + */ + void setDescription(String description); + + /** + * Returns the initial activation state that the filter should have. + * + * @return The initial activation state that the filter should have. + */ + boolean defaultSelected(); + + /** + * Set the initial activation state that the filter should have. + * + * @param defaultSelected + * The initial activation state that the filter should have (true if the filter should be + * active by default). + */ + void setDefaultSelected(boolean defaultSelected); + + /** + * Returns the activation condition based on the scope and comparison objects. + * + * @param scope + * The scope on which the filter will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return The activation condition based on the scope and comparison objects. + */ + boolean isEnabled(IComparisonScope scope, Comparison comparison); + + /** + * A registry of {@link IDifferenceFilter}. + * + * @since 4.0 + */ + interface Registry { + + /** + * Returns the list of {@link IDifferenceFilter} contained in the registry. + * + * @param scope + * The scope on which the filters will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return The list of {@link IDifferenceFilter} contained in the registry. + */ + Collection getFilters(IComparisonScope scope, Comparison comparison); + + /** + * Add to the registry the given {@link IDifferenceFilter}. + * + * @param filter + * The given {@link IDifferenceFilter}. + * @return The previous value associated with the class name of the given {@link IDifferenceFilter}, + * or null if there was no entry in the registry for the class name. + */ + IDifferenceFilter add(IDifferenceFilter filter); + + /** + * Remove from the registry the {@link IDifferenceFilter} designated by the given {@link String} . + * + * @param className + * The given {@link String} representing a {@link IDifferenceFilter}. + * @return The {@link IDifferenceFilter} designated by the given {@link String}. + */ + IDifferenceFilter remove(String className); + + /** + * Clear the registry. + */ + void clear(); + } + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterChange.java new file mode 100644 index 000000000..5563c48fe --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterChange.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.filters; + +import com.google.common.base.Predicate; + +import java.util.Collection; + +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; +import org.eclipse.emf.ecore.EObject; + +/** + * Stores selected and unselected filters, and a predicate that aggregates the selected state predicates of + * selected filters and the unselected state predicates of unselected filters. It will be used when a change + * of selected filters occurs. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface IDifferenceFilterChange extends ICompareEvent { + + /** + * Returns a {@link Predicate} that aggregates the selected state predicates of selected filters and the + * unselected state predicates of unselected filters. + * + * @return a predicate that aggregates the selected state predicates of selected filters and the + * unselected state predicates of unselected filters. + */ + + Predicate getPredicate(); + + /** + * Returns the list of selected {@link IDifferenceFilter}. + * + * @return the list of selected filters. + */ + Collection getSelectedDifferenceFilters(); + + /** + * Returns the list of unselected {@link IDifferenceFilter}. + * + * @return the list of unselected filters. + */ + Collection getUnselectedDifferenceFilters(); + +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/AbstractDifferenceGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/AbstractDifferenceGroupProvider.java new file mode 100644 index 000000000..5ed83ab74 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/AbstractDifferenceGroupProvider.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups; + +import static com.google.common.collect.Lists.newArrayListWithCapacity; + +import com.google.common.collect.ImmutableList; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature.Setting; +import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.emf.edit.tree.TreePackage; + +/** + * Abstract implementation of {@link IDifferenceGroupProvider}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public abstract class AbstractDifferenceGroupProvider extends AdapterImpl implements IDifferenceGroupProvider2 { + + /** The cross reference adapter used by the difference group provider. */ + private final ECrossReferenceAdapter crossReferenceAdapter; + + /** + * A human-readable label for this group provider. This will be displayed in the EMF Compare UI. + * + * @since 4.1 + */ + protected String label; + + /** + * The initial activation state of the group provider. + * + * @since 4.1 + */ + protected boolean activeByDefault; + + /** + * Groups held by this {@link IDifferenceGroupProvider}. + */ + private Collection groups; + + private Comparison comparison; + + /** + * Default constructor. + */ + public AbstractDifferenceGroupProvider() { + crossReferenceAdapter = new ECrossReferenceAdapter() { + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#isIncluded(org.eclipse.emf.ecore.EReference) + */ + @Override + protected boolean isIncluded(EReference eReference) { + return eReference == TreePackage.Literals.TREE_NODE__DATA; + } + }; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel() + * @since 4.1 + */ + public String getLabel() { + return label; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String) + * @since 4.1 + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected() + * @since 4.1 + */ + public boolean defaultSelected() { + return activeByDefault; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean) + * @since 4.1 + */ + public void setDefaultSelected(boolean active) { + this.activeByDefault = active; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org + * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison) + * @since 4.1 + */ + public boolean isEnabled(IComparisonScope scope, Comparison comparison) { + return true; + } + + /** + * Returns the cross reference adapter used by this difference group provider. + * + * @return the crossReferenceAdapter the cross reference adapter used by this difference group provider. + */ + protected final ECrossReferenceAdapter getCrossReferenceAdapter() { + return crossReferenceAdapter; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getTreeNodes(java.lang.Object) + */ + public List getTreeNodes(EObject eObject) { + Collection inverseReferences = crossReferenceAdapter + .getNonNavigableInverseReferences(eObject); + List ret = newArrayListWithCapacity(inverseReferences.size()); + for (Setting setting : inverseReferences) { + ret.add((TreeNode)setting.getEObject()); + } + return ret; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object) + */ + @Override + public boolean isAdapterForType(Object type) { + return type == IDifferenceGroupProvider.class; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison) + * @since 4.1 + */ + public Collection getGroups(Comparison aComparison) { + if (!groupsAreBuilt() || comparison != aComparison) { + dispose(); + this.comparison = aComparison; + groups = buildGroups(comparison); + } + return groups; + } + + /** + * Builds the groups for this comparison. The framework expects that all groups are fully initialized ( + * their sub tree should be built). Extending {@link IDifferenceGroupProvider2} needs to override this + * method to provid groups. + * + * @param aComparison + * comparison against which the groups will be built. + * @return Newly built collections of {@link IDifferenceGroup}. + * @since 4.1 + */ + protected Collection buildGroups(Comparison aComparison) { + return ImmutableList.of(); + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider2#groupsAreBuilt() + * @since 4.1 + */ + public boolean groupsAreBuilt() { + return groups != null && comparison != null; + } + + /** + * @return comparison against which the groups has been built. + * @since 4.1 + */ + protected Comparison getComparison() { + return comparison; + } + + /** + * {@inheritDoc} + * + * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#dispose() + * @since 4.1 + */ + public void dispose() { + comparison = null; + if (groups != null) { + for (IDifferenceGroup group : groups) { + group.dispose(); + } + groups = null; + } + + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroup.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroup.java new file mode 100644 index 000000000..baf513c98 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroup.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.groups; + +import com.google.common.base.Function; + +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.provider.utils.IStyledString; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.tree.TreeNode; +import org.eclipse.swt.graphics.Image; + +/** + * This interface represents an EMF Compare "group" of differences that can be displayed in the structural + * differences viewer of the UI. + * + * @author Laurent Goubet + * @see BasicDifferenceGroupImpl + * @since 4.0 + */ +public interface IDifferenceGroup extends Adapter { + + /** + * Function that retrieve the data of the given TreeNode. + */ + Function TREE_NODE_DATA = new Function() { + public EObject apply(EObject node) { + final EObject data; + if (node instanceof TreeNode) { + data = ((TreeNode)node).getData(); + } else { + data = node; + } + return data; + } + }; + + /** + * A human-readable label for this group. + * + * @return A human-readable label for this group that can be displayed to the user. + */ + String getName(); + + /** + * The styled label for the this group. This will be displayed in the EMF Compare UI. + * + * @return A human-readable styled label for this group that can be displayed to the user. + */ + IStyledString.IComposedStyledString getStyledName(); + + /** + * The icon that is to be used for this group in the compare UI. + * + * @return Icon that is to be used for this group in the compare UI. If {@code null}, a default image will + * be used instead. + */ + Image getImage(); + + /** + * The list of TreeNode containded in this group. + * + * @return the list of TreeNode containded in this group. + */ + List getChildren(); + + /** + * Dispose this group provider. + */ + void dispose(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java new file mode 100644 index 000000000..1c9ccf429 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2012, 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.structuremergeviewer.groups; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.compare.Comparison; +import org.eclipse.emf.compare.scope.IComparisonScope; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * Instances of this class will be used by EMF Compare in order to provide difference grouping facilities to + * the structural differences view. + * + * @author Laurent Goubet + * @since 4.0 + */ +public interface IDifferenceGroupProvider extends Adapter { + + /** + * This will be called internally by the grouping actions in order to determine how the differences should + * be grouped in the structural view. + * + * @param comparison + * The comparison which is to be displayed in the structural view. By default, its containment + * tree will be displayed. + * @return The collection of difference groups that are to be displayed in the structural viewer. An empty + * group will not be displayed at all. If {@code null}, we'll fall back to the default behavior. + */ + Collection getGroups(Comparison comparison); + + /** + * Returns the activation condition based on the scope and comparison objects. + * + * @param scope + * The scope on which the group provider will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return The activation condition based on the scope and comparison objects. + */ + boolean isEnabled(IComparisonScope scope, Comparison comparison); + + /** + * Dispose this difference group provider. + */ + void dispose(); + + /** + * Returns all {@link TreeNode}s that are wrapping the given {@code eObject}. It internally use a cross + * reference adapter. + * + * @param eObject + * the object from which we want inverse reference. + * @return all {@link TreeNode}s targeting the given {@code eObject} through + * {@link org.eclipse.emf.edit.tree.TreePackage.Literals#TREE_NODE__DATA}. + */ + List getTreeNodes(EObject eObject); + + /** + * A descriptor that can create adifference group provider. They are used as the values in a + * {@link IDifferenceGroupProvider.Descriptor.Registry registry}. + * + * @author Axel Richard + */ + interface Descriptor { + + /** + * Creates a group provider. + * + * @return the newly created group provider or null if error. + */ + IDifferenceGroupProvider createGroupProvider(); + + /** + * A human-readable label for this group. This will be displayed in the EMF Compare UI. + * + * @return The label for this group. + */ + public String getLabel(); + + /** + * A human-readable description for this group. This will be displayed in EMF Compare UI. + * + * @return + */ + public String getDescription(); + + /** + * Rank of this group. The highest rank enabled {@link IDifferenceGroupProvider} will be used as + * default group provider. + * + * @return the rank. + */ + public int getRank(); + + /** + * Return the type of Comparison this group provider can handle. + * + * @return {@link ComparisonType} + */ + public ComparisonType getType(); + + /** + * A registry of {@link IDifferenceGroupProvider}. + */ + interface Registry { + /** + * Returns the list of {@link IDifferenceGroupProvider} contained in the registry. + * + * @param scope + * The scope on which the group providers will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return The list of {@link IDifferenceGroupProvider} contained in the registry. + */ + Collection getGroupProviders(IComparisonScope scope, + Comparison comparison); + + /** + * Returns the default group provider. + * + * @param scope + * The scope on which the group providers will be applied. + * @param comparison + * The comparison which is to be displayed in the structural view. + * @return the default group provider or null if none. + */ + IDifferenceGroupProvider.Descriptor getDefaultGroupProvider(IComparisonScope scope, + Comparison comparison); + + /** + * Add to the registry the given {@link IDifferenceGroupProvider}. + * + * @param provider + * The given {@link IDifferenceGroupProvider}. + * @param className + * The class name of the given provider. + * @return The previous value associated with the class name of the given + * {@link IDifferenceGroupProvider}, or null if there was no entry in the registry for the + * class name. + */ + IDifferenceGroupProvider.Descriptor add(IDifferenceGroupProvider.Descriptor provider, + String className); + + /** + * Remove from the registry the {@link IDifferenceGroupProvider} designated by the given + * {@link String} . + * + * @param className + * The given {@link String} representing a {@link IDifferenceGroupProvider}. + * @return The {@link IDifferenceGroupProvider} designated by the given {@link String}. + */ + IDifferenceGroupProvider.Descriptor remove(String className); + + /** + * Clear the registry. + */ + void clear(); + } + } + + /** + * Type of comparison a {@link IDifferenceGroupProvider} can handle. + * + * @author Arthur Daussy + */ + public static enum ComparisonType { + /** Only three way comparison. */ + THREE_WAY, // + /** Only two way comparison. */ + TWO_WAY, // Two way comparison + /** Can handle both comparison type. */ + BOTH + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider2.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider2.java new file mode 100644 index 000000000..f8cb3e6a7 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider2.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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.structuremergeviewer.groups; + +/** + * Extended interface of {@link IDifferenceGroupProvider} that gives information on the building status of its + * groups. + * + * @author Arthur Daussy + * @since 4.1 + */ +public interface IDifferenceGroupProvider2 extends IDifferenceGroupProvider { + + /** + * Tells if the groups of this provider have been already built for a comparison. + * + * @return true if the groups has been built for this comparison or false + * otherwise. + */ + boolean groupsAreBuilt(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProviderChange.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProviderChange.java new file mode 100644 index 000000000..f43ea4bd8 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProviderChange.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups; + +import org.eclipse.emf.compare.rcp.ui.configuration.ICompareEvent; + +/** + * Stores selected {@link IDifferenceGroupProvider}. + * + * @author Mikael Barbero + * @since 4.0 + */ +public interface IDifferenceGroupProviderChange extends ICompareEvent { + + /** + * Returns the selected {@link IDifferenceGroupProviderChange}. + * + * @return the selected IDifferenceGroupProvider. + */ + IDifferenceGroupProvider getDifferenceGroupProvider(); +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/extender/IDifferenceGroupExtender.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/extender/IDifferenceGroupExtender.java new file mode 100644 index 000000000..6ae069c56 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/extender/IDifferenceGroupExtender.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2013, 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.structuremergeviewer.groups.extender; + +import java.util.Collection; + +import org.eclipse.emf.edit.tree.TreeNode; + +/** + * Instances of this class will be used by EMF Compare in order to extend the children of TreeNodes containing + * in the structure merge viewer. + * + * @author Axel Richard + * @since 4.0 + */ +public interface IDifferenceGroupExtender { + + /** + * Checks if the given TreeNode have to be handled by the extender. + * + * @param treeNode + * the given TreeNode. + * @return true if the TreeNode have to be handled, false otherwise. + */ + boolean handle(TreeNode treeNode); + + /** + * Add children to the given TreeNode. + * + * @param treeNode + * the given TreeNode. + */ + void addChildren(TreeNode treeNode); + + /** + * A registry of {@link IDifferenceGroupExtender}. + */ + interface Registry { + + /** + * Returns the list of {@link IDifferenceGroupExtender} contained in the registry. + * + * @return The list of {@link IDifferenceGroupExtender} contained in the registry. + */ + Collection getExtenders(); + + /** + * Add to the registry the given {@link IDifferenceGroupExtender}. + * + * @param extender + * The given {@link IDifferenceGroupExtender}. + * @return The previous value associated with the class name of the given + * {@link IDifferenceGroupExtender}, or null if there was no entry in the registry for the + * class name. + */ + IDifferenceGroupExtender add(IDifferenceGroupExtender extender); + + /** + * Remove from the registry the {@link IDifferenceGroupExtender} designated by the given + * {@link String} . + * + * @param className + * The given {@link String} representing a {@link IDifferenceGroupExtender}. + * @return The {@link IDifferenceGroupExtender} designated by the given {@link String}. + */ + IDifferenceGroupExtender remove(String className); + + /** + * Clear the registry. + */ + void clear(); + } +} diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/xpom.xml b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/xpom.xml new file mode 100644 index 000000000..12fa76e51 --- /dev/null +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/xpom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + org.eclipse.emf.compare + emf.compare-bundle-parent + 1.0.0-SNAPSHOT + ../../org.eclipse.emf.compare-parent/bundle-parent + + org.eclipse.emf.compare + org.eclipse.emf.compare.rcp.ui + 4.4.2-SNAPSHOT + eclipse-plugin + From 0ef598f3815fe8318e797ec804d834715f7108da Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Tue, 30 Apr 2024 18:39:32 -0400 Subject: [PATCH 2/6] Issue #443: Added Feature patch for o.e.emf.compare.rcp.ui Signed-off-by: Ernesto Posse --- .../.project | 17 ++++++++ .../build.properties | 5 +++ .../feature.properties | 43 +++++++++++++++++++ .../feature.xml | 31 +++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/.project create mode 100644 papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/build.properties create mode 100644 papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.properties create mode 100644 papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.xml diff --git a/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/.project b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/.project new file mode 100644 index 000000000..7d4753b0b --- /dev/null +++ b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/.project @@ -0,0 +1,17 @@ + + + com.zeligsoft.emf.compare.rcp.ui.patch.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/build.properties b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/build.properties new file mode 100644 index 000000000..a54095fcc --- /dev/null +++ b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/build.properties @@ -0,0 +1,5 @@ +bin.includes = feature.xml,\ + feature.properties +src.includes = feature.xml,\ + feature.properties,\ + build.properties diff --git a/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.properties b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.properties new file mode 100644 index 000000000..b2729c861 --- /dev/null +++ b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.properties @@ -0,0 +1,43 @@ +# +# Copyright 2018 ADLINK Technology Limited. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# "featureName" property - name of the feature +featureName=CX Patch for EMF Compare RCP UI + +# "providerName" property - name of the company that provides the feature +providerName=Zeligsoft (2009) Ltd. + +# "updateSiteName" property - label for the update site +updateSiteName=CX Patch for EMF Compare RCP UI + +# "description" property - description of the feature +description=Feature patch for EMF Compare RCP UI + +# "licenseURL" property - URL of the "Feature License" +# do not translate value - just change to point to a locale-specific HTML page +licenseURL=license.html + +# "license" property - text of the "Feature Update License" +# should be plain text version of license agreement pointed to be "licenseURL" +license=\ +SOFTWARE LICENSE AGREEMENT\n\ +\n\ +IMPORTANT -- PLEASE READ CAREFULLY:\nLicensed under the Apache License, Version 2.0 (the "License"); You may not use this file except in compliance with the License.\n\ +You may obtain a copy of the License at\n\n\ +http://www.apache.org/licenses/LICENSE-2.0 \n\n\ +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\ +See the License for the specific language governing permissions and limitations under the License. +########### end of license property ########################################## \ No newline at end of file diff --git a/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.xml b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.xml new file mode 100644 index 000000000..311b3c53b --- /dev/null +++ b/papyrus-patch/v4.8.0/com.zeligsoft.emf.compare.rcp.ui.patch.feature/feature.xml @@ -0,0 +1,31 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + From 591fa7f5dfba929fa5814bbb3e4e0733a3ba00cd Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Tue, 30 Apr 2024 18:42:50 -0400 Subject: [PATCH 3/6] Issue #443: Incorporated fix into CompareColotImpl Signed-off-by: Ernesto Posse --- .../mergeviewer/CompareColorImpl.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java index 6bb02ecfc..69e3dea80 100644 --- a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/mergeviewer/CompareColorImpl.java @@ -49,6 +49,9 @@ public class CompareColorImpl implements RemovalListener, ICompareCo /** Scale factor */ private static final double INTERPOLATION_SCALE_2 = 0.97; + + /** Scale factor for filling of a selected element */ + private static final double INTERPOLATION_SCALE_SELECTED_FILL = 0.3; /** Scale factor to compute the color of border. */ private static final double DARKER_BORDER_SCALE_FACTOR = -0.5; @@ -82,18 +85,24 @@ public class CompareColorImpl implements RemovalListener, ICompareCo private RGB incomingFill; + private RGB incommingSelectedFill; + private RGB conflictSelected; private RGB conflict; private RGB conflictFill; + private RGB conflictSelectedFill; + private RGB outgoingSelected; private RGB outgoing; private RGB outgoingFill; + private RGB outgoingSelectedFill; + private RGB requiredColor; private RGB requiredBorderColor; @@ -101,7 +110,7 @@ public class CompareColorImpl implements RemovalListener, ICompareCo private RGB unmergeableColor; private RGB unmergeableBorderColor; - + /** * Constructor. With this constructor the colors will disposed at the same as the control. * @@ -153,7 +162,6 @@ public Color getFillColor(Diff diff, boolean isThreeWay, boolean isIgnoreAncesto } private RGB getFillRGB(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, boolean selected) { - RGB selectedFill = getBackground(); if (isThreeWay && !isIgnoreAncestor) { boolean requiredConflictForWayOfMerge = false; @@ -161,21 +169,21 @@ private RGB getFillRGB(Diff diff, boolean isThreeWay, boolean isIgnoreAncestor, switch (diff.getSource()) { case RIGHT: if (fLeftIsLocal) { - return selected ? selectedFill : incomingFill; + return selected ? incommingSelectedFill : incomingFill; } - return selected ? selectedFill : outgoingFill; + return selected ? outgoingSelectedFill : outgoingFill; case LEFT: if (fLeftIsLocal) { - return selected ? selectedFill : outgoingFill; + return selected ? outgoingSelectedFill : outgoingFill; } - return selected ? selectedFill : incomingFill; + return selected ? incommingSelectedFill : incomingFill; } } else { - return selected ? selectedFill : conflictFill; + return selected ? conflictSelectedFill : conflictFill; } - return selected ? selectedFill : conflictFill; + return selected ? conflictSelectedFill : conflictFill; } - return selected ? selectedFill : outgoingFill; + return selected ? outgoingSelectedFill : outgoingFill; } /** @@ -234,6 +242,7 @@ protected final void updateColors() { } conflict = interpolate(conflictSelected, background, INTERPOLATION_SCALE_1); conflictFill = interpolate(conflictSelected, background, INTERPOLATION_SCALE_2); + conflictSelectedFill = interpolate(conflictSelected, background, INTERPOLATION_SCALE_SELECTED_FILL); outgoingSelected = fColorRegistry.getRGB(OUTGOING_CHANGE_COLOR_THEME_KEY); if (outgoingSelected == null) { @@ -241,6 +250,7 @@ protected final void updateColors() { } outgoing = interpolate(outgoingSelected, background, INTERPOLATION_SCALE_1); outgoingFill = interpolate(outgoingSelected, background, INTERPOLATION_SCALE_2); + outgoingSelectedFill = interpolate(outgoingSelected, background, INTERPOLATION_SCALE_SELECTED_FILL); incomingSelected = fColorRegistry.getRGB(INCOMING_CHANGE_COLOR_THEME_KEY); if (incomingSelected == null) { @@ -248,6 +258,7 @@ protected final void updateColors() { } incoming = interpolate(incomingSelected, background, INTERPOLATION_SCALE_1); incomingFill = interpolate(incomingSelected, background, INTERPOLATION_SCALE_2); + incommingSelectedFill = interpolate(incomingSelected, background, INTERPOLATION_SCALE_SELECTED_FILL); } /** From a5bc7dad6fdbad749bfe1c5309d5bbd58033ce81 Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Tue, 30 Apr 2024 18:44:38 -0400 Subject: [PATCH 4/6] Issue #443: Updated patches pom file Signed-off-by: Ernesto Posse --- papyrus-patch/v4.8.0/pom.xml | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/papyrus-patch/v4.8.0/pom.xml b/papyrus-patch/v4.8.0/pom.xml index ba2ee7b8a..e27c5c2d6 100644 --- a/papyrus-patch/v4.8.0/pom.xml +++ b/papyrus-patch/v4.8.0/pom.xml @@ -13,14 +13,18 @@ https://download.eclipse.org/releases/2020-06/ - https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository/ + + https://download.eclipse.org/tools/orbit/downloads/drops/R20200529191137/repository/ - https://download.eclipse.org/modeling/mdt/papyrus/updates/releases/2020-06/ + + https://download.eclipse.org/modeling/mdt/papyrus/updates/releases/2020-06/ https://archive.eclipse.org/tools/cdt/releases/9.11/ - https://download.eclipse.org/modeling/emf/compare/updates/releases/3.3/R202005260905/ - https://download.eclipse.org/modeling/mdt/papyrus/components/compare/updates/nightly/0.7.0-N20200430-193447/ + + https://download.eclipse.org/modeling/emf/compare/updates/releases/3.3/R202005260905/ + + https://download.eclipse.org/modeling/mdt/papyrus/components/compare/updates/nightly/0.7.0-N20200430-193447/ @@ -76,7 +80,8 @@ package package-feature - ${project.artifactId}_${unqualifiedVersion}.${buildQualifier} + + ${project.artifactId}_${unqualifiedVersion}.${buildQualifier} @@ -93,7 +98,8 @@ gtk x86_64 - @@ -103,17 +109,19 @@ - - org.eclipse.papyrus.uml.properties - org.eclipse.papyrus.views.modelexplorer - + com.zeligsoft.emf.compare.rcp.ui.patch.feature com.zeligsoft.papyrus.uml.properties.patch.feature com.zeligsoft.papyrus.views.modelexplorer.patch.feature site-papyrus-patch - + From 741117f5d256ed104db9d439b93014f47a5ba978 Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Tue, 21 May 2024 18:35:16 -0400 Subject: [PATCH 5/6] Issue #443: Resolving indirect dependency Signed-off-by: Ernesto Posse --- .../v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF index aa955c2c8..6000898be 100644 --- a/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF +++ b/papyrus-patch/v4.8.0/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.eclipse.emf.compare.rcp.ui;singleton:=true Bundle-Version: 4.4.2.qualifier Bundle-Activator: org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin Bundle-Vendor: %providerName -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", From 117725653a7183f243bfee3741e928b4e3239004 Mon Sep 17 00:00:00 2001 From: Ernesto Posse Date: Wed, 22 May 2024 16:46:08 -0400 Subject: [PATCH 6/6] Issue #443: (v2) Added new EMF Compare patch to product and site Signed-off-by: Ernesto Posse --- papyrus-patch/v4.8.0/site-papyrus-patch/site.xml | 3 +++ .../papyrus-cx-axcioma.product | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/papyrus-patch/v4.8.0/site-papyrus-patch/site.xml b/papyrus-patch/v4.8.0/site-papyrus-patch/site.xml index 37d9d06ac..13f2846a3 100644 --- a/papyrus-patch/v4.8.0/site-papyrus-patch/site.xml +++ b/papyrus-patch/v4.8.0/site-papyrus-patch/site.xml @@ -6,6 +6,9 @@ + + + Provides Papyrus patches for CX4CBDDS. diff --git a/releng/com.zeligsoft.papyrus-cx.axcioma.rcp.product/papyrus-cx-axcioma.product b/releng/com.zeligsoft.papyrus-cx.axcioma.rcp.product/papyrus-cx-axcioma.product index 1ea159c34..3a07d2084 100644 --- a/releng/com.zeligsoft.papyrus-cx.axcioma.rcp.product/papyrus-cx-axcioma.product +++ b/releng/com.zeligsoft.papyrus-cx.axcioma.rcp.product/papyrus-cx-axcioma.product @@ -1,7 +1,7 @@ - + @@ -105,6 +105,7 @@ +