Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Goubet2013-02-14 15:11:36 +0000
committerLaurent Goubet2013-02-14 15:11:36 +0000
commit24c860931d5283803d50ed9a9f642b7b88c2b2e1 (patch)
tree3a9122b7c415ab0d6c4cf65c93b543caec2e79a2
parent4d93a07d7b5166770070114330e6e97f1c9cc9fb (diff)
parentdbb9d0adbf6908a99821a0a9e101fa264aebbf1d (diff)
downloadorg.eclipse.emf.compare-24c860931d5283803d50ed9a9f642b7b88c2b2e1.tar.gz
org.eclipse.emf.compare-24c860931d5283803d50ed9a9f642b7b88c2b2e1.tar.xz
org.eclipse.emf.compare-24c860931d5283803d50ed9a9f642b7b88c2b2e1.zip
Merge branch 'master' into logical_experimentation
Conflicts: plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/AbstractTest.java8
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/merge/ExtensionMergeTest.java90
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/suite/AllTests.java3
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/pom.xml2
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractEditPartMergeViewer.java (renamed from plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/DMergeViewer.java)21
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractGraphicalMergeViewer.java (renamed from plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/GraphicalMergeViewer.java)30
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DeleteGhostImageFigure.java23
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DiffDecorationEditPolicy.java20
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/DiffDecoratorProvider.java17
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/SelectedDiffAdapter.java37
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramContentMergeViewerConstants.java9
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramIDEDiffAccessorImpl.java14
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/DiagramCompareContentMergeViewer.java21
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramContentMergeViewer.java23
-rw-r--r--plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramMergeViewer.java9
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/plugin.xml7
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src-gen/org/eclipse/emf/compare/diagram/impl/DiagramDiffImpl.java112
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramComparisonConfiguration.java27
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramDiffExtensionPostProcessor.java78
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/AbstractDiffExtensionFactory.java253
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/DiffExtensionFactoryRegistry.java8
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/IDiffExtensionFactory.java38
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/EdgeChangeFactory.java78
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/HideFactory.java21
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/NodeChangeFactory.java56
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/ShowFactory.java16
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareConstants.java7
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareUIMessages.java5
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/GMFLabelUtil.java8
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/merge/DiagramDiffMerger.java124
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionDescriptor.java14
-rw-r--r--plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionRegistry.java4
-rw-r--r--plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/add_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/add_ov.gif)bin186 -> 186 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/chg_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/chg_ov.gif)bin187 -> 187 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confadd_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confadd_ov.png)bin215 -> 215 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confchg_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confchg_ov.png)bin205 -> 205 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confdel_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confdel_ov.png)bin207 -> 207 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_add_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_add_ov.png)bin222 -> 222 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_chg_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_chg_ov.png)bin204 -> 204 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_del_ov.png (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_del_ov.png)bin211 -> 211 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/del_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/del_ov.gif)bin184 -> 184 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/error_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/error_ov.gif)bin339 -> 339 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inadd_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inadd_ov.gif)bin194 -> 194 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inchg_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inchg_ov.gif)bin191 -> 191 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/indel_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/indel_ov.gif)bin190 -> 190 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inoutchg_ov.gifbin0 -> 299 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/merged_ov.gifbin0 -> 185 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outadd_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outadd_ov.gif)bin190 -> 190 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outchg_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outchg_ov.gif)bin194 -> 194 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outdel_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outdel_ov.gif)bin188 -> 188 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inadd_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inadd_ov.gif)bin194 -> 194 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inchg_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inchg_ov.gif)bin190 -> 190 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_indel_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_indel_ov.gif)bin190 -> 190 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inoutchg_ov.gifbin0 -> 300 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outadd_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outadd_ov.gif)bin190 -> 190 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outchg_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outchg_ov.gif)bin196 -> 196 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outdel_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outdel_ov.gif)bin188 -> 188 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/removed_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/removed_ov.gif)bin131 -> 131 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/warning_ov.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/warning_ov.gif)bin324 -> 324 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.edit/plugin.properties167
-rw-r--r--plugins/org.eclipse.emf.compare.edit/plugin.xml3
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src-gen/org/eclipse/emf/compare/provider/EMFCompareEditPlugin.java205
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/AbstractCopyCommand.java95
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java80
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java68
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java14
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java20
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/IItemStyledLabelProvider.java18
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/AttributeChangeItemProviderSpec.java92
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/CompareItemProviderAdapterFactorySpec.java234
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ComparisonItemProviderSpec.java203
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ConflictItemProviderSpec.java23
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchItemProviderSpec.java528
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchResourceItemProviderSpec.java261
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/OverlayImageProvider.java342
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ReferenceChangeItemProviderSpec.java511
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ResourceAttachmentChangeItemProviderSpec.java178
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/ComposedStyledString.java108
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/IStyledString.java259
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF87
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/merged_ov.gifbin176 -> 0 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/plugin.xml425
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/pom.xml2
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java100
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java91
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java108
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java33
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java93
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java49
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java196
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java1117
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java54
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java78
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEStringAttributeChangeAccessor.java23
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java68
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java740
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java414
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java58
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewerContentProvider.java2
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewer.java4
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewerContentProvider.java7
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffContainer.java120
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffElement.java157
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffNode.java60
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DiffNodeComparer.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java261
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java105
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java280
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/AttributeChangeNode.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/CompareNodeAdapterFactory.java9
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/ConflictNode.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/MatchNode.java11
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/StyledStringConverter.java120
-rw-r--r--plugins/org.eclipse.emf.compare.ide/plugin.xml23
-rw-r--r--plugins/org.eclipse.emf.compare.ide/schema/MergerExtension.exsd129
-rw-r--r--plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/EMFCompareIDEPlugin.java123
-rw-r--r--plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/emfcompareidemessages.properties5
-rw-r--r--plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java56
-rw-r--r--plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/SyncResourceSet.java7
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF16
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/build.properties19
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif)bin219 -> 219 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif (renamed from plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif)bin307 -> 307 bytes
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml64
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/pom.xml2
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd116
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd116
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java133
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java365
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java249
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java368
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java620
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java192
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java316
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java574
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java28
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/AbstractAccessorFactory.java)38
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java62
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java233
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java67
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java104
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java)107
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java120
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java114
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java114
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/EmptyMatchedResourcesFilter.java135
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java211
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java94
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java115
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java115
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java)381
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java)266
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java82
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java)107
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java220
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java105
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java)256
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java)278
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java110
-rw-r--r--plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/FuzzyTest.java23
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java150
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fragmentation/FragmentationTest.java66
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DynamicInstanceComparisonTest.java23
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ExtensionMergeTest.java94
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeOutOfScopeValuesTest.java78
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeTest.java150
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java162
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java10
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.edit/plugin.xml3
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/ForwardingUMLDiffItemProvider.java99
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/StereotypeApplicationChangeItemProviderSpec.java115
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/UMLCompareAdapterFactorySpec.java6
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/AbstractTest.java33
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/association/AddAssociationTest.java31
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/ExtensionMergeTest.java89
-rw-r--r--plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java5
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/plugin.xml7
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/src-gen/org/eclipse/emf/compare/uml2/impl/UMLDiffImpl.java98
-rw-r--r--plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/merge/UMLDiffMerger.java102
-rw-r--r--plugins/org.eclipse.emf.compare/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.emf.compare/build.properties1
-rw-r--r--plugins/org.eclipse.emf.compare/model/compare.ecore4
-rw-r--r--plugins/org.eclipse.emf.compare/model/compare.genmodel5
-rw-r--r--plugins/org.eclipse.emf.compare/plugin.xml24
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/ComparePackage.java3742
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Comparison.java337
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Diff.java10
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/MatchResource.java427
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparePackageImpl.java2032
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparisonImpl.java791
-rw-r--r--plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/MatchResourceImpl.java1022
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/emfcomparemessages.properties4
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/MatchCrossReferencer.java11
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/ModelIdentifier.java169
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/AttributeChangeSpec.java433
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java83
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ReferenceChangeSpec.java880
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ResourceAttachmentChangeSpec.java473
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AbstractMerger.java190
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AttributeChangeMerger.java474
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java126
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IBatchMerger.java46
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IMerger.java292
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ReferenceChangeMerger.java714
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ResourceAttachmentChangeMerger.java475
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/DiffUtil.java268
213 files changed, 18515 insertions, 12342 deletions
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/META-INF/MANIFEST.MF
index 8ae37404d..3b581f853 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/META-INF/MANIFEST.MF
@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.5.0",
org.eclipse.gmf.runtime.emf.core;bundle-version="1.2.2",
org.eclipse.gmf.runtime.notation;bundle-version="1.2.0",
org.eclipse.emf.compare.diagram.ide.ecoretools;bundle-version="2.0.0",
- org.eclipse.ui;bundle-version="3.5.0"
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.emf.compare.uml2;bundle-version="2.1.0"
Import-Package: com.google.common.base;version="[10.0.1,11.0.0)",
com.google.common.collect;version="[10.0.1,11.0.0)"
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/AbstractTest.java b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/AbstractTest.java
index 5c4e0b68e..7dd6cc3c0 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/AbstractTest.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/AbstractTest.java
@@ -4,6 +4,7 @@ import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.diagram.diff.DiagramDiffExtensionPostProcessor;
import org.eclipse.emf.compare.extension.PostProcessorDescriptor;
import org.eclipse.emf.compare.extension.PostProcessorRegistry;
@@ -18,6 +19,8 @@ import com.google.common.collect.Iterators;
@SuppressWarnings("nls")
public abstract class AbstractTest {
+ private EMFCompare emfCompare;
+
private PostProcessorRegistry postProcessorRegistry;
@Before
@@ -27,8 +30,13 @@ public abstract class AbstractTest {
"http://www.eclipse.org/gmf/runtime/\\d.\\d.\\d/notation", null,
"org.eclipse.emf.compare.diagram.diff.DiagramDiffExtensionPostProcessor",
new DiagramDiffExtensionPostProcessor()));
+ emfCompare = EMFCompare.builder().setPostProcessorRegistry(postProcessorRegistry).build();
}
+ protected EMFCompare getCompare() {
+ return emfCompare;
+ }
+
/**
* @return the postProcessorRegistry
*/
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/merge/ExtensionMergeTest.java b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/merge/ExtensionMergeTest.java
new file mode 100644
index 000000000..1bfe3a4c7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/merge/ExtensionMergeTest.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * 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.diagram.ecoretools.tests.merge;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.diagram.DiagramDiff;
+import org.eclipse.emf.compare.diagram.ecoretools.tests.AbstractTest;
+import org.eclipse.emf.compare.diagram.ecoretools.tests.DiagramInputData;
+import org.eclipse.emf.compare.diagram.ecoretools.tests.edgechanges.data.EdgeChangesInputData;
+import org.eclipse.emf.compare.diagram.merge.DiagramDiffMerger;
+import org.eclipse.emf.compare.merge.AttributeChangeMerger;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.merge.ReferenceChangeMerger;
+import org.eclipse.emf.compare.merge.ResourceAttachmentChangeMerger;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.uml2.UMLDiff;
+import org.eclipse.emf.compare.uml2.merge.UMLDiffMerger;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class ExtensionMergeTest extends AbstractTest {
+ private EdgeChangesInputData input = new EdgeChangesInputData();
+
+ @Test
+ public void testInstantiationMerger() throws IOException {
+ final Resource left = input.getA1Left();
+ final Resource right = input.getA1Right();
+
+ testMergeRightToLeft(left, right, null);
+ }
+
+
+ protected void testMergeRightToLeft(Notifier left, Notifier right, Notifier origin) {
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left, right, origin);
+ final Comparison comparisonBefore = getCompare().compare(scope);
+ EList<Diff> differences = comparisonBefore.getDifferences();
+ final IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ final IMerger umlMerger = new UMLDiffMerger();
+ umlMerger.setRanking(11);
+ final IMerger diagramMerger = new DiagramDiffMerger();
+ diagramMerger.setRanking(11);
+ registry.add(umlMerger);
+ registry.add(diagramMerger);
+ for (Diff diff : differences) {
+ final Class<? extends IMerger> expectedMerger;
+ if (diff instanceof DiagramDiff) {
+ expectedMerger = DiagramDiffMerger.class;
+ } else if (diff instanceof UMLDiff) {
+ expectedMerger = UMLDiffMerger.class;
+ } else if (diff instanceof AttributeChange) {
+ expectedMerger = AttributeChangeMerger.class;
+ } else if (diff instanceof ReferenceChange) {
+ expectedMerger = ReferenceChangeMerger.class;
+ } else {
+ expectedMerger = ResourceAttachmentChangeMerger.class;
+ }
+ IMerger merger = org.eclipse.emf.compare.tests.merge.ExtensionMergeTest.getMerger(registry, diff,
+ expectedMerger);
+ merger.copyRightToLeft(diff, null);
+ }
+ final Comparison comparisonAfter = getCompare().compare(scope);
+ assertTrue("Comparison#getDifferences() must be empty after copyAllRightToLeft", comparisonAfter
+ .getDifferences().isEmpty());
+ }
+
+ @Override
+ protected DiagramInputData getInput() {
+ return input;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/suite/AllTests.java
index 687416147..1a7cb9c70 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ecoretools.tests/src/org/eclipse/emf/compare/diagram/ecoretools/tests/suite/AllTests.java
@@ -18,6 +18,7 @@ import org.eclipse.emf.compare.ComparePackage;
import org.eclipse.emf.compare.diagram.DiagramComparePackage;
import org.eclipse.emf.compare.diagram.ecoretools.tests.edgechanges.EdgechangesTest;
import org.eclipse.emf.compare.diagram.ecoretools.tests.hide.HideTest;
+import org.eclipse.emf.compare.diagram.ecoretools.tests.merge.ExtensionMergeTest;
import org.eclipse.emf.compare.diagram.ecoretools.tests.nodechanges.NodechangesTest;
import org.eclipse.emf.compare.diagram.ecoretools.tests.show.ShowTest;
import org.eclipse.emf.compare.tests.suite.CompareTestSuite;
@@ -38,7 +39,7 @@ import org.junit.runners.Suite.SuiteClasses;
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
@RunWith(Suite.class)
-@SuiteClasses({HideTest.class, ShowTest.class, NodechangesTest.class, EdgechangesTest.class})
+@SuiteClasses({HideTest.class, ShowTest.class, NodechangesTest.class, EdgechangesTest.class, ExtensionMergeTest.class})
public class AllTests {
/**
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.diagram.ide.ui/META-INF/MANIFEST.MF
index 3b108c3ea..c806d8934 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.emf.compare.diagram.ide.ui;singleton:=true
-Bundle-Version: 2.1.0.qualifier
+Bundle-Version: 3.0.0.qualifier
Bundle-Activator: org.eclipse.emf.compare.diagram.ide.ui.GMFCompareUIPlugin
Require-Bundle: org.eclipse.compare,
org.eclipse.emf.compare,
org.eclipse.gmf.runtime.diagram.ui,
org.eclipse.emf.compare.diagram,
- org.junit,
+ org.eclipse.emf.compare.ide;bundle-version="3.0.0",
org.eclipse.emf.compare.ide.ui;bundle-version="2.1.0",
org.eclipse.emf.compare.rcp.ui;bundle-version="2.1.0",
org.eclipse.emf.compare.diagram.ide;bundle-version="2.0.0",
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/pom.xml b/plugins/org.eclipse.emf.compare.diagram.ide.ui/pom.xml
index b45d08df9..4b4195497 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/pom.xml
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>org.eclipse.emf.compare</groupId>
<artifactId>org.eclipse.emf.compare.diagram.ide.ui</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/DMergeViewer.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractEditPartMergeViewer.java
index 046a21c4f..908b96ec0 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/DMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractEditPartMergeViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -15,25 +15,38 @@ import org.eclipse.gef.ui.parts.AbstractEditPartViewer;
import org.eclipse.jface.viewers.ISelection;
/**
+ * Abstract viewer for comparison of graphical elements.
+ *
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ * @since 3.0
*/
-public abstract class DMergeViewer extends AbstractEditPartViewer {
+public abstract class AbstractEditPartMergeViewer extends AbstractEditPartViewer {
+ /** The side that manages this viewer. */
private final MergeViewerSide fSide;
/**
+ * Constructor.
*
+ * @param side
+ * The side having to be handle.
*/
- public DMergeViewer(MergeViewerSide side) {
+ public AbstractEditPartMergeViewer(MergeViewerSide side) {
fSide = side;
}
+ /**
+ * Set the input of the viewer.
+ *
+ * @param object
+ * The input.
+ */
public abstract void setInput(Object object);
/**
* Returns the wrapped {@link AbstractEditPartViewer}.
*
- * @return
+ * @return The viewer.
*/
protected abstract AbstractEditPartViewer getGraphicalViewer();
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/GraphicalMergeViewer.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractGraphicalMergeViewer.java
index b1296417d..401ee4d0c 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/GraphicalMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/AbstractGraphicalMergeViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -20,20 +20,28 @@ import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
/**
+ * Abstract graphical merge viewer for comparison of graphical elements.
+ *
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ * @since 3.0
*/
-public abstract class GraphicalMergeViewer extends DMergeViewer {
-
- private final ISelectionChangedListener fForwardingSelectionListener;
+public abstract class AbstractGraphicalMergeViewer extends AbstractEditPartMergeViewer {
- /** the diagram edit domain. */
+ /** The diagram edit domain. */
protected DiagramEditDomain editDomain;
+ /** Listener for forwarding selection. */
+ private final ISelectionChangedListener fForwardingSelectionListener;
+
/**
+ * The constructor.
+ *
* @param parent
+ * The parent composite.
* @param side
+ * The side having to be handle.
*/
- public GraphicalMergeViewer(Composite parent, MergeViewerSide side) {
+ public AbstractGraphicalMergeViewer(Composite parent, MergeViewerSide side) {
super(side);
editDomain = new DiagramEditDomain(null);
@@ -46,6 +54,11 @@ public abstract class GraphicalMergeViewer extends DMergeViewer {
// getGraphicalViewer().addSelectionChangedListener(fForwardingSelectionListener);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ */
@Override
protected void handleDispose(DisposeEvent event) {
// getGraphicalViewer().removeSelectionChangedListener(fForwardingSelectionListener);
@@ -55,11 +68,14 @@ public abstract class GraphicalMergeViewer extends DMergeViewer {
/**
* {@inheritDoc}
*
- * @see org.eclipse.emf.compare.diagram.ide.ui.DMergeViewer#getGraphicalViewer()
+ * @see org.eclipse.emf.compare.diagram.ide.ui.AbstractEditPartMergeViewer#getGraphicalViewer()
*/
@Override
protected abstract AbstractEditPartViewer getGraphicalViewer();
+ /**
+ * Listener for forwarding selection.
+ */
private class ForwardingViewerSelectionListener implements ISelectionChangedListener {
/**
* {@inheritDoc}
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DeleteGhostImageFigure.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DeleteGhostImageFigure.java
index e0f34cbe8..b4f643ac9 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DeleteGhostImageFigure.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DeleteGhostImageFigure.java
@@ -1,10 +1,28 @@
+/*******************************************************************************
+ * 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.diagram.ide.ui.decoration;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.RectangleFigure;
+/**
+ * Figure to represent a phantom of a graphical object.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
public class DeleteGhostImageFigure extends RectangleFigure {
+ /**
+ * Constructor.
+ */
public DeleteGhostImageFigure() {
super();
}
@@ -13,6 +31,11 @@ public class DeleteGhostImageFigure extends RectangleFigure {
// super(figure, alpha, transparency);
// }
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.draw2d.Shape#paintFigure(org.eclipse.draw2d.Graphics)
+ */
@Override
public void paintFigure(Graphics graphics) {
super.paintFigure(graphics);
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DiffDecorationEditPolicy.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DiffDecorationEditPolicy.java
index bf22073b2..e67fd1b81 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DiffDecorationEditPolicy.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/DiffDecorationEditPolicy.java
@@ -1,9 +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.diagram.ide.ui.decoration;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.DecorationEditPolicy;
+/**
+ * DecorationEditPolicy which forces the creation of decorators after each refresh.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
public class DiffDecorationEditPolicy extends DecorationEditPolicy {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.DecorationEditPolicy#refresh()
+ */
@Override
public void refresh() {
decorators = null;
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/DiffDecoratorProvider.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/DiffDecoratorProvider.java
index 54f74c817..c146f741d 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/DiffDecoratorProvider.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/DiffDecoratorProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -8,7 +8,6 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
-
package org.eclipse.emf.compare.diagram.ide.ui.decoration.provider;
import java.util.Iterator;
@@ -150,6 +149,13 @@ public class DiffDecoratorProvider extends AbstractProvider implements IDecorato
return view != null && (view instanceof Node);
}
+ /**
+ * Get the graphical difference in relation to the given view.
+ *
+ * @param view
+ * The view.
+ * @return The graphical difference.
+ */
public static DiagramDiff getRelatedSelectedDifference(View view) {
SelectedDiffAdapter adapter = getSelectedDiffAdapter(view);
if (adapter != null) {
@@ -161,6 +167,13 @@ public class DiffDecoratorProvider extends AbstractProvider implements IDecorato
return null;
}
+ /**
+ * Get a <code>SelectedDiffAdapter</code> if it exists, on the given view.
+ *
+ * @param view
+ * The view.
+ * @return The adapter or null.
+ */
private static SelectedDiffAdapter getSelectedDiffAdapter(View view) {
Iterator<Adapter> adapters = view.eAdapters().iterator();
while (adapters.hasNext()) {
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/SelectedDiffAdapter.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/SelectedDiffAdapter.java
index 68cb91e81..7a72447f4 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/SelectedDiffAdapter.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/decoration/provider/SelectedDiffAdapter.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * 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.diagram.ide.ui.decoration.provider;
import org.eclipse.emf.common.notify.Adapter;
@@ -5,14 +15,31 @@ import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.compare.diagram.DiagramDiff;
+/**
+ * Adapter to retrieve the graphical differences on an object.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
public class SelectedDiffAdapter implements Adapter {
+ /** A graphical difference. */
private DiagramDiff diff;
+ /**
+ * Constructor.
+ *
+ * @param diff
+ * A graphical difference.
+ */
public SelectedDiffAdapter(DiagramDiff diff) {
this.diff = diff;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
+ */
public void notifyChanged(Notification notification) {
// TODO Auto-generated method stub
@@ -22,12 +49,22 @@ public class SelectedDiffAdapter implements Adapter {
return diff;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
+ */
public void setTarget(Notifier newTarget) {
if (newTarget instanceof DiagramDiff) {
this.diff = (DiagramDiff)newTarget;
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object)
+ */
public boolean isAdapterForType(Object type) {
return type == DiagramDiff.class;
}
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramContentMergeViewerConstants.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramContentMergeViewerConstants.java
index 9fc39a811..872bc309c 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramContentMergeViewerConstants.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramContentMergeViewerConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -11,14 +11,21 @@
package org.eclipse.emf.compare.diagram.ide.ui.internal.accessor;
/**
+ * Constants used in accessors for diagrams comparison.
+ *
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public final class DiagramContentMergeViewerConstants {
+ /** DIFF_NODE_TYPE. */
public static final String DIFF_NODE_TYPE = "diagramcompare_diff"; //$NON-NLS-1$
+ /** MATCH_NODE_TYPE. */
public static final String MATCH_NODE_TYPE = "diagramcompare_match"; //$NON-NLS-1$
+ /**
+ * Constructor.
+ */
private DiagramContentMergeViewerConstants() {
}
}
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramIDEDiffAccessorImpl.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramIDEDiffAccessorImpl.java
index fc59d799a..2da084afb 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramIDEDiffAccessorImpl.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/accessor/DiagramIDEDiffAccessorImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -16,15 +16,22 @@ import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.ecore.EObject;
/**
+ * Accessor on a graphical difference.
+ *
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class DiagramIDEDiffAccessorImpl extends DiagramIDEMatchAccessorImpl implements IDiagramDiffAccessor {
+ /** A graphical difference. */
private DiagramDiff fDiff;
/**
+ * Constructor.
+ *
* @param diff
+ * A graphical difference.
* @param side
+ * The side where the change is.
*/
public DiagramIDEDiffAccessorImpl(DiagramDiff diff, MergeViewerSide side) {
super(diff.getMatch(), side);
@@ -45,6 +52,11 @@ public class DiagramIDEDiffAccessorImpl extends DiagramIDEMatchAccessorImpl impl
return fDiff;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IEObjectAccessor#getEObject()
+ */
public EObject getEObject() {
if (fDiff instanceof DiagramDiff) {
return ((DiagramDiff)fDiff).getView();
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/DiagramCompareContentMergeViewer.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/DiagramCompareContentMergeViewer.java
index 029f35948..d8f5328d3 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/DiagramCompareContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/DiagramCompareContentMergeViewer.java
@@ -26,8 +26,9 @@ import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.diagram.ide.ui.DMergeViewer;
+import org.eclipse.emf.compare.diagram.ide.ui.AbstractEditPartMergeViewer;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree.TreeContentMergeViewerContentProvider;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
@@ -74,11 +75,11 @@ public abstract class DiagramCompareContentMergeViewer extends ContentMergeViewe
*/
protected static final int CENTER_WIDTH = 34;
- protected DMergeViewer fAncestor;
+ protected AbstractEditPartMergeViewer fAncestor;
- protected DMergeViewer fLeft;
+ protected AbstractEditPartMergeViewer fLeft;
- protected DMergeViewer fRight;
+ protected AbstractEditPartMergeViewer fRight;
private ActionContributionItem fCopyDiffLeftToRightItem;
@@ -377,7 +378,7 @@ public abstract class DiagramCompareContentMergeViewer extends ContentMergeViewe
EList<Diff> differences = getComparison().getDifferences();
final Command copyCommand = getEditingDomain().createCopyAllNonConflictingCommand(differences,
- leftToRight);
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
getEditingDomain().getCommandStack().execute(copyCommand);
@@ -439,7 +440,7 @@ public abstract class DiagramCompareContentMergeViewer extends ContentMergeViewe
fRight.getControl().setBounds(x + width1 + centerWidth, y, width2, height);
}
- protected abstract DMergeViewer createMergeViewer(Composite parent, MergeViewerSide side,
+ protected abstract AbstractEditPartMergeViewer createMergeViewer(Composite parent, MergeViewerSide side,
DiagramCompareContentMergeViewer master);
@Override
@@ -491,21 +492,21 @@ public abstract class DiagramCompareContentMergeViewer extends ContentMergeViewe
/**
* @return the fAncestor
*/
- public DMergeViewer getAncestorMergeViewer() {
+ public AbstractEditPartMergeViewer getAncestorMergeViewer() {
return fAncestor;
}
/**
* @return the fLeft
*/
- public DMergeViewer getLeftMergeViewer() {
+ public AbstractEditPartMergeViewer getLeftMergeViewer() {
return fLeft;
}
/**
* @return the fRight
*/
- public DMergeViewer getRightMergeViewer() {
+ public AbstractEditPartMergeViewer getRightMergeViewer() {
return fRight;
}
@@ -561,7 +562,7 @@ public abstract class DiagramCompareContentMergeViewer extends ContentMergeViewe
* The viewer which selection is to be checked.
* @return The first of the Diffs selected in the given viewer, if any.
*/
- protected Diff getDiffFrom(DMergeViewer viewer) {
+ protected Diff getDiffFrom(AbstractEditPartMergeViewer viewer) {
Diff diff = null;
final ISelection selection = viewer.getSelection();
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramContentMergeViewer.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramContentMergeViewer.java
index 47d679479..30cda9a3e 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramContentMergeViewer.java
@@ -42,12 +42,13 @@ import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.diagram.DiagramDiff;
import org.eclipse.emf.compare.diagram.NodeChange;
-import org.eclipse.emf.compare.diagram.ide.ui.DMergeViewer;
-import org.eclipse.emf.compare.diagram.ide.ui.GraphicalMergeViewer;
+import org.eclipse.emf.compare.diagram.ide.ui.AbstractEditPartMergeViewer;
+import org.eclipse.emf.compare.diagram.ide.ui.AbstractGraphicalMergeViewer;
import org.eclipse.emf.compare.diagram.ide.ui.decoration.DeleteGhostImageFigure;
import org.eclipse.emf.compare.diagram.ide.ui.internal.accessor.IDiagramDiffAccessor;
import org.eclipse.emf.compare.diagram.ide.ui.internal.accessor.IDiagramNodeAccessor;
import org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.DiagramCompareContentMergeViewer;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree.TreeContentMergeViewerContentProvider;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.DiffNode;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
@@ -143,8 +144,8 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
@SuppressWarnings("unchecked")
// see createMergeViewer() to see it is safe
@Override
- public GraphicalMergeViewer getAncestorMergeViewer() {
- return (GraphicalMergeViewer)super.getAncestorMergeViewer();
+ public AbstractGraphicalMergeViewer getAncestorMergeViewer() {
+ return (AbstractGraphicalMergeViewer)super.getAncestorMergeViewer();
}
/**
@@ -155,8 +156,8 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
@SuppressWarnings("unchecked")
// see createMergeViewer() to see it is safe
@Override
- public GraphicalMergeViewer getLeftMergeViewer() {
- return (GraphicalMergeViewer)super.getLeftMergeViewer();
+ public AbstractGraphicalMergeViewer getLeftMergeViewer() {
+ return (AbstractGraphicalMergeViewer)super.getLeftMergeViewer();
}
/**
@@ -167,8 +168,8 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
@SuppressWarnings("unchecked")
// see createMergeViewer() to see it is safe
@Override
- public GraphicalMergeViewer getRightMergeViewer() {
- return (GraphicalMergeViewer)super.getRightMergeViewer();
+ public AbstractGraphicalMergeViewer getRightMergeViewer() {
+ return (AbstractGraphicalMergeViewer)super.getRightMergeViewer();
}
/**
@@ -185,7 +186,7 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
*/
if (getInput() instanceof DiffNode) {
final Command command = getEditingDomain().createCopyCommand(((DiffNode)getInput()).getTarget(),
- leftToRight);
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
getEditingDomain().getCommandStack().execute(command);
if (leftToRight) {
@@ -211,7 +212,7 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
List<Diff> differences = getComparison().getDifferences((EObject)elt);
final Command command = getEditingDomain().createCopyAllNonConflictingCommand(differences,
- leftToRight);
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
getEditingDomain().getCommandStack().execute(command);
if (leftToRight) {
@@ -241,7 +242,7 @@ public class DiagramContentMergeViewer extends DiagramCompareContentMergeViewer
* @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite)
*/
@Override
- protected DMergeViewer createMergeViewer(final Composite parent, MergeViewerSide side,
+ protected AbstractEditPartMergeViewer createMergeViewer(final Composite parent, MergeViewerSide side,
DiagramCompareContentMergeViewer master) {
final DiagramMergeViewer mergeTreeViewer = new DiagramMergeViewer(parent, side);
return mergeTreeViewer;
diff --git a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramMergeViewer.java b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramMergeViewer.java
index 9d5c98930..2ca90cc4a 100644
--- a/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.diagram.ide.ui/src/org/eclipse/emf/compare/diagram/ide/ui/internal/contentmergeviewer/diagram/DiagramMergeViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -26,7 +26,7 @@ import org.eclipse.emf.compare.diagram.Hide;
import org.eclipse.emf.compare.diagram.LabelChange;
import org.eclipse.emf.compare.diagram.NodeChange;
import org.eclipse.emf.compare.diagram.Show;
-import org.eclipse.emf.compare.diagram.ide.ui.GraphicalMergeViewer;
+import org.eclipse.emf.compare.diagram.ide.ui.AbstractGraphicalMergeViewer;
import org.eclipse.emf.compare.diagram.ide.ui.decoration.DiffDecorationEditPolicy;
import org.eclipse.emf.compare.diagram.ide.ui.decoration.provider.DiffDecoratorProvider;
import org.eclipse.emf.compare.diagram.ide.ui.decoration.provider.SelectedDiffAdapter;
@@ -55,7 +55,10 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
-class DiagramMergeViewer extends GraphicalMergeViewer {
+/**
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
+class DiagramMergeViewer extends AbstractGraphicalMergeViewer {
private IDiagramNodeAccessor fInput;
diff --git a/plugins/org.eclipse.emf.compare.diagram/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.diagram/META-INF/MANIFEST.MF
index fd6ddf5e1..224332ea4 100644
--- a/plugins/org.eclipse.emf.compare.diagram/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.diagram/META-INF/MANIFEST.MF
@@ -10,12 +10,14 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.emf.compare.diagram,
org.eclipse.emf.compare.diagram.diff,
org.eclipse.emf.compare.diagram.diff.util,
+ org.eclipse.emf.compare.diagram.merge,
org.eclipse.emf.compare.diagram.provider,
org.eclipse.emf.compare.diagram.util
Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport,
org.eclipse.gmf.runtime.notation,
org.eclipse.gmf.runtime.diagram.ui,
- org.eclipse.emf.compare;bundle-version="2.0.0"
+ org.eclipse.emf.compare;bundle-version="2.0.0",
+ org.eclipse.emf.compare.ide;bundle-version="3.0.0"
Import-Package: com.google.common.base;version="10.0.1",
com.google.common.collect;version="10.0.1"
Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.emf.compare.diagram/plugin.xml b/plugins/org.eclipse.emf.compare.diagram/plugin.xml
index 589e41c11..ed00bb47a 100644
--- a/plugins/org.eclipse.emf.compare.diagram/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.diagram/plugin.xml
@@ -27,5 +27,12 @@
</nsURI>
</postProcessor>
</extension>
+ <extension
+ point="org.eclipse.emf.compare.ide.mergerExtension">
+ <merger
+ class="org.eclipse.emf.compare.diagram.merge.DiagramDiffMerger"
+ ranking="11">
+ </merger>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.compare.diagram/src-gen/org/eclipse/emf/compare/diagram/impl/DiagramDiffImpl.java b/plugins/org.eclipse.emf.compare.diagram/src-gen/org/eclipse/emf/compare/diagram/impl/DiagramDiffImpl.java
index 7e3c36b3e..f9549e73b 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src-gen/org/eclipse/emf/compare/diagram/impl/DiagramDiffImpl.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src-gen/org/eclipse/emf/compare/diagram/impl/DiagramDiffImpl.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -11,12 +11,12 @@
package org.eclipse.emf.compare.diagram.impl;
import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceSource;
-import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.diagram.DiagramComparePackage;
import org.eclipse.emf.compare.diagram.DiagramDiff;
import org.eclipse.emf.compare.impl.DiffImpl;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
@@ -233,111 +233,17 @@ public abstract class DiagramDiffImpl extends DiffImpl implements DiagramDiff {
return super.eIsSet(featureID);
}
+ @Deprecated
@Override
public void copyLeftToRight() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- setEquivalentDiffAsMerged();
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getSemanticDiff() != null) {
- for (Diff semanticRefines : getSemanticDiff().getRefines()) {
- semanticRefines.copyLeftToRight();
- }
- getSemanticDiff().copyLeftToRight();
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "requires" diffs
- mergeRequires(false);
- } else {
- // merge all "required by" diffs
- mergeRequiredBy(false);
- }
-
- for (Diff diff : getRefinedBy()) {
- diff.copyLeftToRight();
- }
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyLeftToRight(this, new BasicMonitor());
}
+ @Deprecated
@Override
public void copyRightToLeft() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- setEquivalentDiffAsMerged();
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getSemanticDiff() != null) {
- for (Diff semanticRefines : getSemanticDiff().getRefines()) {
- semanticRefines.copyRightToLeft();
- }
- getSemanticDiff().copyRightToLeft();
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "required by" diffs
- mergeRequiredBy(true);
- } else {
- mergeRequires(true);
- }
-
- for (Diff diff : getRefinedBy()) {
- diff.copyRightToLeft();
- }
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyRightToLeft(this, new BasicMonitor());
}
-
- private void setEquivalentDiffAsMerged() {
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequiredBy() differences that require us} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequiredBy() differences
- * that require us}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequiredBy(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequiredBy()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequires() required differences} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequires() required
- * differences}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequires(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequires()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
} // DiagramDiffImpl
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramComparisonConfiguration.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramComparisonConfiguration.java
index bdab62d54..48fa40a6e 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramComparisonConfiguration.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramComparisonConfiguration.java
@@ -1,13 +1,40 @@
+/*******************************************************************************
+ * 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.diagram.diff;
+/**
+ * Configuration of the diagram comparison.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
public class DiagramComparisonConfiguration {
+ /** Detection threshold value for the move of a graphical object. */
private int moveThreshold;
+ /**
+ * Get the threshold value for the move change.
+ *
+ * @return The threshold value.
+ */
public int getMoveThreshold() {
return moveThreshold;
}
+ /**
+ * Set the threshold value for the move change.
+ *
+ * @param moveThreshold
+ * The threshold value.
+ */
public void setMoveThreshold(int moveThreshold) {
this.moveThreshold = moveThreshold;
}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramDiffExtensionPostProcessor.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramDiffExtensionPostProcessor.java
index 4afab1a27..1e7ad231f 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramDiffExtensionPostProcessor.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/DiagramDiffExtensionPostProcessor.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * 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.diagram.diff;
import java.util.HashSet;
@@ -13,40 +23,76 @@ import org.eclipse.emf.compare.diagram.diff.internal.extension.DiffExtensionFact
import org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory;
import org.eclipse.emf.compare.extension.IPostProcessor;
+/**
+ * Post-processor to create the diagram difference extensions.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ */
public class DiagramDiffExtensionPostProcessor implements IPostProcessor {
+ /** Registry of diagram difference extension factories. */
private Set<IDiffExtensionFactory> diagramExtensionFactories;
+ /** Diagram comparison configuration. */
private DiagramComparisonConfiguration configuration;
+ /**
+ * Constructor.
+ */
public DiagramDiffExtensionPostProcessor() {
}
+ /**
+ * Constructor.
+ *
+ * @param configuration
+ * The diagram comparison configuration.
+ */
public DiagramDiffExtensionPostProcessor(DiagramComparisonConfiguration configuration) {
this.configuration = configuration;
}
+ /**
+ * Set the diagram comparison configuration.
+ *
+ * @param configuration
+ * The configuration.
+ */
public void setConfiguration(DiagramComparisonConfiguration configuration) {
this.configuration = configuration;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.extension.IPostProcessor#postMatch(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.common.util.Monitor)
+ */
public void postMatch(Comparison comparison, Monitor monitor) {
- // TODO Auto-generated method stub
-
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.extension.IPostProcessor#postDiff(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.common.util.Monitor)
+ */
public void postDiff(Comparison comparison, Monitor monitor) {
- // TODO Auto-generated method stub
-
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.extension.IPostProcessor#postRequirements(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.common.util.Monitor)
+ */
public void postRequirements(Comparison comparison, Monitor monitor) {
final Map<Class<? extends Diff>, IDiffExtensionFactory> mapDiagramExtensionFactories = DiffExtensionFactoryRegistry
.createExtensionFactories(configuration);
diagramExtensionFactories = new HashSet<IDiffExtensionFactory>(mapDiagramExtensionFactories.values());
- // Creation of the UML difference extensions
+ // Creation of the diagram difference extensions
for (Diff diff : comparison.getDifferences()) {
applyManagedTypes(diff);
}
@@ -63,23 +109,29 @@ public class DiagramDiffExtensionPostProcessor implements IPostProcessor {
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.extension.IPostProcessor#postEquivalences(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.common.util.Monitor)
+ */
public void postEquivalences(Comparison comparison, Monitor monitor) {
- // TODO Auto-generated method stub
-
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.extension.IPostProcessor#postConflicts(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.common.util.Monitor)
+ */
public void postConflicts(Comparison comparison, Monitor monitor) {
- // TODO Auto-generated method stub
-
}
/**
- * Creates the difference extensions in relation to the existing {@link DiffElement}s.
+ * Creates the difference extensions in relation to the existing difference.
*
* @param element
- * The input {@link DiffElement}.
- * @param diffModelCrossReferencer
- * The cross referencer.
+ * The current candidate difference for the build of the diagram extension.
*/
private void applyManagedTypes(Diff element) {
for (IDiffExtensionFactory factory : diagramExtensionFactories) {
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/AbstractDiffExtensionFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/AbstractDiffExtensionFactory.java
index 2082199b2..07175bb0d 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/AbstractDiffExtensionFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/AbstractDiffExtensionFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -22,7 +22,6 @@ import org.eclipse.emf.compare.AttributeChange;
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.ReferenceChange;
import org.eclipse.emf.compare.ResourceAttachmentChange;
@@ -33,78 +32,119 @@ import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
- * Factory for the difference extensions.
+ * Factory of diagram difference extensions.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public abstract class AbstractDiffExtensionFactory implements IDiffExtensionFactory {
+ /**
+ * Switch which returns the <code>DifferenceKind</code> of the matching diagram extension in relation to
+ * the given difference.
+ */
+ // CHECKSTYLE:OFF
private CompareSwitch<DifferenceKind> differenceKindCompareSwitch = new CompareSwitch<DifferenceKind>() {
+ // CHECKSTYLE:ON
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.util.CompareSwitch#caseAttributeChange(org.eclipse.emf.compare.AttributeChange)
+ */
@Override
public DifferenceKind caseAttributeChange(AttributeChange object) {
+ DifferenceKind result;
if (isRelatedToAnExtensionAdd(object)) {
- return DifferenceKind.ADD;
+ result = DifferenceKind.ADD;
} else if (isRelatedToAnExtensionDelete(object)) {
- return DifferenceKind.DELETE;
+ result = DifferenceKind.DELETE;
} else if (isRelatedToAnExtensionChange(object)) {
- return DifferenceKind.CHANGE;
+ result = DifferenceKind.CHANGE;
} else if (isRelatedToAnExtensionMove(object)) {
- return DifferenceKind.MOVE;
+ result = DifferenceKind.MOVE;
} else {
- return super.caseAttributeChange(object);
+ result = super.caseAttributeChange(object);
}
+ return result;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.util.CompareSwitch#caseReferenceChange(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
public DifferenceKind caseReferenceChange(ReferenceChange object) {
+ DifferenceKind result;
if (isRelatedToAnExtensionAdd(object)) {
- return DifferenceKind.ADD;
+ result = DifferenceKind.ADD;
} else if (isRelatedToAnExtensionDelete(object)) {
- return DifferenceKind.DELETE;
+ result = DifferenceKind.DELETE;
} else if (isRelatedToAnExtensionChange(object)) {
- return DifferenceKind.CHANGE;
+ result = DifferenceKind.CHANGE;
} else if (isRelatedToAnExtensionMove(object)) {
- return DifferenceKind.MOVE;
+ result = DifferenceKind.MOVE;
} else {
- return super.caseReferenceChange(object);
+ result = super.caseReferenceChange(object);
}
+ return result;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.util.CompareSwitch#caseResourceAttachmentChange(org.eclipse.emf.compare.ResourceAttachmentChange)
+ */
@Override
public DifferenceKind caseResourceAttachmentChange(ResourceAttachmentChange object) {
+ DifferenceKind result;
if (isRelatedToAnExtensionAdd(object)) {
- return DifferenceKind.ADD;
+ result = DifferenceKind.ADD;
} else if (isRelatedToAnExtensionDelete(object)) {
- return DifferenceKind.DELETE;
+ result = DifferenceKind.DELETE;
} else if (isRelatedToAnExtensionChange(object)) {
- return DifferenceKind.CHANGE;
+ result = DifferenceKind.CHANGE;
} else if (isRelatedToAnExtensionMove(object)) {
- return DifferenceKind.MOVE;
+ result = DifferenceKind.MOVE;
} else {
- return super.caseResourceAttachmentChange(object);
+ result = super.caseResourceAttachmentChange(object);
}
+ return result;
}
};
/**
* {@inheritDoc}
*
- * @see org.eclipse.emf.compare.uml2.diff.internal.extension.IDiffExtensionFactory#handles(org.eclipse.emf.compare.diff.metamodel.DiffElement)
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#handles(org.eclipse.emf.compare.Diff)
*/
public boolean handles(Diff input) {
return getRelatedExtensionKind(input) != null && !isDiffOnAddOrDelete(input);
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#getParentMatch(org.eclipse.emf.compare.Diff)
+ */
public Match getParentMatch(Diff input) {
return input.getMatch();
}
+ /**
+ * Check if the given difference is part of an add or delete change.
+ *
+ * @param input
+ * The difference to check.
+ * @return True if it is part of an add or delete change, false otherwise.
+ */
protected boolean isDiffOnAddOrDelete(Diff input) {
final Match match = input.getMatch();
final EObject container = match.eContainer();
if (container instanceof Match) {
final Iterator<Diff> diffs = ((Match)container).getAllDifferences().iterator();
while (diffs.hasNext()) {
- final Diff diff = (Diff)diffs.next();
+ final Diff diff = diffs.next();
if (diff instanceof ReferenceChange
&& (isRelatedToAnExtensionAdd((ReferenceChange)diff) || isRelatedToAnExtensionDelete((ReferenceChange)diff))
&& match.getComparison().getMatch(((ReferenceChange)diff).getValue()) == match) {
@@ -115,62 +155,179 @@ public abstract class AbstractDiffExtensionFactory implements IDiffExtensionFact
return false;
}
+ /**
+ * Get the <code>DifferenceKind</code> of the matching diagram difference extension in relation to the
+ * given difference.
+ *
+ * @param input
+ * The given difference.
+ * @return The kind of the diagram difference extension if this one exists, null otherwise.
+ */
protected DifferenceKind getRelatedExtensionKind(Diff input) {
return differenceKindCompareSwitch.doSwitch(input);
}
+ /**
+ * Check if the given reference change is related to a graphical add. It may be overridden in the child
+ * factories in order to precise which kind of graphical add has to be considered.
+ *
+ * @param input
+ * The reference change.
+ * @return True if the reference change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionAdd(ReferenceChange input) {
return false;
}
+ /**
+ * Check if the given reference change is related to a graphical delete. It may be overridden in the child
+ * factories in order to precise which kind of graphical delete has to be considered.
+ *
+ * @param input
+ * The reference change.
+ * @return True if the reference change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionDelete(ReferenceChange input) {
return false;
}
+ /**
+ * Check if the given reference change is related to a graphical change. It may be overridden in the child
+ * factories in order to precise which kind of graphical change has to be considered.
+ *
+ * @param input
+ * The reference change.
+ * @return True if the reference change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionChange(ReferenceChange input) {
return false;
}
+ /**
+ * Check if the given reference change is related to a graphical move. It may be overridden in the child
+ * factories in order to precise which kind of graphical move has to be considered.
+ *
+ * @param input
+ * The reference change.
+ * @return True if the reference change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionMove(ReferenceChange input) {
return false;
}
+ /**
+ * Check if the given attribute change is related to a graphical add. It may be overridden in the child
+ * factories in order to precise which kind of graphical add has to be considered.
+ *
+ * @param input
+ * The attribute change.
+ * @return True if the attribute change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionAdd(AttributeChange input) {
return false;
}
+ /**
+ * Check if the given attribute change is related to a graphical delete. It may be overridden in the child
+ * factories in order to precise which kind of graphical delete has to be considered.
+ *
+ * @param input
+ * The attribute change.
+ * @return True if the attribute change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionDelete(AttributeChange input) {
return false;
}
+ /**
+ * Check if the given attribute change is related to a graphical change. It may be overridden in the child
+ * factories in order to precise which kind of graphical change has to be considered.
+ *
+ * @param input
+ * The attribute change.
+ * @return True if the attribute change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionChange(AttributeChange input) {
return false;
}
+ /**
+ * Check if the given attribute change is related to a graphical move. It may be overridden in the child
+ * factories in order to precise which kind of graphical move has to be considered.
+ *
+ * @param input
+ * The attribute change.
+ * @return True if the attribute change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionMove(AttributeChange input) {
return false;
}
+ /**
+ * Check if the given resource attachment change is related to a graphical add. It may be overridden in
+ * the child factories in order to precise which kind of graphical add has to be considered.
+ *
+ * @param input
+ * The resource attachment change.
+ * @return True if the resource attachment change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionAdd(ResourceAttachmentChange input) {
return false;
}
+ /**
+ * Check if the given resource attachment change is related to a graphical delete. It may be overridden in
+ * the child factories in order to precise which kind of graphical delete has to be considered.
+ *
+ * @param input
+ * The resource attachment change.
+ * @return True if the resource attachment change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionDelete(ResourceAttachmentChange input) {
return false;
}
+ /**
+ * Check if the given resource attachment change is related to a graphical change. It may be overridden in
+ * the child factories in order to precise which kind of graphical change has to be considered.
+ *
+ * @param input
+ * The resource attachment change.
+ * @return True if the resource attachment change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionChange(ResourceAttachmentChange input) {
return false;
}
+ /**
+ * Check if the given resource attachment change is related to a graphical ;ove. It may be overridden in
+ * the child factories in order to precise which kind of graphical ;ove has to be considered.
+ *
+ * @param input
+ * The resource attachment change.
+ * @return True if the resource attachment change is a good candidate, false otherwise.
+ */
protected boolean isRelatedToAnExtensionMove(ResourceAttachmentChange input) {
return false;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#getExtensionKind()
+ */
public Class<? extends Diff> getExtensionKind() {
return Diff.class;
}
+ /**
+ * Get all the add and delete changes on the objects contained in the one concerned by the given reference
+ * change.
+ *
+ * @param input
+ * The given reference change.
+ * @return The found differences.
+ */
protected Set<Diff> getAllContainedDifferences(ReferenceChange input) {
final Comparison comparison = input.getMatch().getComparison();
final Match match = comparison.getMatch(input.getValue());
@@ -179,6 +336,15 @@ public abstract class AbstractDiffExtensionFactory implements IDiffExtensionFact
return result;
}
+ /**
+ * Get all the add and delete changes under the given match.
+ *
+ * @param comparison
+ * The comparison.
+ * @param match
+ * The match
+ * @return The found differences.
+ */
private Set<Diff> getAllContainedDifferences(Comparison comparison, Match match) {
final Set<Diff> result = Sets.newLinkedHashSet();
@@ -203,26 +369,25 @@ public abstract class AbstractDiffExtensionFactory implements IDiffExtensionFact
return result;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#fillRequiredDifferences(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.compare.Diff)
+ */
public void fillRequiredDifferences(Comparison comparison, Diff extension) {
- // TODO Auto-generated method stub
-
}
/**
- * Find the cross references of the given model object, through the specified feature, with a cross
- * referencer and a predicate.
+ * Find the differences, on the given model object, which match with the predicate.
*
* @param comparison
* The comparison.
* @param lookup
* The model object.
- * @param inFeature
- * The feature.
* @param p
* The predicate.
- * @param crossReferencer
- * The cross referencer.
- * @return The cross references.
+ * @return The found differences.
*/
protected final List<Diff> findCrossReferences(Comparison comparison, EObject lookup, Predicate<Diff> p) {
final List<Diff> result = new ArrayList<Diff>();
@@ -234,23 +399,37 @@ public abstract class AbstractDiffExtensionFactory implements IDiffExtensionFact
return result;
}
+ /**
+ * Get the GMF view which represents a semantic element and containing the given difference.
+ *
+ * @param input
+ * The difference.
+ * @return The found view.
+ */
protected View getViewContainer(Diff input) {
final Match match = input.getMatch();
- return getViewContainer(match, input.getSource());
+ return getViewContainer(match);
}
- protected View getViewContainer(Match match, DifferenceSource source) {
+ /**
+ * From the one of the matched objects of the given match, it returns the first found parent GMF view
+ * which represents a semantic element.
+ *
+ * @param match
+ * The given match.
+ * @return The found view.
+ */
+ protected View getViewContainer(Match match) {
EObject result = match.getLeft();
if (result == null) {
result = match.getRight();
}
- if (result instanceof View
- && ReferenceUtil.safeEGet(result, NotationPackage.Literals.VIEW__ELEMENT) != null) {
- return (View)result;
- } else if (match.eContainer() instanceof Match) {
- return getViewContainer((Match)match.eContainer(), source);
+ if (!(result instanceof View && ReferenceUtil
+ .safeEGet(result, NotationPackage.Literals.VIEW__ELEMENT) != null)
+ && match.eContainer() instanceof Match) {
+ result = getViewContainer((Match)match.eContainer());
}
- return null;
+ return (View)result;
}
}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/DiffExtensionFactoryRegistry.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/DiffExtensionFactoryRegistry.java
index 853df1378..4e9943915 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/DiffExtensionFactoryRegistry.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/DiffExtensionFactoryRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -25,6 +25,8 @@ import org.eclipse.emf.compare.diagram.diff.internal.extension.factories.ShowFac
/**
* Registry of all {@link IDiffExtensionFactory}.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public final class DiffExtensionFactoryRegistry {
@@ -32,7 +34,6 @@ public final class DiffExtensionFactoryRegistry {
* Constructor.
*/
private DiffExtensionFactoryRegistry() {
- // TODO Auto-generated constructor stub
}
/**
@@ -40,8 +41,7 @@ public final class DiffExtensionFactoryRegistry {
* unmodifiable.
*
* @param configuration
- * @param engine
- * The UML2 difference engine.
+ * The diagram comparison configuration.
* @return an unmodifiable set of all {@link IDiffExtensionFactory}.
*/
public static Map<Class<? extends Diff>, IDiffExtensionFactory> createExtensionFactories(
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/IDiffExtensionFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/IDiffExtensionFactory.java
index 65db908cb..b6c88cb19 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/IDiffExtensionFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/IDiffExtensionFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -15,23 +15,29 @@ import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
/**
- * An {@link IDiffExtensionFactory} is a factory capable to create an {@link AbstractDiffExtension} from a
- * {@link DiffElement} if and only if this factory can {@link #handles(DiffElement) handle} the given
- * {@link DiffElement}.
+ * An {@link IDiffExtensionFactory} is a factory capable to create an {@link Diff extension} from a
+ * {@link Diff} if and only if this factory can {@link #handles(Diff) handle} the given {@link Diff}.
* <p>
- * A factory must be able to say in which parent a {@link AbstractDiffExtension} must be attached if it
- * handles the {@link DiffElement} from which it has been {@link #create(DiffElement) created}.
+ * A factory must be able to say in which parent an {@link Diff extension} must be attached if it handles the
+ * {@link Diff} from which it has been {@link #create(Diff) created}.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public interface IDiffExtensionFactory {
+ /**
+ * Returns the kind of extension that this factory has to create.
+ *
+ * @return The kind of extension.
+ */
Class<? extends Diff> getExtensionKind();
/**
- * Returns true if this factory handles the given kind of DiffElement, i.e., if it can create an
- * {@link AbstractDiffExtension}.
+ * Returns true if this factory handles the given kind of Diff, i.e., if it can create an {@link Diff
+ * extension}.
* <p>
* <b>Performance note: </b> this method should return as quickly as possible as it will called on every
- * {@link DiffElement} of the DiffModel.
+ * {@link Diff} of the Comparison.
*
* @param input
* the element to test
@@ -40,8 +46,8 @@ public interface IDiffExtensionFactory {
boolean handles(Diff input);
/**
- * Creates and returns an {@link AbstractDiffExtension} from the given {@link DiffElement}. The returned
- * element MUST NOT be added to its parent, it will be done by the UML2DiffEngine.
+ * Creates and returns a {@link Diff extension} from the given {@link Diff}. The returned element MUST NOT
+ * be added to its parent, it will be done by the post processor.
*
* @param input
* The input difference element.
@@ -50,9 +56,7 @@ public interface IDiffExtensionFactory {
Diff create(Diff input);
/**
- * Returns the {@link DiffElement} in which the {@link #create(DiffElement) created}
- * {@link AbstractDiffExtension} will be added as a sub diff element. This {@link DiffElement} can be from
- * the model or newly created.
+ * Returns the match in which the difference will be added.
*
* @param input
* The input difference element.
@@ -63,10 +67,10 @@ public interface IDiffExtensionFactory {
/**
* Sets the required link of the difference extension created by the related factory.
*
- * @param diff
- * The difference extension.
- * @param comaprison
+ * @param comparison
* The comparison.
+ * @param extension
+ * The difference extension.
*/
void fillRequiredDifferences(Comparison comparison, Diff extension);
}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/EdgeChangeFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/EdgeChangeFactory.java
index f256279c5..39897d86d 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/EdgeChangeFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/EdgeChangeFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -37,15 +37,27 @@ import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
- * Factory for UMLAssociationChangeLeftTarget.
+ * Factory of edge changes.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class EdgeChangeFactory extends AbstractDiffExtensionFactory {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#getExtensionKind()
+ */
@Override
public Class<? extends Diff> getExtensionKind() {
return EdgeChange.class;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#create(org.eclipse.emf.compare.Diff)
+ */
public Diff create(Diff input) {
final EdgeChange ret = DiagramCompareFactory.eINSTANCE.createEdgeChange();
@@ -80,6 +92,12 @@ public class EdgeChangeFactory extends AbstractDiffExtensionFactory {
return ret;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#fillRequiredDifferences(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.compare.Diff)
+ */
@Override
public void fillRequiredDifferences(Comparison comparison, Diff extension) {
final DiagramDiff diff = (DiagramDiff)extension;
@@ -163,36 +181,69 @@ public class EdgeChangeFactory extends AbstractDiffExtensionFactory {
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#getParentMatch(org.eclipse.emf.compare.Diff)
+ */
@Override
public Match getParentMatch(Diff input) {
return input.getMatch().getComparison().getMatch(getViewContainer(input));
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionAdd(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
protected boolean isRelatedToAnExtensionAdd(ReferenceChange input) {
return input.getValue() instanceof Edge && input.getReference().isContainment()
&& input.getKind() == DifferenceKind.ADD;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionDelete(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
protected boolean isRelatedToAnExtensionDelete(ReferenceChange input) {
return input.getValue() instanceof Edge && input.getReference().isContainment()
&& input.getKind() == DifferenceKind.DELETE;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionMove(org.eclipse.emf.compare.AttributeChange)
+ */
@Override
protected boolean isRelatedToAnExtensionMove(AttributeChange input) {
- return (input.getAttribute().eContainer().equals(NotationPackage.eINSTANCE.getRelativeBendpoints()) || input
- .getAttribute().equals(NotationPackage.eINSTANCE.getIdentityAnchor_Id())
- && input.getRefines().isEmpty());
+ return input.getAttribute().eContainer().equals(NotationPackage.eINSTANCE.getRelativeBendpoints())
+ || input.getAttribute().equals(NotationPackage.eINSTANCE.getIdentityAnchor_Id())
+ && input.getRefines().isEmpty();
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionMove(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
protected boolean isRelatedToAnExtensionMove(ReferenceChange input) {
return input.getValue() instanceof IdentityAnchor && input.getReference().isContainment()
&& input.getRefines().isEmpty();
}
+ /**
+ * Get all differences which are part of a move extension, from the given difference (being part of the
+ * result).
+ *
+ * @param input
+ * The given difference.
+ * @return The found differences.
+ */
private Set<Diff> getAllDifferencesForMove(Diff input) {
// FIXME we're not taking enough diffs into account here
final Comparison comparison = input.getMatch().getComparison();
@@ -202,12 +253,22 @@ public class EdgeChangeFactory extends AbstractDiffExtensionFactory {
return result;
}
+ /**
+ * Get all differences which are part of a move extension, from the given match.
+ *
+ * @param comparison
+ * The comparison.
+ * @param match
+ * The match.
+ * @return The found differences.
+ */
private Set<Diff> getAllNonExtendedDifferences(Comparison comparison, Match match) {
final Set<Diff> result = Sets.newLinkedHashSet();
final Set<Match> prune = Sets.newLinkedHashSet();
for (Diff candidate : match.getDifferences()) {
if (getRelatedExtensionKind(candidate) != null) {
+ // It exists an extension for this candidate
result.add(candidate);
} else if (candidate instanceof ReferenceChange
&& ((ReferenceChange)candidate).getReference().isContainment()) {
@@ -224,6 +285,13 @@ public class EdgeChangeFactory extends AbstractDiffExtensionFactory {
return result;
}
+ /**
+ * From a given diagram difference extension, get the related semantic difference.
+ *
+ * @param input
+ * The diagram difference extension.
+ * @return The semantic one.
+ */
private Diff getSemanticDiff(Diff input) {
if (input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof View) {
final View view = (View)((ReferenceChange)input).getValue();
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/HideFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/HideFactory.java
index 4e86840cf..84fe8ba04 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/HideFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/HideFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -23,15 +23,27 @@ import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
- * Factory for UMLAssociationChangeLeftTarget.
+ * Factory of hide changes.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class HideFactory extends AbstractDiffExtensionFactory {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#getExtensionKind()
+ */
@Override
public Class<? extends Diff> getExtensionKind() {
return Hide.class;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#create(org.eclipse.emf.compare.Diff)
+ */
public Diff create(Diff input) {
final Hide ret = DiagramCompareFactory.eINSTANCE.createHide();
@@ -49,6 +61,11 @@ public class HideFactory extends AbstractDiffExtensionFactory {
return ret;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionChange(org.eclipse.emf.compare.AttributeChange)
+ */
@Override
protected boolean isRelatedToAnExtensionChange(AttributeChange input) {
if (input.getAttribute().equals(NotationPackage.eINSTANCE.getView_Visible())) {
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/NodeChangeFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/NodeChangeFactory.java
index dc4a61fcc..5bab3fbbe 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/NodeChangeFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/NodeChangeFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -37,21 +37,40 @@ import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
- * Factory for UMLAssociationChangeLeftTarget.
+ * Factory of node changes.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class NodeChangeFactory extends AbstractDiffExtensionFactory {
+ /** Configuration of the diagram comparison. */
private final DiagramComparisonConfiguration configuration;
+ /**
+ * Constructor.
+ *
+ * @param configuration
+ * The configuration of the diagram comparison.
+ */
public NodeChangeFactory(DiagramComparisonConfiguration configuration) {
this.configuration = configuration;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#getExtensionKind()
+ */
@Override
public Class<? extends Diff> getExtensionKind() {
return NodeChange.class;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#create(org.eclipse.emf.compare.Diff)
+ */
public Diff create(Diff input) {
final NodeChange ret = DiagramCompareFactory.eINSTANCE.createNodeChange();
@@ -86,6 +105,12 @@ public class NodeChangeFactory extends AbstractDiffExtensionFactory {
return ret;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#fillRequiredDifferences(org.eclipse.emf.compare.Comparison,
+ * org.eclipse.emf.compare.Diff)
+ */
@Override
public void fillRequiredDifferences(Comparison comparison, Diff extension) {
final DiagramDiff diff = (DiagramDiff)extension;
@@ -114,11 +139,21 @@ public class NodeChangeFactory extends AbstractDiffExtensionFactory {
}
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#getParentMatch(org.eclipse.emf.compare.Diff)
+ */
@Override
public Match getParentMatch(Diff input) {
return input.getMatch().getComparison().getMatch(getViewContainer(input));
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionAdd(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
protected boolean isRelatedToAnExtensionAdd(ReferenceChange input) {
return input.getReference().isContainment() && input.getKind() == DifferenceKind.ADD
@@ -126,6 +161,11 @@ public class NodeChangeFactory extends AbstractDiffExtensionFactory {
&& ReferenceUtil.safeEGet(input.getValue(), NotationPackage.Literals.VIEW__ELEMENT) != null;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionDelete(org.eclipse.emf.compare.ReferenceChange)
+ */
@Override
protected boolean isRelatedToAnExtensionDelete(ReferenceChange input) {
return input.getReference().isContainment() && input.getKind() == DifferenceKind.DELETE
@@ -133,6 +173,11 @@ public class NodeChangeFactory extends AbstractDiffExtensionFactory {
&& ReferenceUtil.safeEGet(input.getValue(), NotationPackage.Literals.VIEW__ELEMENT) != null;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionMove(org.eclipse.emf.compare.AttributeChange)
+ */
@Override
protected boolean isRelatedToAnExtensionMove(AttributeChange input) {
return input.getAttribute().eContainer().equals(NotationPackage.eINSTANCE.getLocation())
@@ -165,6 +210,13 @@ public class NodeChangeFactory extends AbstractDiffExtensionFactory {
return false;
}
+ /**
+ * From a given diagram difference extension, get the related semantic difference.
+ *
+ * @param input
+ * The diagram difference extension.
+ * @return The semantic one.
+ */
private Diff getSemanticDiff(Diff input) {
if (input instanceof ReferenceChange && ((ReferenceChange)input).getValue() instanceof View) {
final View view = (View)((ReferenceChange)input).getValue();
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/ShowFactory.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/ShowFactory.java
index dd6959746..1fd6ff3c7 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/ShowFactory.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/internal/extension/factories/ShowFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -23,7 +23,9 @@ import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
/**
- * Factory for UMLAssociationChangeLeftTarget.
+ * Factory of show changes.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class ShowFactory extends AbstractDiffExtensionFactory {
@@ -32,6 +34,11 @@ public class ShowFactory extends AbstractDiffExtensionFactory {
return Show.class;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.IDiffExtensionFactory#create(org.eclipse.emf.compare.Diff)
+ */
public Diff create(Diff input) {
final Show ret = DiagramCompareFactory.eINSTANCE.createShow();
@@ -48,6 +55,11 @@ public class ShowFactory extends AbstractDiffExtensionFactory {
return ret;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.diagram.diff.internal.extension.AbstractDiffExtensionFactory#isRelatedToAnExtensionChange(org.eclipse.emf.compare.AttributeChange)
+ */
@Override
protected boolean isRelatedToAnExtensionChange(AttributeChange input) {
if (input.getAttribute().equals(NotationPackage.eINSTANCE.getView_Visible())) {
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareConstants.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareConstants.java
index 5f2476626..9986fb963 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareConstants.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareConstants.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 Obeo.
+ * 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
@@ -10,18 +10,17 @@
*******************************************************************************/
package org.eclipse.emf.compare.diagram.diff.util;
-
/**
* Defines constants used throughout EMF Compare's UI.
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
public interface DiagramCompareConstants {
-
+
/** Preferences description for the move threshold. */
String PREFERENCES_DESCRIPTION_MOVE_THRESHOLD = DiagramCompareUIMessages
.getString("DiagramCompareConstants.preferences.moveThresholdLabel") + ':'; //$NON-NLS-1$
-
+
/** Preferences key for the move threshold. */
String PREFERENCES_KEY_MOVE_THRESHOLD = "emfcompare.diagram.move.threshold"; //$NON-NLS-1$
}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareUIMessages.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareUIMessages.java
index 5265e3c0f..9421fe6cf 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareUIMessages.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/DiagramCompareUIMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 Obeo.
+ * 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
@@ -59,8 +59,9 @@ public final class DiagramCompareUIMessages {
* @see MessageFormat#format(String, Object[])
*/
public static String getString(String key, Object... arguments) {
- if (arguments == null)
+ if (arguments == null) {
return getString(key);
+ }
return MessageFormat.format(getString(key), arguments);
}
}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/GMFLabelUtil.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/GMFLabelUtil.java
index 6f4158699..78fa47bfb 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/GMFLabelUtil.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/diff/util/GMFLabelUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * 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
@@ -39,10 +39,13 @@ import org.eclipse.swt.widgets.Shell;
* @author Cedric Notot <a href="mailto:cedric.notot@obeo.fr">cedric.notot@obeo.fr</a>
*/
public final class GMFLabelUtil {
+ // CHECKSTYLE:OFF
// FIXME this is dangerous (potential memory leaks) and crappy (singleton), but was made to avoid creating
// thousands of Diagrams.
private static Map<Diagram, DiagramEditPart> DIAGRAM_EDIT_PARTS = Maps.newHashMap();
+ // CHECKSTYLE:ON
+
/**
* Constructor.
*/
@@ -89,6 +92,9 @@ public final class GMFLabelUtil {
Display.getDefault().syncExec(labelSetter);
}
+ /**
+ * Clean edit parts and registry.
+ */
public static void cleanup() {
for (Map.Entry<Diagram, DiagramEditPart> entry : DIAGRAM_EDIT_PARTS.entrySet()) {
entry.getValue().deactivate();
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/merge/DiagramDiffMerger.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/merge/DiagramDiffMerger.java
new file mode 100644
index 000000000..e860d7b6b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/merge/DiagramDiffMerger.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * 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.diagram.merge;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.diagram.DiagramDiff;
+import org.eclipse.emf.compare.merge.AbstractMerger;
+
+/**
+ * Specific implementation of {@link AbstractMerger} for Diagram differences.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public class DiagramDiffMerger extends AbstractMerger {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
+ */
+ public boolean isMergerFor(Diff target) {
+ return target instanceof DiagramDiff;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyLeftToRight(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final DiagramDiff diff = (DiagramDiff)target;
+
+ setEquivalentDiffAsMerged(diff);
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ final Diff semanticDiff = diff.getSemanticDiff();
+ if (semanticDiff != null) {
+ for (Diff semanticRefines : semanticDiff.getRefines()) {
+ mergeDiff(semanticRefines, false, monitor);
+ }
+ mergeDiff(semanticDiff, false, monitor);
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "requires" diffs
+ mergeRequires(diff, false, monitor);
+ } else {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, false, monitor);
+ }
+
+ for (Diff refining : diff.getRefinedBy()) {
+ mergeDiff(refining, false, monitor);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyRightToLeft(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final DiagramDiff diff = (DiagramDiff)target;
+
+ setEquivalentDiffAsMerged(diff);
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ final Diff semanticDiff = diff.getSemanticDiff();
+ if (semanticDiff != null) {
+ for (Diff semanticRefines : semanticDiff.getRefines()) {
+ mergeDiff(semanticRefines, true, monitor);
+ }
+ mergeDiff(semanticDiff, true, monitor);
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, true, monitor);
+ } else {
+ mergeRequires(diff, true, monitor);
+ }
+
+ for (Diff refining : diff.getRefinedBy()) {
+ mergeDiff(refining, true, monitor);
+ }
+ }
+
+ /**
+ * Iterates over the differences equivalent to {@code diff} and sets them as
+ * {@link DifferenceState#MERGED}.
+ *
+ * @param diff
+ * Diff which equivalences are to be considered merged.
+ */
+ private void setEquivalentDiffAsMerged(DiagramDiff diff) {
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionDescriptor.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionDescriptor.java
index 1c37936f6..cb5373f2f 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionDescriptor.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionDescriptor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 Obeo.
+ * 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
@@ -27,7 +27,7 @@ public class ViewLabelProviderExtensionDescriptor {
protected IViewLabelProvider extension;
/**
- * Constructor
+ * Constructor.
*/
public ViewLabelProviderExtensionDescriptor() {
this.className = null;
@@ -35,6 +35,16 @@ public class ViewLabelProviderExtensionDescriptor {
this.extension = null;
}
+ /**
+ * Constructor.
+ *
+ * @param className
+ * .
+ * @param diagramType
+ * .
+ * @param extension
+ * .
+ */
public ViewLabelProviderExtensionDescriptor(String className, String diagramType,
IViewLabelProvider extension) {
this.className = className;
diff --git a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionRegistry.java b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionRegistry.java
index 7fc2fbe98..3a8486e30 100644
--- a/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionRegistry.java
+++ b/plugins/org.eclipse.emf.compare.diagram/src/org/eclipse/emf/compare/diagram/provider/ViewLabelProviderExtensionRegistry.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2012 Obeo.
+ * 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
@@ -18,7 +18,7 @@ import java.util.List;
*
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public class ViewLabelProviderExtensionRegistry {
+public final class ViewLabelProviderExtensionRegistry {
/** List of extensions created from the extension point contributions. */
private static final List<ViewLabelProviderExtensionDescriptor> VIEW_LABEL_PROVIDERS = new ArrayList<ViewLabelProviderExtensionDescriptor>();
diff --git a/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
index 5ddf56670..59a352283 100644
--- a/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
@@ -13,7 +13,8 @@ Export-Package: org.eclipse.emf.compare.command,
org.eclipse.emf.compare.domain,
org.eclipse.emf.compare.domain.impl,
org.eclipse.emf.compare.provider,
- org.eclipse.emf.compare.provider.spec
+ org.eclipse.emf.compare.provider.spec,
+ org.eclipse.emf.compare.provider.utils
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.compare;visibility:=reexport,
org.eclipse.emf.edit;visibility:=reexport,
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/add_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/add_ov.gif
index c123a2b13..c123a2b13 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/add_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/add_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/chg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/chg_ov.gif
index 2b1b8d677..2b1b8d677 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/chg_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/chg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confadd_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confadd_ov.png
index f7834e57e..f7834e57e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confadd_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confadd_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confchg_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confchg_ov.png
index 6be0f6725..6be0f6725 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confchg_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confchg_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confdel_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confdel_ov.png
index dac7e135d..dac7e135d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confdel_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confdel_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_add_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_add_ov.png
index ffed135d2..ffed135d2 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_add_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_add_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_chg_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_chg_ov.png
index b5d33e535..b5d33e535 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_chg_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_chg_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_del_ov.png b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_del_ov.png
index 2bff268e6..2bff268e6 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/confr_del_ov.png
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/confr_del_ov.png
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/del_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/del_ov.gif
index ef0207c62..ef0207c62 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/del_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/del_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/error_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/error_ov.gif
index 0bc60689c..0bc60689c 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/error_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/error_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inadd_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inadd_ov.gif
index 05a9f5a68..05a9f5a68 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inadd_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inadd_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inchg_ov.gif
index 12d4a9732..12d4a9732 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/inchg_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/indel_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/indel_ov.gif
index 373a68f14..373a68f14 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/indel_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/indel_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inoutchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inoutchg_ov.gif
new file mode 100644
index 000000000..453497689
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/inoutchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/merged_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/merged_ov.gif
new file mode 100644
index 000000000..603a9e124
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/merged_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outadd_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outadd_ov.gif
index 63fb2967c..63fb2967c 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outadd_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outadd_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outchg_ov.gif
index 78321d74d..78321d74d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outchg_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outdel_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outdel_ov.gif
index 7182e5596..7182e5596 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/outdel_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/outdel_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inadd_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inadd_ov.gif
index 0ac0cea9e..0ac0cea9e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inadd_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inadd_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inchg_ov.gif
index c330c0c9f..c330c0c9f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_inchg_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_indel_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_indel_ov.gif
index 5acab6778..5acab6778 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_indel_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_indel_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inoutchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inoutchg_ov.gif
new file mode 100644
index 000000000..ca8c6f4a4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_inoutchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outadd_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outadd_ov.gif
index 69607651f..69607651f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outadd_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outadd_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outchg_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outchg_ov.gif
index 17ba1af4f..17ba1af4f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outchg_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outchg_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outdel_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outdel_ov.gif
index ef6b8b745..ef6b8b745 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/r_outdel_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/r_outdel_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/removed_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/removed_ov.gif
index 045d88f09..045d88f09 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/removed_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/removed_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/warning_ov.gif b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/warning_ov.gif
index 2b2e50fe7..2b2e50fe7 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/warning_ov.gif
+++ b/plugins/org.eclipse.emf.compare.edit/icons/full/ovr16/warning_ov.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.edit/plugin.properties b/plugins/org.eclipse.emf.compare.edit/plugin.properties
index cfc399b97..85f997260 100644
--- a/plugins/org.eclipse.emf.compare.edit/plugin.properties
+++ b/plugins/org.eclipse.emf.compare.edit/plugin.properties
@@ -1,83 +1,84 @@
-# Copyright (c) 2012 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
-
-pluginName = Compare Edit Support
-providerName = Eclipse Modeling Project
-
-_UI_CreateChild_text = {0}
-_UI_CreateChild_text2 = {1} {0}
-_UI_CreateChild_text3 = {1}
-_UI_CreateChild_tooltip = Create New {0} Under {1} Feature
-_UI_CreateChild_description = Create a new child of type {0} for the {1} feature of the selected {2}.
-_UI_CreateSibling_description = Create a new sibling of type {0} for the selected {2}, under the {1} feature of their parent.
-
-_UI_PropertyDescriptor_description = The {0} of the {1}
-
-_UI_Comparison_type = Comparison
-_UI_MatchResource_type = Match Resource
-_UI_Match_type = Match
-_UI_Diff_type = Diff
-_UI_ResourceAttachmentChange_type = Resource Attachment Change
-_UI_ReferenceChange_type = Reference Change
-_UI_AttributeChange_type = Attribute Change
-_UI_Conflict_type = Conflict
-_UI_Equivalence_type = Equivalence
-_UI_Unknown_type = Object
-
-_UI_Unknown_datatype= Value
-
-_UI_Comparison_matchedResources_feature = Matched Resources
-_UI_Comparison_matches_feature = Matches
-_UI_Comparison_conflicts_feature = Conflicts
-_UI_MatchResource_leftURI_feature = Left URI
-_UI_MatchResource_rightURI_feature = Right URI
-_UI_MatchResource_originURI_feature = Origin URI
-_UI_Match_subMatches_feature = Sub Matches
-_UI_Match_differences_feature = Differences
-_UI_Match_left_feature = Left
-_UI_Match_right_feature = Right
-_UI_Match_origin_feature = Origin
-_UI_Diff_match_feature = Match
-_UI_Diff_requires_feature = Requires
-_UI_Diff_requiredBy_feature = Required By
-_UI_Diff_refines_feature = Refines
-_UI_Diff_refinedBy_feature = Refined By
-_UI_Diff_kind_feature = Kind
-_UI_Diff_equivalentDiffs_feature = Equivalent Diffs
-_UI_Diff_conflict_feature = Conflict
-_UI_ResourceAttachmentChange_resourceURI_feature = Resource URI
-_UI_ReferenceChange_reference_feature = Reference
-_UI_ReferenceChange_value_feature = Value
-_UI_AttributeChange_attribute_feature = Attribute
-_UI_AttributeChange_value_feature = Value
-_UI_Conflict_differences_feature = Differences
-_UI_Equivalence_differences_feature = Differences
-_UI_Unknown_feature = Unspecified
-
-_UI_DifferenceKind_ADD_literal = ADD
-_UI_DifferenceKind_DELETE_literal = DELETE
-_UI_DifferenceKind_CHANGE_literal = CHANGE
-_UI_DifferenceKind_MOVE_literal = MOVE
-_UI_DifferenceSource_LEFT_literal = LEFT
-_UI_DifferenceSource_RIGHT_literal = RIGHT
-_UI_Match_submatches_feature = Submatches
-_UI_Diff_source_feature = Source
-_UI_MatchResource_left_feature = Left
-_UI_MatchResource_right_feature = Right
-_UI_MatchResource_origin_feature = Origin
-_UI_Diff_equivalence_feature = Equivalence
-_UI_Conflict_kind_feature = Kind
-_UI_ConflictKind_REAL_literal = REAL
-_UI_ConflictKind_PSEUDO_literal = PSEUDO
-_UI_Comparison_equivalences_feature = Equivalences
-_UI_Diff_state_feature = State
-_UI_DifferenceState_UNRESOLVED_literal = UNRESOLVED
-_UI_DifferenceState_MERGED_literal = MERGED
-_UI_DifferenceState_DISCARDED_literal = DISCARDED
-_UI_Comparison_threeWay_feature = Three Way
+# Copyright (c) 2012 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
+
+pluginName = Compare Edit Support
+providerName = Eclipse Modeling Project
+
+_UI_CreateChild_text = {0}
+_UI_CreateChild_text2 = {1} {0}
+_UI_CreateChild_text3 = {1}
+_UI_CreateChild_tooltip = Create New {0} Under {1} Feature
+_UI_CreateChild_description = Create a new child of type {0} for the {1} feature of the selected {2}.
+_UI_CreateSibling_description = Create a new sibling of type {0} for the selected {2}, under the {1} feature of their parent.
+
+_UI_PropertyDescriptor_description = The {0} of the {1}
+
+_UI_Comparison_type = Comparison
+_UI_MatchResource_type = Match Resource
+_UI_Match_type = Match
+_UI_Diff_type = Diff
+_UI_ResourceAttachmentChange_type = Resource Attachment Change
+_UI_ReferenceChange_type = Reference Change
+_UI_AttributeChange_type = Attribute Change
+_UI_Conflict_type = Conflict
+_UI_Equivalence_type = Equivalence
+_UI_Unknown_type = Object
+
+_UI_Unknown_datatype= Value
+
+_UI_Comparison_matchedResources_feature = Matched Resources
+_UI_Comparison_matches_feature = Matches
+_UI_Comparison_conflicts_feature = Conflicts
+_UI_MatchResource_leftURI_feature = Left URI
+_UI_MatchResource_rightURI_feature = Right URI
+_UI_MatchResource_originURI_feature = Origin URI
+_UI_Match_subMatches_feature = Sub Matches
+_UI_Match_differences_feature = Differences
+_UI_Match_left_feature = Left
+_UI_Match_right_feature = Right
+_UI_Match_origin_feature = Origin
+_UI_Diff_match_feature = Match
+_UI_Diff_requires_feature = Requires
+_UI_Diff_requiredBy_feature = Required By
+_UI_Diff_refines_feature = Refines
+_UI_Diff_refinedBy_feature = Refined By
+_UI_Diff_kind_feature = Kind
+_UI_Diff_equivalentDiffs_feature = Equivalent Diffs
+_UI_Diff_conflict_feature = Conflict
+_UI_ResourceAttachmentChange_resourceURI_feature = Resource URI
+_UI_ReferenceChange_reference_feature = Reference
+_UI_ReferenceChange_value_feature = Value
+_UI_AttributeChange_attribute_feature = Attribute
+_UI_AttributeChange_value_feature = Value
+_UI_Conflict_differences_feature = Differences
+_UI_Equivalence_differences_feature = Differences
+_UI_Unknown_feature = Unspecified
+
+_UI_DifferenceKind_ADD_literal = ADD
+_UI_DifferenceKind_DELETE_literal = DELETE
+_UI_DifferenceKind_CHANGE_literal = CHANGE
+_UI_DifferenceKind_MOVE_literal = MOVE
+_UI_DifferenceSource_LEFT_literal = LEFT
+_UI_DifferenceSource_RIGHT_literal = RIGHT
+_UI_Match_submatches_feature = Submatches
+_UI_Diff_source_feature = Source
+_UI_MatchResource_left_feature = Left
+_UI_MatchResource_right_feature = Right
+_UI_MatchResource_origin_feature = Origin
+_UI_Diff_equivalence_feature = Equivalence
+_UI_Conflict_kind_feature = Kind
+_UI_ConflictKind_REAL_literal = REAL
+_UI_ConflictKind_PSEUDO_literal = PSEUDO
+_UI_Comparison_equivalences_feature = Equivalences
+_UI_Diff_state_feature = State
+_UI_DifferenceState_UNRESOLVED_literal = UNRESOLVED
+_UI_DifferenceState_MERGED_literal = MERGED
+_UI_DifferenceState_DISCARDED_literal = DISCARDED
+_UI_Comparison_threeWay_feature = Three Way
+_UI_MatchResource_comparison_feature = Comparison
diff --git a/plugins/org.eclipse.emf.compare.edit/plugin.xml b/plugins/org.eclipse.emf.compare.edit/plugin.xml
index c16737afb..e7a9d46ca 100644
--- a/plugins/org.eclipse.emf.compare.edit/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.edit/plugin.xml
@@ -23,7 +23,8 @@
org.eclipse.emf.edit.provider.IStructuredItemContentProvider
org.eclipse.emf.edit.provider.ITreeItemContentProvider
org.eclipse.emf.edit.provider.IItemLabelProvider
- org.eclipse.emf.edit.provider.IItemPropertySource"/>
+ org.eclipse.emf.edit.provider.IItemPropertySource
+ org.eclipse.emf.compare.provider.IItemStyledLabelProvider"/>
</extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.compare.edit/src-gen/org/eclipse/emf/compare/provider/EMFCompareEditPlugin.java b/plugins/org.eclipse.emf.compare.edit/src-gen/org/eclipse/emf/compare/provider/EMFCompareEditPlugin.java
index 776976bfa..a998adfe2 100644
--- a/plugins/org.eclipse.emf.compare.edit/src-gen/org/eclipse/emf/compare/provider/EMFCompareEditPlugin.java
+++ b/plugins/org.eclipse.emf.compare.edit/src-gen/org/eclipse/emf/compare/provider/EMFCompareEditPlugin.java
@@ -1,104 +1,101 @@
-/**
- * Copyright (c) 2012 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.provider;
-
-import org.eclipse.emf.common.EMFPlugin;
-
-import org.eclipse.emf.common.util.ResourceLocator;
-
-import org.eclipse.emf.ecore.provider.EcoreEditPlugin;
-
-/**
- * This is the central singleton for the Compare edit plugin.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
-public final class EMFCompareEditPlugin extends EMFPlugin {
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * Keep track of the singleton.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public static final EMFCompareEditPlugin INSTANCE = new EMFCompareEditPlugin();
-
- /**
- * Keep track of the singleton.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- private static Implementation plugin;
-
- /**
- * Create the instance.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public EMFCompareEditPlugin() {
- super(new ResourceLocator[] {EcoreEditPlugin.INSTANCE, });
- }
-
- /**
- * Returns the singleton instance of the Eclipse plugin.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the singleton instance.
- * @generated
- */
- @Override
- public ResourceLocator getPluginResourceLocator() {
- return plugin;
- }
-
- /**
- * Returns the singleton instance of the Eclipse plugin.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the singleton instance.
- * @generated
- */
- public static Implementation getPlugin() {
- return plugin;
- }
-
- /**
- * The actual implementation of the Eclipse <b>Plugin</b>.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public static class Implementation extends EclipsePlugin {
- /**
- * Creates an instance.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public Implementation() {
- super();
-
- // Remember the static instance.
- //
- plugin = this;
- }
- }
-
-}
+/**
+ * Copyright (c) 2012 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.provider;
+
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.common.util.ResourceLocator;
+import org.eclipse.emf.ecore.provider.EcoreEditPlugin;
+
+/**
+ * This is the central singleton for the Compare edit plugin.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+public final class EMFCompareEditPlugin extends EMFPlugin {
+
+ /**
+ * The plug-in ID.
+ *
+ * @since 3.0
+ */
+ public static final String PLUGIN_ID = "org.eclipse.emf.compare.edit"; //$NON-NLS-1$
+
+ /**
+ *
+ * @generated
+ */
+ public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * Keep track of the singleton.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EMFCompareEditPlugin INSTANCE = new EMFCompareEditPlugin();
+
+ /**
+ * Keep track of the singleton.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private static Implementation plugin;
+
+ /**
+ * Create the instance.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EMFCompareEditPlugin() {
+ super(new ResourceLocator[] {EcoreEditPlugin.INSTANCE, });
+ }
+
+ /**
+ * Returns the singleton instance of the Eclipse plugin.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @return the singleton instance.
+ * @generated
+ */
+ @Override
+ public ResourceLocator getPluginResourceLocator() {
+ return plugin;
+ }
+
+ /**
+ * Returns the singleton instance of the Eclipse plugin.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @return the singleton instance.
+ * @generated
+ */
+ public static Implementation getPlugin() {
+ return plugin;
+ }
+
+ /**
+ * The actual implementation of the Eclipse <b>Plugin</b>.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public static class Implementation extends EclipsePlugin {
+ /**
+ * Creates an instance.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public Implementation() {
+ super();
+
+ // Remember the static instance.
+ //
+ plugin = this;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/AbstractCopyCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/AbstractCopyCommand.java
new file mode 100644
index 000000000..a8bb1137e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/AbstractCopyCommand.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.command.impl;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.command.ICompareCopyCommand;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.ecore.change.util.ChangeRecorder;
+import org.eclipse.emf.edit.command.ChangeCommand;
+
+/**
+ * This command can be used to copy a number of diffs (or a single one) in a given direction.
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ * @since 3.0
+ */
+public abstract class AbstractCopyCommand extends ChangeCommand implements ICompareCopyCommand {
+ /** The list of differences we are to merge. */
+ protected final List<? extends Diff> differences;
+
+ /** Direction of the merge operation. */
+ protected final boolean leftToRight;
+
+ /** Merger registry. */
+ protected final IMerger.Registry mergerRegistry;
+
+ /**
+ * Constructs an instance of this command given the list of differences that it needs to merge.
+ *
+ * @param changeRecorder
+ * The change recorder associated to this command.
+ * @param notifiers
+ * The collection of notifiers that will be notified of this command's execution.
+ * @param differences
+ * The list of differences that this command should merge.
+ * @param leftToRight
+ * The direction in which {@code differences} should be merged.
+ * @param mergerRegistry
+ * The registry of mergers.
+ */
+ public AbstractCopyCommand(ChangeRecorder changeRecorder, Collection<Notifier> notifiers,
+ List<? extends Diff> differences, boolean leftToRight, IMerger.Registry mergerRegistry) {
+ super(changeRecorder, notifiers);
+ this.differences = ImmutableList.copyOf(differences);
+ this.leftToRight = leftToRight;
+ this.mergerRegistry = mergerRegistry;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
+ */
+ public boolean isLeftToRight() {
+ return leftToRight;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
+ */
+ @Override
+ public Collection<?> getAffectedObjects() {
+ return differences;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.AbstractCommand#canExecute()
+ */
+ @Override
+ public boolean canExecute() {
+ return super.canExecute() && Iterables.any(differences, hasState(DifferenceState.UNRESOLVED));
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java
index dd9453115..1c8cfebee 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -10,21 +10,19 @@
*******************************************************************************/
package org.eclipse.emf.compare.command.impl;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
+import com.google.common.base.Predicate;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.command.ICompareCopyCommand;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
-import org.eclipse.emf.edit.command.ChangeCommand;
/**
* This command can be used to copy a number of diffs (or a single one) in a given direction.
@@ -35,12 +33,7 @@ import org.eclipse.emf.edit.command.ChangeCommand;
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
-public class CopyAllNonConflictingCommand extends ChangeCommand implements ICompareCopyCommand {
- /** The list of differences we are to merge. */
- private final List<? extends Diff> differences;
-
- /** Direction of the merge operation. */
- private final boolean leftToRight;
+public class CopyAllNonConflictingCommand extends AbstractCopyCommand {
/**
* Constructs an instance of this command given the list of differences that it needs to merge.
@@ -53,41 +46,13 @@ public class CopyAllNonConflictingCommand extends ChangeCommand implements IComp
* The list of differences that this command should merge.
* @param leftToRight
* The direction in which {@code differences} should be merged.
+ * @param mergerRegistry
+ * The registry of mergers.
+ * @since 3.0
*/
public CopyAllNonConflictingCommand(ChangeRecorder changeRecorder, Collection<Notifier> notifiers,
- List<? extends Diff> differences, boolean leftToRight) {
- super(changeRecorder, notifiers);
- this.differences = ImmutableList.copyOf(differences);
- this.leftToRight = leftToRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
- */
- public boolean isLeftToRight() {
- return leftToRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
- */
- @Override
- public Collection<?> getAffectedObjects() {
- return differences;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.AbstractCommand#canExecute()
- */
- @Override
- public boolean canExecute() {
- return super.canExecute() && Iterables.any(differences, hasState(DifferenceState.UNRESOLVED));
+ List<? extends Diff> differences, boolean leftToRight, IMerger.Registry mergerRegistry) {
+ super(changeRecorder, notifiers, differences, leftToRight, mergerRegistry);
}
/**
@@ -97,18 +62,21 @@ public class CopyAllNonConflictingCommand extends ChangeCommand implements IComp
*/
@Override
protected void doExecute() {
- if (leftToRight) {
- for (Diff diff : differences) {
- if (diff.getSource() == DifferenceSource.LEFT && diff.getConflict() == null) {
- diff.copyLeftToRight();
+ final Predicate<? super Diff> filter = new Predicate<Diff>() {
+ public boolean apply(Diff input) {
+ if (input == null || input.getConflict() != null) {
+ return false;
}
+ return leftToRight && input.getSource() == DifferenceSource.LEFT || !leftToRight
+ && input.getSource() == DifferenceSource.RIGHT;
}
+ };
+
+ IBatchMerger merger = new BatchMerger(mergerRegistry, filter);
+ if (leftToRight) {
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
} else {
- for (Diff diff : differences) {
- if (diff.getSource() == DifferenceSource.RIGHT && diff.getConflict() == null) {
- diff.copyRightToLeft();
- }
- }
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
}
}
}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java
index b0a06da7b..a879d7aca 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -10,20 +10,16 @@
*******************************************************************************/
package org.eclipse.emf.compare.command.impl;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.command.ICompareCopyCommand;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
-import org.eclipse.emf.edit.command.ChangeCommand;
/**
* This command can be used to copy a number of diffs (or a single one) in a given direction.
@@ -34,12 +30,7 @@ import org.eclipse.emf.edit.command.ChangeCommand;
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
-public class CopyCommand extends ChangeCommand implements ICompareCopyCommand {
- /** The list of differences we are to merge. */
- private final List<Diff> differences;
-
- /** Direction of the merge operation. */
- private final boolean leftToRight;
+public class CopyCommand extends AbstractCopyCommand {
/**
* Constructs an instance of this command given the list of differences that it needs to merge.
@@ -52,41 +43,13 @@ public class CopyCommand extends ChangeCommand implements ICompareCopyCommand {
* The list of differences that this command should merge.
* @param leftToRight
* The direction in which {@code differences} should be merged.
+ * @param mergerRegistry
+ * The registry of mergers.
+ * @since 3.0
*/
public CopyCommand(ChangeRecorder changeRecorder, Collection<Notifier> notifiers, List<Diff> differences,
- boolean leftToRight) {
- super(changeRecorder, notifiers);
- this.differences = ImmutableList.copyOf(differences);
- this.leftToRight = leftToRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
- */
- public boolean isLeftToRight() {
- return leftToRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
- */
- @Override
- public Collection<?> getAffectedObjects() {
- return differences;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.AbstractCommand#canExecute()
- */
- @Override
- public boolean canExecute() {
- return super.canExecute() && Iterables.any(differences, hasState(DifferenceState.UNRESOLVED));
+ boolean leftToRight, IMerger.Registry mergerRegistry) {
+ super(changeRecorder, notifiers, differences, leftToRight, mergerRegistry);
}
/**
@@ -96,14 +59,11 @@ public class CopyCommand extends ChangeCommand implements ICompareCopyCommand {
*/
@Override
protected void doExecute() {
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
if (leftToRight) {
- for (Diff diff : differences) {
- diff.copyLeftToRight();
- }
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
} else {
- for (Diff diff : differences) {
- diff.copyRightToLeft();
- }
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
}
}
}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java
index a0cc6b7a6..3a9ed9bee 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -15,6 +15,7 @@ import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.command.ICompareCommandStack;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
/**
@@ -31,8 +32,15 @@ public interface ICompareEditingDomain {
*/
ChangeRecorder getChangeRecorder();
- Command createCopyCommand(Diff diff, boolean leftToRight);
+ /**
+ * @since 3.0
+ */
+ Command createCopyCommand(Diff diff, boolean leftToRight, IMerger.Registry mergerRegistry);
- Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight);
+ /**
+ * @since 3.0
+ */
+ Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight,
+ IMerger.Registry mergerRegistry);
}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java
index 60ed2cf99..d5b5ec89c 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -28,6 +28,7 @@ import org.eclipse.emf.compare.command.impl.CopyAllNonConflictingCommand;
import org.eclipse.emf.compare.command.impl.CopyCommand;
import org.eclipse.emf.compare.command.impl.DualCompareCommandStack;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.ecore.resource.Resource;
@@ -145,28 +146,33 @@ public class EMFCompareEditingDomain implements ICompareEditingDomain {
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.domain.ICompareEditingDomain#createCopyCommand(org.eclipse.emf.compare.Diff,
- * boolean)
+ * boolean, org.eclipse.emf.compare.merge.IMerger.Registry)
+ * @since 3.0
*/
- public Command createCopyCommand(Diff diff, boolean leftToRight) {
+ public Command createCopyCommand(Diff diff, boolean leftToRight, IMerger.Registry mergerRegistry) {
ImmutableSet<Notifier> notifiers = ImmutableSet.<Notifier> builder().add(
diff.getMatch().getComparison()).addAll(fNotifiers).build();
- return new CopyCommand(fChangeRecorder, notifiers, Collections.singletonList(diff), leftToRight);
+ return new CopyCommand(fChangeRecorder, notifiers, Collections.singletonList(diff), leftToRight,
+ mergerRegistry);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.domain.ICompareEditingDomain#createCopyAllNonConflictingCommand(java.util.List,
- * boolean)
+ * boolean, org.eclipse.emf.compare.merge.IMerger.Registry)
+ * @since 3.0
*/
- public Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight) {
+ public Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight,
+ IMerger.Registry mergerRegistry) {
ImmutableSet.Builder<Notifier> notifiersBuilder = ImmutableSet.builder();
for (Diff diff : differences) {
notifiersBuilder.add(diff.getMatch().getComparison());
}
ImmutableSet<Notifier> notifiers = notifiersBuilder.addAll(fNotifiers).build();
- return new CopyAllNonConflictingCommand(fChangeRecorder, notifiers, differences, leftToRight);
+ return new CopyAllNonConflictingCommand(fChangeRecorder, notifiers, differences, leftToRight,
+ mergerRegistry);
}
/**
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/IItemStyledLabelProvider.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/IItemStyledLabelProvider.java
new file mode 100644
index 000000000..80b13b6c4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/IItemStyledLabelProvider.java
@@ -0,0 +1,18 @@
+package org.eclipse.emf.compare.provider;
+
+import org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public interface IItemStyledLabelProvider {
+
+ /**
+ * Returns the styled text label for the given object.
+ *
+ * @param object
+ * the object to evaluate the styled string for.
+ * @return the styled string.
+ */
+ public IComposedStyledString getStyledText(Object object);
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/AttributeChangeItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/AttributeChangeItemProviderSpec.java
index d9626c9b1..8f70267aa 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/AttributeChangeItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/AttributeChangeItemProviderSpec.java
@@ -20,21 +20,27 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.AttributeChange;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.DifferenceKind;
-import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
import org.eclipse.emf.compare.provider.AttributeChangeItemProvider;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+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.ecore.util.EcoreUtil;
/**
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public class AttributeChangeItemProviderSpec extends AttributeChangeItemProvider {
+public class AttributeChangeItemProviderSpec extends AttributeChangeItemProvider implements IItemStyledLabelProvider {
+
+ private final OverlayImageProvider overlayProvider;
/**
* @param adapterFactory
*/
public AttributeChangeItemProviderSpec(AdapterFactory adapterFactory) {
super(adapterFactory);
+ overlayProvider = new OverlayImageProvider(getResourceLocator(), true);
}
/**
@@ -45,12 +51,16 @@ public class AttributeChangeItemProviderSpec extends AttributeChangeItemProvider
@Override
public Object getImage(Object object) {
AttributeChange attributeChange = (AttributeChange)object;
- Object ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), attributeChange.getValue());
+ Object attributeChangeValueImage = AdapterFactoryUtil.getImage(getRootAdapterFactory(),
+ attributeChange.getValue());
- if (ret == null) {
- ret = super.getImage(object);
+ if (attributeChangeValueImage == null) {
+ attributeChangeValueImage = super.getImage(object);
}
+ Object diffImage = overlayProvider.getComposedImage(attributeChange, attributeChangeValueImage);
+ Object ret = overlayImage(object, diffImage);
+
return ret;
}
@@ -61,38 +71,7 @@ public class AttributeChangeItemProviderSpec extends AttributeChangeItemProvider
*/
@Override
public String getText(Object object) {
- final AttributeChange attChange = (AttributeChange)object;
-
- final String valueText = getValueText(attChange);
- final String attributeText = getAttributeText(attChange);
-
- String remotely = ""; //$NON-NLS-1$
- if (attChange.getSource() == DifferenceSource.RIGHT) {
- remotely = "remotely "; //$NON-NLS-1$
- }
-
- String ret = ""; //$NON-NLS-1$
- switch (attChange.getKind()) {
- case ADD:
- ret = valueText + " has been " + remotely + "added to " + attributeText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case DELETE:
- ret = valueText + " has been " + remotely + "deleted from " + attributeText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case CHANGE:
- String changeText = ReferenceChangeItemProviderSpec.changeText(attChange, attChange
- .getAttribute());
- ret = attributeText + " " + valueText + " has been " + remotely + changeText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case MOVE:
- ret = valueText + " has been " + remotely + "moved in '" + attributeText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- default:
- throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
- + " value: " + attChange.getKind()); //$NON-NLS-1$
- }
-
- return ret;
+ return getStyledText(object).getString();
}
protected String getAttributeText(final AttributeChange attChange) {
@@ -144,4 +123,43 @@ public class AttributeChangeItemProviderSpec extends AttributeChangeItemProvider
return super.getForeground(object);
}
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ final AttributeChange attChange = (AttributeChange)object;
+
+ final String valueText = getValueText(attChange);
+
+ final String attributeText = getAttributeText(attChange);
+
+ ComposedStyledString ret = new ComposedStyledString(valueText);
+ ret.append(" [" + attributeText, Style.DECORATIONS_STYLER); //$NON-NLS-1$
+
+ switch (attChange.getKind()) {
+ case ADD:
+ ret.append(" add", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case DELETE:
+ ret.append(" delete", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case CHANGE:
+ ret.append(
+ " " + ReferenceChangeItemProviderSpec.changeText(attChange, attChange.getAttribute()), //$NON-NLS-1$
+ Style.DECORATIONS_STYLER);
+ break;
+ case MOVE:
+ ret.append(" move", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ default:
+ throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
+ + " value: " + attChange.getKind()); //$NON-NLS-1$
+ }
+ ret.append("]", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+
+ return ret;
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/CompareItemProviderAdapterFactorySpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/CompareItemProviderAdapterFactorySpec.java
index b3e708a15..eb272fcae 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/CompareItemProviderAdapterFactorySpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/CompareItemProviderAdapterFactorySpec.java
@@ -1,107 +1,127 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.provider.spec;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory;
-import org.eclipse.emf.edit.provider.IItemLabelProvider;
-
-/**
- * Specialized {@link CompareItemProviderAdapterFactory} returning ItemProviderAdapter with nice
- * {@link IItemLabelProvider#getText(Object)} and {@link IItemLabelProvider#getImage(Object)}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class CompareItemProviderAdapterFactorySpec extends CompareItemProviderAdapterFactory {
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createMatchAdapter()
- */
- @Override
- public Adapter createMatchAdapter() {
- if (matchItemProvider == null) {
- matchItemProvider = new MatchItemProviderSpec(this);
- }
-
- return matchItemProvider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createReferenceChangeAdapter()
- */
- @Override
- public Adapter createReferenceChangeAdapter() {
- if (referenceChangeItemProvider == null) {
- referenceChangeItemProvider = new ReferenceChangeItemProviderSpec(this);
- }
-
- return referenceChangeItemProvider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createAttributeChangeAdapter()
- */
- @Override
- public Adapter createAttributeChangeAdapter() {
- if (attributeChangeItemProvider == null) {
- attributeChangeItemProvider = new AttributeChangeItemProviderSpec(this);
- }
-
- return attributeChangeItemProvider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createMatchResourceAdapter()
- */
- @Override
- public Adapter createMatchResourceAdapter() {
- if (matchResourceItemProvider == null) {
- matchResourceItemProvider = new MatchResourceItemProviderSpec(this);
- }
- return matchResourceItemProvider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createComparisonAdapter()
- */
- @Override
- public Adapter createComparisonAdapter() {
- if (comparisonItemProvider == null) {
- comparisonItemProvider = new ComparisonItemProviderSpec(this);
- }
-
- return comparisonItemProvider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createConflictAdapter()
- */
- @Override
- public Adapter createConflictAdapter() {
- if (conflictItemProvider == null) {
- conflictItemProvider = new ConflictItemProviderSpec(this);
- }
-
- return conflictItemProvider;
- }
-}
+/*******************************************************************************
+ * 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.provider.spec;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+
+/**
+ * Specialized {@link CompareItemProviderAdapterFactory} returning ItemProviderAdapter with nice
+ * {@link IItemLabelProvider#getText(Object)} and {@link IItemLabelProvider#getImage(Object)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class CompareItemProviderAdapterFactorySpec extends CompareItemProviderAdapterFactory {
+
+ public CompareItemProviderAdapterFactorySpec() {
+ super();
+ supportedTypes.add(IItemStyledLabelProvider.class);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createMatchAdapter()
+ */
+ @Override
+ public Adapter createMatchAdapter() {
+ if (matchItemProvider == null) {
+ matchItemProvider = new MatchItemProviderSpec(this);
+ }
+
+ return matchItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createReferenceChangeAdapter()
+ */
+ @Override
+ public Adapter createReferenceChangeAdapter() {
+ if (referenceChangeItemProvider == null) {
+ referenceChangeItemProvider = new ReferenceChangeItemProviderSpec(this);
+ }
+
+ return referenceChangeItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createAttributeChangeAdapter()
+ */
+ @Override
+ public Adapter createAttributeChangeAdapter() {
+ if (attributeChangeItemProvider == null) {
+ attributeChangeItemProvider = new AttributeChangeItemProviderSpec(this);
+ }
+
+ return attributeChangeItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createMatchResourceAdapter()
+ */
+ @Override
+ public Adapter createMatchResourceAdapter() {
+ if (matchResourceItemProvider == null) {
+ matchResourceItemProvider = new MatchResourceItemProviderSpec(this);
+ }
+ return matchResourceItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createComparisonAdapter()
+ */
+ @Override
+ public Adapter createComparisonAdapter() {
+ if (comparisonItemProvider == null) {
+ comparisonItemProvider = new ComparisonItemProviderSpec(this);
+ }
+
+ return comparisonItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createConflictAdapter()
+ */
+ @Override
+ public Adapter createConflictAdapter() {
+ if (conflictItemProvider == null) {
+ conflictItemProvider = new ConflictItemProviderSpec(this);
+ }
+
+ return conflictItemProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.CompareItemProviderAdapterFactory#createResourceAttachmentChangeAdapter()
+ */
+ @Override
+ public Adapter createResourceAttachmentChangeAdapter() {
+ if (resourceAttachmentChangeItemProvider == null) {
+ resourceAttachmentChangeItemProvider = new ResourceAttachmentChangeItemProviderSpec(this);
+ }
+
+ return resourceAttachmentChangeItemProvider;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ComparisonItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ComparisonItemProviderSpec.java
index b75ca7fdd..8e4c1402d 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ComparisonItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ComparisonItemProviderSpec.java
@@ -1,89 +1,114 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.provider.spec;
-
-import static com.google.common.collect.Iterables.concat;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.isEmpty;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-
-import java.util.Collection;
-
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.provider.ComparisonItemProvider;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class ComparisonItemProviderSpec extends ComparisonItemProvider {
-
- /**
- * @param adapterFactory
- */
- public ComparisonItemProviderSpec(AdapterFactory adapterFactory) {
- super(adapterFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
- */
- @Override
- public Collection<?> getChildren(Object object) {
- Comparison comparison = (Comparison)object;
- return ImmutableList.copyOf(getChildrenIterable(comparison));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#hasChildren(java.lang.Object)
- */
- @Override
- public boolean hasChildren(Object object) {
- Comparison comparison = (Comparison)object;
- return !isEmpty(getChildrenIterable(comparison));
- }
-
- private Iterable<EObject> getChildrenIterable(Comparison comparison) {
- Iterable<Match> match = getNonEmptyMatches(comparison);
- return concat(match, comparison.getMatchedResources());
- }
-
- private Iterable<Match> getNonEmptyMatches(Comparison comparison) {
- Iterable<Match> match = filter(comparison.getMatches(), new Predicate<Match>() {
- public boolean apply(Match input) {
- final boolean ret;
- IEditingDomainItemProvider editingDomainItemProvider = (IEditingDomainItemProvider)adapterFactory
- .adapt(input, IEditingDomainItemProvider.class);
-
- if (editingDomainItemProvider instanceof MatchItemProviderSpec) {
- ret = !isEmpty(((MatchItemProviderSpec)editingDomainItemProvider)
- .getChildrenIterable(input));
- } else if (editingDomainItemProvider != null) {
- ret = !editingDomainItemProvider.getChildren(input).isEmpty();
- } else {
- ret = false;
- }
-
- return ret;
- }
- });
- return match;
- }
-}
+/*******************************************************************************
+ * 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.provider.spec;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+
+import com.google.common.base.Predicate;
+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.common.util.EList;
+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.provider.ComparisonItemProvider;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.utils.ComposedStyledString;
+import org.eclipse.emf.compare.provider.utils.IStyledString;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class ComparisonItemProviderSpec extends ComparisonItemProvider implements IItemStyledLabelProvider {
+
+ /**
+ * @param adapterFactory
+ */
+ public ComparisonItemProviderSpec(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
+ */
+ @Override
+ public Collection<?> getChildren(Object object) {
+ Comparison comparison = (Comparison)object;
+ return ImmutableList.copyOf(getChildrenIterable(comparison));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(Object object) {
+ Comparison comparison = (Comparison)object;
+ return !isEmpty(getChildrenIterable(comparison));
+ }
+
+ private Iterable<EObject> getChildrenIterable(Comparison comparison) {
+ Iterable<? extends EObject> matches = getNonEmptyMatches(comparison);
+ List<EObject> children = Lists.newArrayList(matches);
+ for (EObject match : matches) {
+ EList<Diff> differences = ((Match)match).getDifferences();
+ if (!isEmpty(filter(differences, ResourceAttachmentChange.class))) {
+ children.remove(match);
+ }
+ }
+
+ return concat(children, comparison.getMatchedResources());
+ }
+
+ private Iterable<Match> getNonEmptyMatches(Comparison comparison) {
+ Iterable<Match> match = filter(comparison.getMatches(), new Predicate<Match>() {
+ public boolean apply(Match input) {
+ final boolean ret;
+ IEditingDomainItemProvider editingDomainItemProvider = (IEditingDomainItemProvider)adapterFactory
+ .adapt(input, IEditingDomainItemProvider.class);
+
+ if (editingDomainItemProvider instanceof MatchItemProviderSpec) {
+ ret = !isEmpty(((MatchItemProviderSpec)editingDomainItemProvider)
+ .getChildrenIterable(input));
+ } else if (editingDomainItemProvider != null) {
+ ret = !editingDomainItemProvider.getChildren(input).isEmpty();
+ } else {
+ ret = false;
+ }
+
+ return ret;
+ }
+ });
+ return match;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ return new ComposedStyledString(getText(object));
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ConflictItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ConflictItemProviderSpec.java
index 53e4535b0..325a65405 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ConflictItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ConflictItemProviderSpec.java
@@ -17,11 +17,14 @@ import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.provider.ConflictItemProvider;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.utils.ComposedStyledString;
+import org.eclipse.emf.compare.provider.utils.IStyledString;
/**
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public class ConflictItemProviderSpec extends ConflictItemProvider {
+public class ConflictItemProviderSpec extends ConflictItemProvider implements IItemStyledLabelProvider {
/**
* @param adapterFactory
@@ -37,10 +40,7 @@ public class ConflictItemProviderSpec extends ConflictItemProvider {
*/
@Override
public String getText(Object object) {
- Conflict conflict = (Conflict)object;
- int size = conflict.getDifferences().size() - 1;
- return conflict.getKind().getName() + " conflict with " + size + " other difference"
- + (size > 1 ? "s" : "");
+ return getStyledText(object).getString();
}
/**
@@ -54,4 +54,17 @@ public class ConflictItemProviderSpec extends ConflictItemProvider {
EList<Diff> differences = conflict.getDifferences();
return differences;
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ Conflict conflict = (Conflict)object;
+ int size = conflict.getDifferences().size() - 1;
+ return new ComposedStyledString(conflict.getKind().getName()
+ + " conflict with " + size + " other difference" //$NON-NLS-1$ //$NON-NLS-2$
+ + (size > 1 ? "s" : "")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchItemProviderSpec.java
index 75bb7f5fd..f00268299 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchItemProviderSpec.java
@@ -1,254 +1,274 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.provider.spec;
-
-import static com.google.common.base.Predicates.not;
-import static com.google.common.base.Predicates.or;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.isEmpty;
-import static com.google.common.collect.Iterables.transform;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-import java.util.Collection;
-
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Conflict;
-import org.eclipse.emf.compare.ConflictKind;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ReferenceChange;
-import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
-import org.eclipse.emf.compare.provider.MatchItemProvider;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-
-/**
- * Specialized {@link MatchItemProvider} returning nice output for {@link #getText(Object)} and
- * {@link #getImage(Object)}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class MatchItemProviderSpec extends MatchItemProvider {
-
- private static final Predicate<ReferenceChange> CONTAINMENT_REFERENCE_CHANGE = new Predicate<ReferenceChange>() {
- public boolean apply(ReferenceChange input) {
- return input.getReference().isContainment();
- }
- };
-
- private static final Function<ReferenceChange, EObject> VALUE = new Function<ReferenceChange, EObject>() {
- public EObject apply(ReferenceChange input) {
- return input.getValue();
- }
- };
-
- /**
- * Constructor calling super {@link #MatchItemProvider(AdapterFactory)}.
- *
- * @param adapterFactory
- * the adapter factory
- */
- public MatchItemProviderSpec(AdapterFactory adapterFactory) {
- super(adapterFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.MatchItemProvider#getImage(java.lang.Object)
- */
- @Override
- public Object getImage(Object object) {
- Match match = (Match)object;
- Object ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getLeft());
-
- if (ret == null) {
- ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getRight());
- }
-
- if (ret == null) {
- ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getOrigin());
- }
-
- if (ret == null) {
- ret = super.getImage(object);
- }
-
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.MatchItemProvider#getText(java.lang.Object)
- */
- @Override
- public String getText(Object object) {
- Match match = (Match)object;
- String ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getLeft());
-
- if (ret == null) {
- ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getRight());
- }
-
- if (ret == null) {
- ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getOrigin());
- }
-
- if (ret == null) {
- ret = super.getText(object);
- }
-
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
- */
- @Override
- public Collection<?> getChildren(Object object) {
- Match match = (Match)object;
- Iterable<?> filteredChildren = getChildrenIterable(match);
- return ImmutableList.copyOf(filteredChildren);
- }
-
- Iterable<?> getChildrenIterable(Match match) {
- ImmutableSet<EObject> containementDifferenceValues = containmentReferencesValues(match);
-
- @SuppressWarnings("unchecked")
- Predicate<Object> childrenFilter = not(or(matchOfContainmentDiff(containementDifferenceValues),
- matchWithNoChildren(), emptyMatch(), PSEUDO_CONFLICT_DIFF, REFINED_DIFF,
- PSEUDO_DELETE_CONFLICT));
-
- Iterable<?> filteredChildren = filter(super.getChildren(match), childrenFilter);
- return filteredChildren;
- }
-
- private ImmutableSet<EObject> containmentReferencesValues(Match match) {
- EList<Diff> differences = match.getDifferences();
- Iterable<ReferenceChange> containmentReferenceChanges = filter(filter(differences,
- ReferenceChange.class), CONTAINMENT_REFERENCE_CHANGE);
- ImmutableSet<EObject> containementDifferenceValues = ImmutableSet.copyOf(transform(
- containmentReferenceChanges, VALUE));
- return containementDifferenceValues;
- }
-
- private static Predicate<? super Object> matchOfContainmentDiff(
- final ImmutableSet<EObject> containementDifferenceValues) {
- return new Predicate<Object>() {
- public boolean apply(Object input) {
- boolean ret = false;
- if (input instanceof Match) {
- Match match = (Match)input;
- if (containementDifferenceValues.contains(match.getLeft())
- || containementDifferenceValues.contains(match.getRight())
- || containementDifferenceValues.contains(match.getOrigin())) {
- ret = true;
- }
- }
- return ret;
- }
- };
- }
-
- private Predicate<? super Object> matchWithNoChildren() {
- return new Predicate<Object>() {
- public boolean apply(Object input) {
- boolean ret = false;
- if (input instanceof Match) {
- Match match = (Match)input;
- ret = Iterables.isEmpty(MatchItemProviderSpec.this.getChildrenIterable(match));
- }
- return ret;
- }
- };
- }
-
- private static Predicate<? super Object> emptyMatch() {
- return new Predicate<Object>() {
- public boolean apply(Object input) {
- if (input instanceof Match) {
- final Match match = ((Match)input);
- return match.getLeft() == null && match.getRight() == null && match.getOrigin() == null;
- }
- return false;
- }
- };
- }
-
- static final Predicate<? super Object> REFINED_DIFF = new Predicate<Object>() {
- public boolean apply(Object input) {
- boolean ret = false;
- if (input instanceof Diff) {
- Diff diff = (Diff)input;
- ret = !diff.getRefines().isEmpty();
- }
- return ret;
- }
- };
-
- private static final Predicate<? super Object> PSEUDO_CONFLICT_DIFF = new Predicate<Object>() {
- public boolean apply(Object input) {
- boolean ret = false;
- if (input instanceof Diff) {
- Diff diff = (Diff)input;
- Conflict conflict = diff.getConflict();
- if (conflict != null && conflict.getKind() == ConflictKind.PSEUDO) {
- ret = true;
- }
- }
- return ret;
- }
- };
-
- private static final Predicate<? super Object> PSEUDO_DELETE_CONFLICT = new Predicate<Object>() {
- public boolean apply(Object input) {
- boolean ret = false;
- if (input instanceof ReferenceChange) {
- ReferenceChange referenceChange = (ReferenceChange)input;
- Conflict conflict = referenceChange.getConflict();
- if (conflict != null) {
- EReference eReference = referenceChange.getReference();
- EObject value = referenceChange.getValue();
- Iterable<ReferenceChange> conflictualReferenceChanges = filter(conflict.getDifferences(),
- ReferenceChange.class);
- for (ReferenceChange conflictualReferenceChange : conflictualReferenceChanges) {
- if (conflictualReferenceChange != referenceChange
- && conflictualReferenceChange.getReference() == eReference
- && conflictualReferenceChange.getValue() == value) {
- ret = true;
- }
- }
- }
- }
- return ret;
- }
- };
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#hasChildren(java.lang.Object)
- */
- @Override
- public boolean hasChildren(Object object) {
- Match match = (Match)object;
- return !isEmpty(getChildrenIterable(match));
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.provider.spec;
+
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.base.Predicates.or;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Iterables.transform;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.MatchItemProvider;
+import org.eclipse.emf.compare.provider.utils.ComposedStyledString;
+import org.eclipse.emf.compare.provider.utils.IStyledString;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+
+/**
+ * Specialized {@link MatchItemProvider} returning nice output for {@link #getText(Object)} and
+ * {@link #getImage(Object)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class MatchItemProviderSpec extends MatchItemProvider implements IItemStyledLabelProvider {
+
+ private static final Predicate<ReferenceChange> CONTAINMENT_REFERENCE_CHANGE = new Predicate<ReferenceChange>() {
+ public boolean apply(ReferenceChange input) {
+ return input.getReference().isContainment();
+ }
+ };
+
+ private static final Function<ReferenceChange, EObject> VALUE = new Function<ReferenceChange, EObject>() {
+ public EObject apply(ReferenceChange input) {
+ return input.getValue();
+ }
+ };
+
+ private final OverlayImageProvider overlayProvider;
+
+ /**
+ * Constructor calling super {@link #MatchItemProvider(AdapterFactory)}.
+ *
+ * @param adapterFactory
+ * the adapter factory
+ */
+ public MatchItemProviderSpec(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ overlayProvider = new OverlayImageProvider(getResourceLocator(), true);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.MatchItemProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Object getImage(Object object) {
+ Match match = (Match)object;
+ Object ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getLeft());
+
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getRight());
+ }
+
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getOrigin());
+ }
+
+ if (ret == null) {
+ ret = super.getImage(object);
+ }
+
+ Object matchImage = overlayProvider.getComposedImage(match, ret);
+ ret = overlayImage(object, matchImage);
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.MatchItemProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object object) {
+ Match match = (Match)object;
+ String ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getLeft());
+
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getRight());
+ }
+
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getOrigin());
+ }
+
+ if (ret == null) {
+ ret = super.getText(object);
+ }
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
+ */
+ @Override
+ public Collection<?> getChildren(Object object) {
+ Match match = (Match)object;
+ Iterable<?> filteredChildren = getChildrenIterable(match);
+ return ImmutableList.copyOf(filteredChildren);
+ }
+
+ Iterable<?> getChildrenIterable(Match match) {
+ ImmutableSet<EObject> containementDifferenceValues = containmentReferencesValues(match);
+
+ @SuppressWarnings("unchecked")
+ Predicate<Object> childrenFilter = not(or(matchOfContainmentDiff(containementDifferenceValues),
+ matchWithNoChildren(), emptyMatch(), PSEUDO_CONFLICT_DIFF, REFINED_DIFF,
+ PSEUDO_DELETE_CONFLICT, instanceOf(ResourceAttachmentChange.class)));
+
+ Iterable<?> filteredChildren = filter(super.getChildren(match), childrenFilter);
+ return filteredChildren;
+ }
+
+ private ImmutableSet<EObject> containmentReferencesValues(Match match) {
+ EList<Diff> differences = match.getDifferences();
+ Iterable<ReferenceChange> containmentReferenceChanges = filter(filter(differences,
+ ReferenceChange.class), CONTAINMENT_REFERENCE_CHANGE);
+ ImmutableSet<EObject> containementDifferenceValues = ImmutableSet.copyOf(transform(
+ containmentReferenceChanges, VALUE));
+ return containementDifferenceValues;
+ }
+
+ private static Predicate<? super Object> matchOfContainmentDiff(
+ final ImmutableSet<EObject> containementDifferenceValues) {
+ return new Predicate<Object>() {
+ public boolean apply(Object input) {
+ boolean ret = false;
+ if (input instanceof Match) {
+ Match match = (Match)input;
+ if (containementDifferenceValues.contains(match.getLeft())
+ || containementDifferenceValues.contains(match.getRight())
+ || containementDifferenceValues.contains(match.getOrigin())) {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+ };
+ }
+
+ private Predicate<? super Object> matchWithNoChildren() {
+ return new Predicate<Object>() {
+ public boolean apply(Object input) {
+ boolean ret = false;
+ if (input instanceof Match) {
+ Match match = (Match)input;
+ ret = Iterables.isEmpty(MatchItemProviderSpec.this.getChildrenIterable(match));
+ }
+ return ret;
+ }
+ };
+ }
+
+ private static Predicate<? super Object> emptyMatch() {
+ return new Predicate<Object>() {
+ public boolean apply(Object input) {
+ if (input instanceof Match) {
+ final Match match = ((Match)input);
+ return match.getLeft() == null && match.getRight() == null && match.getOrigin() == null;
+ }
+ return false;
+ }
+ };
+ }
+
+ static final Predicate<? super Object> REFINED_DIFF = new Predicate<Object>() {
+ public boolean apply(Object input) {
+ boolean ret = false;
+ if (input instanceof Diff) {
+ Diff diff = (Diff)input;
+ ret = !diff.getRefines().isEmpty();
+ }
+ return ret;
+ }
+ };
+
+ private static final Predicate<? super Object> PSEUDO_CONFLICT_DIFF = new Predicate<Object>() {
+ public boolean apply(Object input) {
+ boolean ret = false;
+ if (input instanceof Diff) {
+ Diff diff = (Diff)input;
+ Conflict conflict = diff.getConflict();
+ if (conflict != null && conflict.getKind() == ConflictKind.PSEUDO) {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+ };
+
+ private static final Predicate<? super Object> PSEUDO_DELETE_CONFLICT = new Predicate<Object>() {
+ public boolean apply(Object input) {
+ boolean ret = false;
+ if (input instanceof ReferenceChange) {
+ ReferenceChange referenceChange = (ReferenceChange)input;
+ Conflict conflict = referenceChange.getConflict();
+ if (conflict != null) {
+ EReference eReference = referenceChange.getReference();
+ EObject value = referenceChange.getValue();
+ Iterable<ReferenceChange> conflictualReferenceChanges = filter(conflict.getDifferences(),
+ ReferenceChange.class);
+ for (ReferenceChange conflictualReferenceChange : conflictualReferenceChanges) {
+ if (conflictualReferenceChange != referenceChange
+ && conflictualReferenceChange.getReference() == eReference
+ && conflictualReferenceChange.getValue() == value) {
+ ret = true;
+ }
+ }
+ }
+ }
+ return ret;
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(Object object) {
+ Match match = (Match)object;
+ return !isEmpty(getChildrenIterable(match));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ return new ComposedStyledString(getText(object));
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchResourceItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchResourceItemProviderSpec.java
index facbf985c..90c5fbc15 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchResourceItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/MatchResourceItemProviderSpec.java
@@ -1,93 +1,168 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.provider.spec;
-
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.compare.MatchResource;
-import org.eclipse.emf.compare.provider.MatchResourceItemProvider;
-
-/**
- * Specialized {@link MatchResourceItemProvider} returning nice output for {@link #getText(Object)} and
- * {@link #getImage(Object)}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class MatchResourceItemProviderSpec extends MatchResourceItemProvider {
-
- /**
- * Constructor calling super {@link #MatchResourceItemProviderSpec(AdapterFactory)}.
- *
- * @param adapterFactory
- * the adapter factory
- */
- public MatchResourceItemProviderSpec(AdapterFactory adapterFactory) {
- super(adapterFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.MatchResourceItemProvider#getText(java.lang.Object)
- */
- @Override
- public String getText(Object object) {
- final MatchResource matchResource = (MatchResource)object;
- final String leftURI = matchResource.getLeftURI();
- final String rightURI = matchResource.getRightURI();
-
- final String commonBase = getCommonBase(leftURI, rightURI);
-
- String text = ""; //$NON-NLS-1$
- if (leftURI != null) {
- text += leftURI.substring(commonBase.length());
- }
- text += " <-> "; //$NON-NLS-1$
- if (rightURI != null) {
- text += rightURI.substring(commonBase.length());
- }
- // TODO is that really useful info?
- // if (matchResource.eContainer() instanceof Comparison
- // && ((Comparison)matchResource.eContainer()).isThreeWay()) {
- // final String originURI = matchResource.getOriginURI();
- // text += " (" + originURI + ")";
- // }
- return text;
- }
-
- /**
- * Returns the longest common starting substring of the two given strings.
- *
- * @param left
- * First of the two strings for which we need the common starting substring.
- * @param right
- * Second of the two strings for which we need the common starting substring.
- * @return The longest common starting substring of the two given strings.
- */
- public String getCommonBase(String left, String right) {
- if (left == null || right == null) {
- return ""; //$NON-NLS-1$
- }
-
- final char[] leftChars = left.toCharArray();
- final char[] rightChars = right.toCharArray();
-
- final StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < Math.min(leftChars.length, rightChars.length); i++) {
- if (leftChars[i] == rightChars[i]) {
- buffer.append(leftChars[i]);
- } else {
- break;
- }
- }
-
- return buffer.toString();
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.provider.spec;
+
+import static com.google.common.collect.Iterables.filter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.MatchResourceItemProvider;
+import org.eclipse.emf.compare.provider.utils.ComposedStyledString;
+import org.eclipse.emf.compare.provider.utils.IStyledString;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+
+/**
+ * Specialized {@link MatchResourceItemProvider} returning nice output for {@link #getText(Object)} and
+ * {@link #getImage(Object)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class MatchResourceItemProviderSpec extends MatchResourceItemProvider implements IItemStyledLabelProvider {
+
+ /**
+ * Constructor calling super {@link #MatchResourceItemProviderSpec(AdapterFactory)}.
+ *
+ * @param adapterFactory
+ * the adapter factory
+ */
+ public MatchResourceItemProviderSpec(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ }
+
+ @Override
+ public Collection<?> getChildren(Object object) {
+ Collection<Object> children = new ArrayList<Object>();
+ MatchResource matchResource = (MatchResource)object;
+ Comparison comparison = matchResource.getComparison();
+ for (ResourceAttachmentChange rac : filter(comparison.getDifferences(),
+ ResourceAttachmentChange.class)) {
+ final String diffResourceURI = rac.getResourceURI();
+ if (diffResourceURI != null
+ && (diffResourceURI.equals(matchResource.getLeftURI())
+ || diffResourceURI.equals(matchResource.getRightURI()) || diffResourceURI
+ .equals(matchResource.getOriginURI()))) {
+ children.add(rac);
+ }
+ }
+ return children;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.MatchResourceItemProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object object) {
+ final MatchResource matchResource = (MatchResource)object;
+ final String leftURI = matchResource.getLeftURI();
+ final String rightURI = matchResource.getRightURI();
+
+ final String commonBase = getCommonBase(leftURI, rightURI);
+
+ String text = ""; //$NON-NLS-1$
+ if (leftURI != null) {
+ text += leftURI.substring(commonBase.length());
+ }
+ text += " <-> "; //$NON-NLS-1$
+ if (rightURI != null) {
+ text += rightURI.substring(commonBase.length());
+ }
+ if (matchResource.eContainer() instanceof Comparison
+ && ((Comparison)matchResource.eContainer()).isThreeWay()) {
+ final String originURI = matchResource.getOriginURI();
+ text += " (" + originURI.substring(commonBase.length()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return text;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.MatchResourceItemProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Object getImage(Object object) {
+ final MatchResource matchResource = (MatchResource)object;
+ Resource resource = matchResource.getLeft();
+ if (resource == null) {
+ resource = matchResource.getRight();
+ if (resource == null) {
+ resource = matchResource.getOrigin();
+ }
+ }
+
+ if (resource != null) {
+ IItemLabelProvider itemLabelProvider = (IItemLabelProvider)getRootAdapterFactory().adapt(
+ resource, IItemLabelProvider.class);
+
+ Object image = itemLabelProvider.getImage(resource);
+ if (image != null) {
+ return image;
+ } else {
+ return super.getImage(object);
+ }
+ } else {
+ return super.getImage(object);
+ }
+ }
+
+ /**
+ * Returns the longest common starting substring of the two given strings.
+ *
+ * @param left
+ * First of the two strings for which we need the common starting substring.
+ * @param right
+ * Second of the two strings for which we need the common starting substring.
+ * @return The longest common starting substring of the two given strings.
+ */
+ public String getCommonBase(String left, String right) {
+ if (left == null || right == null) {
+ return ""; //$NON-NLS-1$
+ }
+
+ final char[] leftChars = left.toCharArray();
+ final char[] rightChars = right.toCharArray();
+
+ final StringBuilder buffer = new StringBuilder();
+ StringBuilder fragmentBuffer = new StringBuilder();
+ for (int i = 0; i < Math.min(leftChars.length, rightChars.length); i++) {
+ if (leftChars[i] == rightChars[i]) {
+ fragmentBuffer.append(leftChars[i]);
+
+ if (leftChars[i] == '\\' || leftChars[i] == '/') {
+ buffer.append(fragmentBuffer);
+ fragmentBuffer = new StringBuilder();
+ }
+ } else {
+ break;
+ }
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ return new ComposedStyledString(getText(object));
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/OverlayImageProvider.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/OverlayImageProvider.java
new file mode 100644
index 000000000..b5ba7a103
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/OverlayImageProvider.java
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.provider.spec;
+
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Lists.newArrayList;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+
+import com.google.common.base.Predicate;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.common.util.ResourceLocator;
+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.DifferenceState;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.ComposedImage;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class OverlayImageProvider {
+
+ private final boolean fLeftIsLocal;
+
+ private final ResourceLocator fResourceLocator;
+
+ /**
+ *
+ */
+ public OverlayImageProvider(ResourceLocator resourceLocator, boolean leftIsLocal) {
+ this.fResourceLocator = resourceLocator;
+ this.fLeftIsLocal = leftIsLocal;
+ }
+
+ public Object getComposedImage(Diff diff, Object imageToCompose) {
+ String overlay = getImageOverlay(diff);
+ return getComposedImage(imageToCompose, overlay);
+ }
+
+ public Object getComposedImage(Match match, Object imageToCompose) {
+ String overlay = getImageOverlay(match);
+ return getComposedImage(imageToCompose, overlay);
+ }
+
+ private Object getComposedImage(Object imageToCompose, String overlay) {
+ Collection<Object> images = newArrayList();
+ images.add(imageToCompose);
+ if (overlay != null) {
+ Object image = fResourceLocator.getImage(overlay);
+ images.add(image);
+ }
+ return new ComposedImageExtension(images);
+ }
+
+ private String getImageOverlay(Diff diff) {
+ final DifferenceSource source = diff.getSource();
+ final Match match = diff.getMatch();
+ final Conflict conflict = diff.getConflict();
+ final DifferenceKind diffKind = diff.getKind();
+ final Comparison c = match.getComparison();
+ String path = "full/ovr16/";
+
+ if (diff.getState() == DifferenceState.MERGED) {
+ path += "merged_ov";
+ } else if (diff.getState() == DifferenceState.DISCARDED) {
+ path += "removed_ov";
+ } else if (c.isThreeWay()) {
+ String filext = "";
+ if (conflict != null) {
+ if (conflict.getKind() == ConflictKind.REAL) {
+ filext = ".png";
+ path += "conf";
+ path += getConflictWay(source);
+ }
+ // if (conflict.getKind() == ConflictKind.PSEUDO) {
+ // path += "pconf";
+ // }
+ } else {
+ switch (source) {
+ case LEFT:
+ if (fLeftIsLocal) {
+ path += "r_out";
+ } else {
+ path += "out";
+ }
+ break;
+ case RIGHT:
+ if (fLeftIsLocal) {
+ path += "r_in";
+ } else {
+ path += "in";
+ }
+ break;
+ default:
+ // Cannot happen ... for now
+ break;
+ }
+ }
+
+ switch (diffKind) {
+ case ADD:
+ path += "add_ov";
+ break;
+ case DELETE:
+ path += "del_ov";
+ break;
+ case CHANGE:
+ // fallthrough
+ case MOVE:
+ path += "chg_ov";
+ break;
+ default:
+ // Cannot happen ... for now
+ break;
+ }
+ path += filext;
+ } else {
+ path += getPathForTwoWayDiff(diffKind);
+ }
+ return path;
+ }
+
+ private String getPathForTwoWayDiff(final DifferenceKind diffKind) {
+ final String path;
+ switch (diffKind) {
+ case ADD:
+ if (fLeftIsLocal) {
+ path = "add_ov";
+ } else {
+ path = "del_ov";
+ }
+ break;
+ case DELETE:
+ if (fLeftIsLocal) {
+ path = "del_ov";
+ } else {
+ path = "add_ov";
+ }
+ break;
+ case CHANGE:
+ // fallthrough
+ case MOVE:
+ path = "chg_ov";
+ break;
+ default:
+ path = "";
+ break;
+ }
+ return path;
+ }
+
+ private String getConflictWay(final DifferenceSource source) {
+ final String path;
+ if (source == DifferenceSource.LEFT && !fLeftIsLocal) {
+ path = "r_";
+ } else if (source == DifferenceSource.RIGHT && fLeftIsLocal) {
+ path = "r_";
+ } else {
+ path = "";
+ }
+ return path;
+ }
+
+ private String getImageOverlay(Match match) {
+ String path = null;
+ final EObject ancestor = match.getOrigin();
+ final EObject left = match.getLeft();
+ final EObject right = match.getRight();
+
+ final Iterable<Diff> differences = match.getAllDifferences();
+
+ if (match.getComparison().isThreeWay()) {
+ boolean hasConflicts = any(differences, hasConflict(ConflictKind.REAL, ConflictKind.PSEUDO));
+
+ if (ancestor == null) {
+ if (left == null) {
+ if (right != null) {
+ if (fLeftIsLocal) {
+ path = "r_inadd_ov";
+ } else {
+ path = "inadd_ov";
+ }
+ }
+ } else if (right == null) {
+ if (fLeftIsLocal) {
+ path = "r_outadd_ov";
+ } else {
+ path = "outadd_ov";
+ }
+ } else if (hasConflicts && any(differences, hasConflict(ConflictKind.REAL))) {
+ path = "confadd_ov.png";
+ }
+ } else if (left == null) {
+ if (right == null) {
+ // path = Differencer.CONFLICTING | Differencer.DELETION |
+ // Differencer.PSEUDO_CONFLICT;
+ } else if (!hasConflicts) {
+ if (fLeftIsLocal) {
+ path = "r_outdel_ov";
+ } else {
+ path = "outdel_ov";
+ }
+ } else if (any(differences, hasConflict(ConflictKind.REAL))) {
+ path = "confdel_ov.png";
+ }
+ } else if (right == null) {
+ if (!hasConflicts) {
+ if (fLeftIsLocal) {
+ path = "r_indel_ov";
+ } else {
+ path = "indel_ov";
+ }
+ } else if (any(differences, hasConflict(ConflictKind.REAL))) {
+ path = "confchg_ov.png";
+ }
+ } else {
+ boolean ay = isEmpty(filter(differences, LEFT_DIFF));
+ boolean am = isEmpty(filter(differences, RIGHT_DIFF));
+
+ if (isEmpty(differences)) {
+ // empty
+ } else if (ay && !am) {
+ if (fLeftIsLocal) {
+ path = "r_inchg_ov";
+ } else {
+ path = "inchg_ov";
+ }
+ } else if (!ay && am) {
+ if (fLeftIsLocal) {
+ path = "r_outchg_ov";
+ } else {
+ path = "outchg_ov";
+ }
+ } else {
+ if (hasConflicts && any(differences, hasConflict(ConflictKind.REAL))) {
+ path = "confchg_ov.png";
+ } else {
+ path = "r_inoutchg_ov.gif";
+ }
+ }
+ }
+ } else if (left == null) {
+ if (right != null) {
+ if (fLeftIsLocal) {
+ path = "add_ov";
+ } else {
+ path = "del_ov";
+ }
+ }
+ } else if (right == null) {
+ if (fLeftIsLocal) {
+ path = "del_ov";
+ } else {
+ path = "add_ov";
+ }
+ } else if (!isEmpty(differences)) {
+ path = "chg_ov";
+ }
+
+ String ret = null;
+ if (path != null) {
+ ret = "full/ovr16/" + path;
+ }
+ return ret;
+ }
+
+ private static final Predicate<Diff> LEFT_DIFF = new Predicate<Diff>() {
+ public boolean apply(Diff input) {
+ return input != null && input.getSource() == DifferenceSource.LEFT;
+ }
+ };
+
+ private static final Predicate<Diff> RIGHT_DIFF = new Predicate<Diff>() {
+ public boolean apply(Diff input) {
+ return input != null && input.getSource() == DifferenceSource.RIGHT;
+ }
+ };
+
+ private final class ComposedImageExtension extends ComposedImage {
+
+ /**
+ * @param images
+ */
+ ComposedImageExtension(Collection<?> images) {
+ super(images);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ComposedImage#getDrawPoints(org.eclipse.emf.edit.provider.ComposedImage.Size)
+ */
+ @Override
+ public List<Point> getDrawPoints(Size size) {
+ List<ComposedImage.Point> result = super.getDrawPoints(size);
+ if (result.size() > 1) {
+ result.get(1).x = 12;
+ result.get(1).y = 2;
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ComposedImage#getSize(java.util.Collection)
+ */
+ @Override
+ public Size getSize(Collection<? extends Size> imageSizes) {
+ this.imageSizes = newArrayList(imageSizes);
+ List<Point> drawPoints = getDrawPoints(null);
+
+ Size result = new Size();
+ for (int i = 0; i < imageSizes.size(); i++) {
+ Size size = this.imageSizes.get(i);
+ Point point = drawPoints.get(i);
+
+ result.width = Math.max(result.width, size.width + Math.abs(point.x));
+ result.height = Math.max(result.height, size.height + Math.abs(point.y));
+ }
+ return result;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ReferenceChangeItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ReferenceChangeItemProviderSpec.java
index 5c9a6e61a..f20e11fee 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ReferenceChangeItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ReferenceChangeItemProviderSpec.java
@@ -1,245 +1,266 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.provider.spec;
-
-import static com.google.common.base.Predicates.not;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Lists.newArrayList;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.util.URI;
-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.provider.AdapterFactoryUtil;
-import org.eclipse.emf.compare.provider.ReferenceChangeItemProvider;
-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.edit.provider.ITreeItemContentProvider;
-
-/**
- * Specialized {@link ReferenceChangeItemProvider} returning nice output for {@link #getText(Object)} and
- * {@link #getImage(Object)}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class ReferenceChangeItemProviderSpec extends ReferenceChangeItemProvider {
-
- /**
- * Constructor calling super {@link #ReferenceChangeItemProvider(AdapterFactory)}.
- *
- * @param adapterFactory
- * the adapter factory
- */
- public ReferenceChangeItemProviderSpec(AdapterFactory adapterFactory) {
- super(adapterFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.ReferenceChangeItemProvider#getText(java.lang.Object)
- */
- @Override
- public String getText(Object object) {
- final ReferenceChange refChange = (ReferenceChange)object;
-
- final String valueText = getValueText(refChange);
- final String referenceText = getReferenceText(refChange);
-
- String remotely = ""; //$NON-NLS-1$
- if (refChange.getSource() == DifferenceSource.RIGHT) {
- remotely = "remotely "; //$NON-NLS-1$
- }
-
- String ret = ""; //$NON-NLS-1$
- switch (refChange.getKind()) {
- case ADD:
- ret = valueText + " has been " + remotely + "added to " + referenceText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case DELETE:
- ret = valueText + " has been " + remotely + "deleted from " + referenceText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case CHANGE:
- String changeText = changeText(refChange, refChange.getReference());
- ret = referenceText + " " + valueText + " has been " + remotely + changeText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- case MOVE:
- ret = valueText + " has been " + remotely + "moved in " + referenceText; //$NON-NLS-1$ //$NON-NLS-2$
- break;
- default:
- throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
- + " value: " + refChange.getKind()); //$NON-NLS-1$
- }
-
- return ret;
- }
-
- static String changeText(final Diff diff, EStructuralFeature feature) {
- DifferenceSource source = diff.getSource();
- Match matchOfInterrest = diff.getMatch();
- final EObject sourceSide;
- final EObject otherSide;
- if (source == DifferenceSource.LEFT) {
- sourceSide = matchOfInterrest.getLeft();
- otherSide = matchOfInterrest.getRight();
- } else { // source == DifferenceSource.RIGHT
- sourceSide = matchOfInterrest.getRight();
- otherSide = matchOfInterrest.getLeft();
- }
- String changeText = changeText(feature, sourceSide, otherSide);
- return changeText;
- }
-
- private static String changeText(final EStructuralFeature eStructuralFeature, EObject sourceSide,
- EObject otherSide) {
- String changeText;
- if (sourceSide != null) {
- Object leftValue = ReferenceUtil.safeEGet(sourceSide, eStructuralFeature);
- if (leftValue == null || isStringAndNullOrEmpty(leftValue)) {
- changeText = "unset"; //$NON-NLS-1$
- } else if (otherSide != null) {
- Object otherValue = ReferenceUtil.safeEGet(otherSide, eStructuralFeature);
- if (otherValue == null || isStringAndNullOrEmpty(otherValue)) {
- changeText = "set"; //$NON-NLS-1$
- } else {
- changeText = "changed"; //$NON-NLS-1$
- }
- } else {
- changeText = "set"; //$NON-NLS-1$
- }
- } else {
- changeText = "unset"; //$NON-NLS-1$
- }
- return changeText;
- }
-
- private static boolean isStringAndNullOrEmpty(Object s) {
- if (s instanceof String) {
- return Strings.isNullOrEmpty((String)s);
- } else {
- return false;
- }
- }
-
- protected String getReferenceText(final ReferenceChange refChange) {
- return refChange.getReference().getName();
- }
-
- protected String getValueText(final ReferenceChange refChange) {
- String value = AdapterFactoryUtil.getText(getRootAdapterFactory(), refChange.getValue());
- if (value == null) {
- value = "<null>"; //$NON-NLS-1$
- } else {
- value = org.eclipse.emf.compare.provider.spec.Strings.elide(value, 50, "..."); //$NON-NLS-1$
- }
- return value;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.provider.ReferenceChangeItemProvider#getImage(java.lang.Object)
- */
- @Override
- public Object getImage(Object object) {
- ReferenceChange refChange = (ReferenceChange)object;
-
- Object image = AdapterFactoryUtil.getImage(getRootAdapterFactory(), refChange.getValue());
-
- return image;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
- */
- @Override
- public Collection<?> getChildren(Object object) {
- Collection<?> superChildren = super.getChildren(object);
- List<? super Object> ret = newArrayList(superChildren);
-
- ReferenceChange referenceChange = (ReferenceChange)object;
- EReference reference = referenceChange.getReference();
-
- if (reference.isContainment()) {
- Match matchOfValue = referenceChange.getMatch().getComparison().getMatch(
- referenceChange.getValue());
- if (matchOfValue != null) {
- Collection<?> children = getChildren(matchOfValue);
- children.remove(referenceChange);
- ret.addAll(children);
- }
- }
-
- return ImmutableList.copyOf(filter(ret, not(MatchItemProviderSpec.REFINED_DIFF)));
-
- }
-
- private Collection<?> getChildren(Match matchOfValue) {
- final Collection<?> children;
- ITreeItemContentProvider matchItemContentProvider = (ITreeItemContentProvider)adapterFactory.adapt(
- matchOfValue, ITreeItemContentProvider.class);
- if (matchItemContentProvider != null) {
- Collection<?> itemProviderChildren = matchItemContentProvider.getChildren(matchOfValue);
- if (itemProviderChildren instanceof ImmutableCollection<?>) {
- children = newArrayList(itemProviderChildren);
- } else {
- children = itemProviderChildren;
- }
-
- Iterator<?> childrenIterator = children.iterator();
- while (childrenIterator.hasNext()) {
- Object child = childrenIterator.next();
- if (child instanceof Match) {
- if (!matchItemContentProvider.hasChildren(child)) {
- childrenIterator.remove();
- }
- }
-
- }
- } else {
- children = ImmutableList.of();
- }
- return children;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getForeground(java.lang.Object)
- */
- @Override
- public Object getForeground(Object object) {
- ReferenceChange referenceChange = (ReferenceChange)object;
- switch (referenceChange.getState()) {
- case MERGED:
- case DISCARDED:
- return URI.createURI("color://rgb/156/156/156"); //$NON-NLS-1$
- default:
- return super.getForeground(object);
- }
- }
-
-}
+/*******************************************************************************
+ * 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.provider.spec;
+
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Lists.newArrayList;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.URI;
+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.provider.AdapterFactoryUtil;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.ReferenceChangeItemProvider;
+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.utils.ReferenceUtil;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
+
+/**
+ * Specialized {@link ReferenceChangeItemProvider} returning nice output for {@link #getText(Object)} and
+ * {@link #getImage(Object)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class ReferenceChangeItemProviderSpec extends ReferenceChangeItemProvider implements IItemStyledLabelProvider {
+
+ private final OverlayImageProvider overlayProvider;
+
+ /**
+ * Constructor calling super {@link #ReferenceChangeItemProvider(AdapterFactory)}.
+ *
+ * @param adapterFactory
+ * the adapter factory
+ */
+ public ReferenceChangeItemProviderSpec(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ overlayProvider = new OverlayImageProvider(getResourceLocator(), true);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.ReferenceChangeItemProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object object) {
+ return getStyledText(object).getString();
+ }
+
+ static String changeText(final Diff diff, EStructuralFeature feature) {
+ DifferenceSource source = diff.getSource();
+ Match matchOfInterrest = diff.getMatch();
+ final EObject sourceSide;
+ final EObject otherSide;
+ if (source == DifferenceSource.LEFT) {
+ sourceSide = matchOfInterrest.getLeft();
+ otherSide = matchOfInterrest.getRight();
+ } else { // source == DifferenceSource.RIGHT
+ sourceSide = matchOfInterrest.getRight();
+ otherSide = matchOfInterrest.getLeft();
+ }
+ String changeText = changeText(feature, sourceSide, otherSide);
+ return changeText;
+ }
+
+ private static String changeText(final EStructuralFeature eStructuralFeature, EObject sourceSide,
+ EObject otherSide) {
+ String changeText;
+ if (sourceSide != null) {
+ Object leftValue = ReferenceUtil.safeEGet(sourceSide, eStructuralFeature);
+ if (leftValue == null || isStringAndNullOrEmpty(leftValue)) {
+ changeText = "unset"; //$NON-NLS-1$
+ } else if (otherSide != null) {
+ Object otherValue = ReferenceUtil.safeEGet(otherSide, eStructuralFeature);
+ if (otherValue == null || isStringAndNullOrEmpty(otherValue)) {
+ changeText = "set"; //$NON-NLS-1$
+ } else {
+ changeText = "changed"; //$NON-NLS-1$
+ }
+ } else {
+ changeText = "set"; //$NON-NLS-1$
+ }
+ } else {
+ changeText = "unset"; //$NON-NLS-1$
+ }
+ return changeText;
+ }
+
+ private static boolean isStringAndNullOrEmpty(Object s) {
+ if (s instanceof String) {
+ return Strings.isNullOrEmpty((String)s);
+ } else {
+ return false;
+ }
+ }
+
+ protected String getReferenceText(final ReferenceChange refChange) {
+ return refChange.getReference().getName();
+ }
+
+ protected String getValueText(final ReferenceChange refChange) {
+ String value = AdapterFactoryUtil.getText(getRootAdapterFactory(), refChange.getValue());
+ if (value == null) {
+ value = "<null>"; //$NON-NLS-1$
+ } else {
+ value = org.eclipse.emf.compare.provider.spec.Strings.elide(value, 50, "..."); //$NON-NLS-1$
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.ReferenceChangeItemProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Object getImage(Object object) {
+ ReferenceChange refChange = (ReferenceChange)object;
+
+ Object refChangeValueImage = AdapterFactoryUtil.getImage(getRootAdapterFactory(), refChange
+ .getValue());
+
+ Object diffImage = overlayProvider.getComposedImage(refChange, refChangeValueImage);
+ Object ret = overlayImage(object, diffImage);
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
+ */
+ @Override
+ public Collection<?> getChildren(Object object) {
+ Collection<?> superChildren = super.getChildren(object);
+ List<? super Object> ret = newArrayList(superChildren);
+
+ ReferenceChange referenceChange = (ReferenceChange)object;
+ EReference reference = referenceChange.getReference();
+
+ if (reference.isContainment()) {
+ Match matchOfValue = referenceChange.getMatch().getComparison().getMatch(
+ referenceChange.getValue());
+ if (matchOfValue != null) {
+ Collection<?> children = getChildren(matchOfValue);
+ children.remove(referenceChange);
+ ret.addAll(children);
+ }
+ }
+
+ return ImmutableList.copyOf(filter(filter(ret, not(instanceOf(ResourceAttachmentChange.class))),
+ not(MatchItemProviderSpec.REFINED_DIFF)));
+
+ }
+
+ private Collection<?> getChildren(Match matchOfValue) {
+ final Collection<?> children;
+ ITreeItemContentProvider matchItemContentProvider = (ITreeItemContentProvider)adapterFactory.adapt(
+ matchOfValue, ITreeItemContentProvider.class);
+ if (matchItemContentProvider != null) {
+ Collection<?> itemProviderChildren = matchItemContentProvider.getChildren(matchOfValue);
+ if (itemProviderChildren instanceof ImmutableCollection<?>) {
+ children = newArrayList(itemProviderChildren);
+ } else {
+ children = itemProviderChildren;
+ }
+
+ Iterator<?> childrenIterator = children.iterator();
+ while (childrenIterator.hasNext()) {
+ Object child = childrenIterator.next();
+ if (child instanceof Match) {
+ if (!matchItemContentProvider.hasChildren(child)) {
+ childrenIterator.remove();
+ }
+ }
+
+ }
+ } else {
+ children = ImmutableList.of();
+ }
+ return children;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getForeground(java.lang.Object)
+ */
+ @Override
+ public Object getForeground(Object object) {
+ ReferenceChange referenceChange = (ReferenceChange)object;
+ switch (referenceChange.getState()) {
+ case MERGED:
+ case DISCARDED:
+ return URI.createURI("color://rgb/156/156/156"); //$NON-NLS-1$
+ default:
+ return super.getForeground(object);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ final ReferenceChange refChange = (ReferenceChange)object;
+
+ final String valueText = getValueText(refChange);
+
+ final String referenceText = getReferenceText(refChange);
+
+ ComposedStyledString ret = new ComposedStyledString(valueText);
+ ret.append(" [" + referenceText, Style.DECORATIONS_STYLER); //$NON-NLS-1$
+
+ switch (refChange.getKind()) {
+ case ADD:
+ ret.append(" add", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case DELETE:
+ ret.append(" delete", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case CHANGE:
+ ret.append(" " + changeText(refChange, refChange.getReference()), //$NON-NLS-1$
+ Style.DECORATIONS_STYLER);
+ break;
+ case MOVE:
+ ret.append(" move", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ default:
+ throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
+ + " value: " + refChange.getKind()); //$NON-NLS-1$
+ }
+ ret.append("]", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+
+ return ret;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ResourceAttachmentChangeItemProviderSpec.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ResourceAttachmentChangeItemProviderSpec.java
new file mode 100644
index 000000000..bf3656a9e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/spec/ResourceAttachmentChangeItemProviderSpec.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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.provider.spec;
+
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Lists.newArrayList;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.provider.ResourceAttachmentChangeItemProvider;
+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.ecore.EObject;
+import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
+
+/**
+ * Specialized {@link ResourceAttachmentChangeItemProvider} returning nice output for {@link #getText(Object)}
+ * and {@link #getImage(Object)}.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class ResourceAttachmentChangeItemProviderSpec extends ResourceAttachmentChangeItemProvider implements IItemStyledLabelProvider {
+
+ private final OverlayImageProvider overlayProvider;
+
+ /**
+ * Constructor calling super {@link #ResourceAttachmentChangeItemProvider(AdapterFactory)}.
+ *
+ * @param adapterFactory
+ * The adapter factory.
+ */
+ public ResourceAttachmentChangeItemProviderSpec(AdapterFactory adapterFactory) {
+ super(adapterFactory);
+ overlayProvider = new OverlayImageProvider(getResourceLocator(), true);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.ResourceAttachmentChangeItemProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Collection<?> getChildren(Object object) {
+ Collection<?> superChildren = super.getChildren(object);
+ List<? super Object> ret = newArrayList(superChildren);
+
+ ResourceAttachmentChange resourceAttachmentChange = (ResourceAttachmentChange)object;
+ final EObject value;
+ switch (resourceAttachmentChange.getSource()) {
+ case LEFT:
+ value = resourceAttachmentChange.getMatch().getLeft();
+ break;
+ case RIGHT:
+ value = resourceAttachmentChange.getMatch().getRight();
+ break;
+ default:
+ value = null;
+ new IllegalStateException();
+ break;
+ }
+
+ Match matchOfValue = resourceAttachmentChange.getMatch().getComparison().getMatch(value);
+ if (matchOfValue != null) {
+ Collection<?> children = getChildren(matchOfValue);
+ children.remove(resourceAttachmentChange);
+ ret.addAll(children);
+ }
+
+ return ImmutableList.copyOf(filter(ret, not(MatchItemProviderSpec.REFINED_DIFF)));
+ }
+
+ private Collection<?> getChildren(Match matchOfValue) {
+ final Collection<?> children;
+ ITreeItemContentProvider matchItemContentProvider = (ITreeItemContentProvider)adapterFactory.adapt(
+ matchOfValue, ITreeItemContentProvider.class);
+ if (matchItemContentProvider != null) {
+ Collection<?> itemProviderChildren = matchItemContentProvider.getChildren(matchOfValue);
+ if (itemProviderChildren instanceof ImmutableCollection<?>) {
+ children = newArrayList(itemProviderChildren);
+ } else {
+ children = itemProviderChildren;
+ }
+
+ Iterator<?> childrenIterator = children.iterator();
+ while (childrenIterator.hasNext()) {
+ Object child = childrenIterator.next();
+ if (child instanceof Match) {
+ if (!matchItemContentProvider.hasChildren(child)) {
+ childrenIterator.remove();
+ }
+ }
+
+ }
+ } else {
+ children = ImmutableList.of();
+ }
+ return children;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.MatchItemProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Object getImage(Object object) {
+ final Match match = ((ResourceAttachmentChange)object).getMatch();
+ Object ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getLeft());
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getRight());
+ }
+ if (ret == null) {
+ ret = AdapterFactoryUtil.getImage(getRootAdapterFactory(), match.getOrigin());
+ }
+ if (ret == null) {
+ ret = super.getImage(object);
+ }
+
+ Object matchImage = overlayProvider.getComposedImage((ResourceAttachmentChange)object, ret);
+ ret = overlayImage(object, matchImage);
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.ResourceAttachmentChangeItemProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object object) {
+ return getStyledText(object).getString();
+ }
+
+ public IComposedStyledString getStyledText(Object object) {
+ final Match match = ((ResourceAttachmentChange)object).getMatch();
+ String value = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getLeft());
+ if (value == null) {
+ value = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getRight());
+ }
+ if (value == null) {
+ value = AdapterFactoryUtil.getText(getRootAdapterFactory(), match.getOrigin());
+ }
+ if (value == null) {
+ value = super.getText(object);
+ }
+
+ ComposedStyledString ret = new ComposedStyledString(value);
+
+ DifferenceKind labelValue = ((ResourceAttachmentChange)object).getKind();
+ String label = labelValue == null ? "" : labelValue.toString().toLowerCase(); //$NON-NLS-1$
+
+ return ret.append(" [resource contents " + label + "]", Style.DECORATIONS_STYLER); //$NON-NLS-1$ //$NON-NLS-2$
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/ComposedStyledString.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/ComposedStyledString.java
new file mode 100644
index 000000000..9bf91ed04
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/ComposedStyledString.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.provider.utils;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString;
+import org.eclipse.emf.compare.provider.utils.IStyledString.Style;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class ComposedStyledString implements IComposedStyledString {
+
+ private final List<IStyledString> content;
+
+ public ComposedStyledString() {
+ content = newArrayList();
+ }
+
+ public ComposedStyledString(String text) {
+ this(text, Style.NO_STYLE);
+ }
+
+ public ComposedStyledString(String text, Style style) {
+ this();
+ append(text, style);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.utils.IStyledString.IComposedStyledString#getString()
+ */
+ public String getString() {
+ StringBuilder sb = new StringBuilder();
+ for (IStyledString styledString : this) {
+ sb.append(styledString.getString());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.util.IComposedStyledString#append(java.lang.String)
+ */
+ public IComposedStyledString append(String str) {
+ content.add(new StyledString(str, IStyledString.Style.NO_STYLE));
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.util.IComposedStyledString#append(java.lang.String,
+ * org.eclipse.emf.compare.ide.ui.internal.util.IComposedStyledString.Style)
+ */
+ public IComposedStyledString append(String str, Style style) {
+ content.add(new StyledString(str, style));
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Iterable#iterator()
+ */
+ public Iterator<IStyledString> iterator() {
+ return content.iterator();
+ }
+
+ private static final class StyledString implements IStyledString {
+ private final String str;
+
+ private final Style style;
+
+ StyledString(String str, Style style) {
+ this.str = str;
+ this.style = style;
+ }
+
+ /**
+ * @return the str
+ */
+ public String getString() {
+ return str;
+ }
+
+ /**
+ * @return the style
+ */
+ public Style getStyle() {
+ return style;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/IStyledString.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/IStyledString.java
new file mode 100644
index 000000000..344795dd8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/provider/utils/IStyledString.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.provider.utils;
+
+import org.eclipse.emf.common.util.URI;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public interface IStyledString {
+
+ String getString();
+
+ Style getStyle();
+
+ interface IComposedStyledString extends Iterable<IStyledString> {
+
+ IComposedStyledString append(String str);
+
+ IComposedStyledString append(String str, Style style);
+
+ String getString();
+ }
+
+ public static final class Style {
+
+ public static final Style NO_STYLE = new Style(null, null, null, false, null, null, null, null, null);
+
+ public static final Style QUALIFIER_STYLER = new Style(null, null, null, false, null, null, null,
+ null, null);
+
+ public static final Style COUNTER_STYLER = new Style(null, null, null, false, null, null, null, null,
+ null);
+
+ public static final Style DECORATIONS_STYLER = new Style(null, null, null, false, null, null, null,
+ null, null);
+
+ private final URI font;
+
+ private final URI backgroundColor;
+
+ private final URI foregroundColor;
+
+ private final boolean isStrikedout;
+
+ private final URI strikeoutColor;
+
+ private final UnderLineStyle underlineStyle;
+
+ private final URI underlineColor;
+
+ private final BorderStyle borderStyle;
+
+ private final URI borderColor;
+
+ private Style(URI font, URI backgroundColor, URI foregroundColor, boolean isStrikedout,
+ URI strikeoutColor, UnderLineStyle underlineStyle, URI underlineColor,
+ BorderStyle borderStyle, URI borderColor) {
+ this.font = font;
+ this.backgroundColor = backgroundColor;
+ this.foregroundColor = foregroundColor;
+ this.isStrikedout = isStrikedout;
+ this.strikeoutColor = strikeoutColor;
+ this.underlineStyle = underlineStyle;
+ this.underlineColor = underlineColor;
+ this.borderStyle = borderStyle;
+ this.borderColor = borderColor;
+ }
+
+ public URI getFont() {
+ return font;
+ }
+
+ public URI getBackgoundColor() {
+ return backgroundColor;
+ }
+
+ public URI getForegroundColor() {
+ return foregroundColor;
+ }
+
+ public boolean isStrikedout() {
+ return isStrikedout;
+ }
+
+ public URI getStrikeoutColor() {
+ return strikeoutColor;
+ }
+
+ public UnderLineStyle getUnderlineStyle() {
+ return underlineStyle;
+ }
+
+ public URI getUnderlineColor() {
+ return underlineColor;
+ }
+
+ public BorderStyle getBorderStyle() {
+ return borderStyle;
+ }
+
+ public URI getBorderColor() {
+ return borderColor;
+ }
+
+ public static enum UnderLineStyle {
+ NONE, SINGLE, DOUBLE, SQUIGGLE, ERROR, LINK;
+ }
+
+ public static enum BorderStyle {
+ NONE, SOLID, DOT, DASH;
+ }
+
+ public static StyleBuilder builder() {
+ return new StyleBuilder();
+ }
+
+ public static final class StyleBuilder {
+ private static final URI BLACK = URI.createURI("color://rgb/0/0/0"); //$NON-NLS-1$
+
+ private URI font;
+
+ private URI backgroundColor;
+
+ private URI foregroundColor;
+
+ private boolean isStrikedout;
+
+ private URI strikeoutColor;
+
+ private UnderLineStyle underlineStyle = UnderLineStyle.NONE;
+
+ private URI underlineColor;
+
+ private BorderStyle borderStyle = BorderStyle.NONE;
+
+ private URI borderColor;
+
+ /**
+ * @param font
+ * the font to set
+ * @return
+ */
+ public StyleBuilder setFont(URI font) {
+ this.font = font;
+ return this;
+ }
+
+ /**
+ * @param backgroundColor
+ * the backgroundColor to set
+ * @return
+ */
+ public StyleBuilder setBackgroundColor(URI backgroundColor) {
+ this.backgroundColor = backgroundColor;
+ return this;
+ }
+
+ /**
+ * @param foregroundColor
+ * the forregroundColor to set
+ * @return
+ */
+ public StyleBuilder setForegroundColor(URI foregroundColor) {
+ this.foregroundColor = foregroundColor;
+ return this;
+ }
+
+ /**
+ * @param isStrikedout
+ * the isStrikedout to set
+ * @return
+ */
+ public StyleBuilder setStrikedout(boolean isStrikedout) {
+ this.isStrikedout = isStrikedout;
+ if (strikeoutColor == null) {
+ strikeoutColor = BLACK;
+ }
+ return this;
+ }
+
+ /**
+ * @param strikeoutColor
+ * the strikeoutColor to set
+ * @return
+ */
+ public StyleBuilder setStrikeoutColor(URI strikeoutColor) {
+ this.strikeoutColor = strikeoutColor;
+ isStrikedout = true;
+ return this;
+ }
+
+ /**
+ * @param borderColor
+ * the borderColor to set
+ * @return
+ */
+ public StyleBuilder setBorderColor(URI borderColor) {
+ this.borderColor = borderColor;
+ if (borderStyle == BorderStyle.NONE) {
+ borderStyle = BorderStyle.SOLID;
+ }
+ return this;
+ }
+
+ /**
+ * @param borderStyle
+ * the borderStyle to set
+ * @return
+ */
+ public StyleBuilder setBorderStyle(BorderStyle borderStyle) {
+ this.borderStyle = borderStyle;
+ if (borderColor == null) {
+ borderColor = BLACK;
+ }
+ return this;
+ }
+
+ /**
+ * @param underlineColor
+ * the underlineColor to set
+ * @return
+ */
+ public StyleBuilder setUnderlineColor(URI underlineColor) {
+ this.underlineColor = underlineColor;
+ if (underlineStyle == UnderLineStyle.NONE) {
+ underlineStyle = UnderLineStyle.SINGLE;
+ }
+ return this;
+ }
+
+ /**
+ * @param underlineStyle
+ * the underlineStyle to set
+ * @return
+ */
+ public StyleBuilder setUnderlineStyle(UnderLineStyle underlineStyle) {
+ this.underlineStyle = underlineStyle;
+ if (underlineStyle == null) {
+ underlineColor = BLACK;
+ }
+ return this;
+ }
+
+ public Style build() {
+ return new Style(font, backgroundColor, foregroundColor, isStrikedout, strikeoutColor,
+ underlineStyle, underlineColor, borderStyle, borderColor);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
index ccc349714..27b64a9f6 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.ide.ui/META-INF/MANIFEST.MF
@@ -1,44 +1,43 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.emf.compare.ide.ui;singleton:=true
-Bundle-Version: 2.1.0.qualifier
-Bundle-Activator: org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin
-Bundle-Vendor: %providerName
-Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.core.resources;bundle-version="3.5.0",
- org.eclipse.compare;bundle-version="3.5.0",
- org.eclipse.emf.edit.ui;bundle-version="2.5.0",
- org.eclipse.emf.compare.edit;bundle-version="2.0.1",
- org.eclipse.emf.compare.ide;bundle-version="2.0.1",
- org.eclipse.jface.text;bundle-version="3.5.0",
- org.eclipse.emf.compare.rcp.ui;bundle-version="2.0.1",
- org.eclipse.core.filesystem,
- org.eclipse.team.core;bundle-version="3.5.0",
- org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
- org.eclipse.team.ui;bundle-version="3.5.0"
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Bundle-ActivationPolicy: lazy
-Bundle-Localization: plugin
-Export-Package: org.eclipse.emf.compare.ide.ui.internal;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.filter;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.group;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.actions.save;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.editor;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.handler;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.internal.util;x-internal:=true,
- org.eclipse.emf.compare.ide.ui.logical
-Import-Package: com.google.common.annotations;version="[10.0.0,11.0.0)",
- com.google.common.base;version="[10.0.0,11.0.0)",
- com.google.common.cache;version="[10.0.0,11.0.0)",
- com.google.common.collect;version="[10.0.0,11.0.0)",
- com.google.common.io;version="[10.0.0,11.0.0)"
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.emf.compare.ide.ui;singleton:=true
+Bundle-Version: 3.0.0.qualifier
+Bundle-Activator: org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources;bundle-version="3.5.0",
+ org.eclipse.compare;bundle-version="3.5.0",
+ org.eclipse.emf.edit.ui;bundle-version="2.5.0",
+ org.eclipse.emf.compare.edit;bundle-version="2.0.1",
+ org.eclipse.emf.compare.ide;bundle-version="2.0.1",
+ org.eclipse.jface.text;bundle-version="3.5.0",
+ org.eclipse.emf.compare.rcp.ui;bundle-version="2.0.1",
+ org.eclipse.core.filesystem,
+ org.eclipse.team.core;bundle-version="3.5.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.team.ui;bundle-version="3.5.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.emf.compare.ide.ui.internal;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.actions.save;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.editor;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.handler;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.internal.util;x-internal:=true,
+ org.eclipse.emf.compare.ide.ui.logical
+Import-Package: com.google.common.annotations;version="[10.0.0,11.0.0)",
+ com.google.common.base;version="[10.0.0,11.0.0)",
+ com.google.common.cache;version="[10.0.0,11.0.0)",
+ com.google.common.collect;version="[10.0.0,11.0.0)",
+ com.google.common.eventbus;version="[10.0.0,11.0.0)",
+ com.google.common.io;version="[10.0.0,11.0.0)"
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/merged_ov.gif b/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/merged_ov.gif
deleted file mode 100644
index 874a6dcea..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/ovr16/merged_ov.gif
+++ /dev/null
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
index 64d94df78..6b23253c8 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.ide.ui/plugin.xml
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.4"?>
-
-<!--
- Copyright (c) 2012 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
--->
-
-<plugin>
- <extension-point id="accessor_factory" name="Accessor Factory" schema="schema/accessor_factory.exsd"/>
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+
+<!--
+ 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
+-->
+
+<plugin>
+ <extension-point id="accessor_factory" name="Accessor Factory" schema="schema/accessor_factory.exsd"/>
<extension
point="org.eclipse.compare.structureMergeViewers">
<viewer
@@ -38,218 +38,187 @@
<contentTypeBinding
contentMergeViewerId="org.eclipse.emf.compare.ide.ui.internal.EObjectContentMergeViewer"
contentTypeId="org.eclipse.emf.ecore.xmi">
- </contentTypeBinding>
- <viewer
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
- extensions="emfcompare_diff"
- id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EObjectListContentMergeViewer"
- label="EMFCompare Content Merge Viewer">
- </viewer>
- <viewer
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextMergeViewerCreator"
- extensions="eText"
- id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextContentMergeViewer"
- label="EMFCompare Text Merge Viewer">
+ </contentTypeBinding>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
+ extensions="emfcompare_diff"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EObjectListContentMergeViewer"
+ label="EMFCompare Content Merge Viewer">
+ </viewer>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextMergeViewerCreator"
+ extensions="eText"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareTextContentMergeViewer"
+ label="EMFCompare Text Merge Viewer">
+ </viewer>
+ <viewer
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.table.TableContentMergeViewerCreator"
+ extensions="resource_contents"
+ id="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text.EMFCompareResourceContentsContentMergeViewer"
+ label="EMFCompare Resource Contents Merge Viewer">
</viewer>
- </extension>
- <extension
- point="org.eclipse.emf.edit.itemProviderAdapterFactories">
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.CompareNodeAdapterFactory"
- supportedTypes=
- "org.eclipse.compare.structuremergeviewer.IDiffElement
- org.eclipse.compare.structuremergeviewer.IDiffContainer
- org.eclipse.compare.structuremergeviewer.ITypedElement
- org.eclipse.compare.structuremergeviewer.ICompareInput"
- uri="http://www.eclipse.org/emf/compare">
- </factory>
- </extension>
- <extension
- id="org.eclipse.emf.compare.model.provider"
- name="EMF Compare"
- point="org.eclipse.core.resources.modelProviders">
- <modelProvider
- class="org.eclipse.emf.compare.ide.ui.logical.EMFModelProvider">
- </modelProvider>
- <enablement>
- <and>
- <adapt
- type="org.eclipse.core.resources.IFile">
- </adapt>
- <or>
- <test
- args="kindOf"
- property="org.eclipse.core.resources.contentTypeId"
- value="org.eclipse.emf.ecore">
- </test>
- <test
- args="kindOf"
- property="org.eclipse.core.resources.contentTypeId"
- value="org.eclipse.emf.ecore.xmi">
- </test>
- </or>
- </and>
- </enablement>
- </extension>
- <extension
- point="org.eclipse.core.runtime.adapters">
- <factory
- adaptableType="org.eclipse.emf.compare.ide.ui.logical.EMFModelProvider"
- class="org.eclipse.emf.compare.ide.ui.logical.EMFCompareAdapterFactory">
- <adapter
- type="org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter">
- </adapter>
- </factory>
- </extension>
+ </extension>
+ <extension
+ point="org.eclipse.emf.edit.itemProviderAdapterFactories">
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.CompareNodeAdapterFactory"
+ supportedTypes="org.eclipse.compare.structuremergeviewer.ICompareInput"
+ uri="http://www.eclipse.org/emf/compare">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.emf.compare.ide.ui.accessor_factory">
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEEObjectAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEManyStructuralFeatureAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDESingleStructuralFeatureAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEStringAttributeChangeAccessorFactory"
+ ranking="10">
+ </factory>
+ <factory
+ class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEResourceContentsAccessorFactory"
+ ranking="10">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ categoryId="org.eclipse.compare.ui.category.compare"
+ id="org.eclipse.emf.compare.ide.ui.compareInDialog"
+ name="Compare in Dialog">
+ </command>
+ <command
+ categoryId="org.eclipse.compare.ui.category.compare"
+ id="org.eclipse.emf.compare.ide.ui.compareInEditor"
+ name="Compare in new Editor">
+ </command>
+ <command
+ id="org.eclipse.team.ui.compareWithEachOther"
+ name="Each Other">
+ </command>
+ </extension>
+ <extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
+ commandId="org.eclipse.emf.compare.ide.ui.compareInDialog">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInNewEditor"
+ commandId="org.eclipse.emf.compare.ide.ui.compareInEditor">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ <handler
+ class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
+ commandId="org.eclipse.team.ui.compareWithEachOther">
+ <activeWhen>
+ <with
+ variable="selection">
+ <and>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.emf.ecore.EObject">
+ </instanceof>
+ </iterate>
+ <or>
+ <count
+ value="2">
+ </count>
+ <count
+ value="3">
+ </count>
+ </or>
+ </and>
+ </with>
+ </activeWhen>
+ </handler>
+ </extension>
<extension
- point="org.eclipse.emf.compare.ide.ui.accessor_factory">
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEEObjectAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEManyStructuralFeatureAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDESingleStructuralFeatureAccessorFactory"
- ranking="10">
- </factory>
- <factory
- class="org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.factory.IDEStringAttributeChangeAccessorFactory"
- ranking="10">
- </factory>
- </extension>
- <extension
- point="org.eclipse.ui.commands">
- <command
- categoryId="org.eclipse.compare.ui.category.compare"
- id="org.eclipse.emf.compare.ide.ui.compareInDialog"
- name="Compare in Dialog">
- </command>
- <command
- categoryId="org.eclipse.compare.ui.category.compare"
- id="org.eclipse.emf.compare.ide.ui.compareInEditor"
- name="Compare in new Editor">
- </command>
- <command
- id="org.eclipse.team.ui.compareWithEachOther"
- name="Each Other">
- </command>
- </extension>
- <extension
- point="org.eclipse.ui.handlers">
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
- commandId="org.eclipse.emf.compare.ide.ui.compareInDialog">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInNewEditor"
- commandId="org.eclipse.emf.compare.ide.ui.compareInEditor">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- <handler
- class="org.eclipse.emf.compare.ide.ui.internal.handler.CompareInDialog"
- commandId="org.eclipse.team.ui.compareWithEachOther">
- <activeWhen>
- <with
- variable="selection">
- <and>
- <iterate
- ifEmpty="false"
- operator="and">
- <instanceof
- value="org.eclipse.emf.ecore.EObject">
- </instanceof>
- </iterate>
- <or>
- <count
- value="2">
- </count>
- <count
- value="3">
- </count>
- </or>
- </and>
- </with>
- </activeWhen>
- </handler>
- </extension>
- <extension
- point="org.eclipse.ui.menus">
- <menuContribution
- allPopups="true"
- locationURI="popup:compareWithMenu?after=compareWithGroup">
- <command
- commandId="org.eclipse.emf.compare.ide.ui.compareInDialog"
- label="Each Other &lt;EObject&gt; (in Dialog)"
- style="push">
- <visibleWhen
- checkEnabled="true">
- </visibleWhen>
- </command>
- <command
- commandId="org.eclipse.emf.compare.ide.ui.compareInEditor"
- label="Each Other &lt;EObject&gt; (in Editor)"
- style="push">
- <visibleWhen
- checkEnabled="true">
- </visibleWhen>
- </command>
- </menuContribution>
- <menuContribution
- allPopups="false"
- locationURI="popup:org.eclipse.ui.popup.any">
- <menu
- id="compareWithMenu"
- label="Compare With">
- <separator
- name="compareWithGroup">
- </separator>
- </menu>
- </menuContribution>
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="true"
+ locationURI="popup:compareWithMenu?after=compareWithGroup">
+ <command
+ commandId="org.eclipse.emf.compare.ide.ui.compareInDialog"
+ label="Each Other &lt;EObject&gt; (in Dialog)"
+ style="push">
+ <visibleWhen
+ checkEnabled="true">
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.emf.compare.ide.ui.compareInEditor"
+ label="Each Other &lt;EObject&gt; (in Editor)"
+ style="push">
+ <visibleWhen
+ checkEnabled="true">
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ allPopups="false"
+ locationURI="popup:org.eclipse.ui.popup.any">
+ <menu
+ id="compareWithMenu"
+ label="Compare With">
+ <separator
+ name="compareWithGroup">
+ </separator>
+ </menu>
+ </menuContribution>
</extension>
-</plugin>
+</plugin>
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/pom.xml b/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
index c2b30b70c..521a2e87f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
+++ b/plugins/org.eclipse.emf.compare.ide.ui/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>org.eclipse.emf.compare</groupId>
<artifactId>org.eclipse.emf.compare.ide.ui</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
index c18aa4040..b6afffffd 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareConstants.java
@@ -1,48 +1,52 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public final class EMFCompareConstants {
-
- private EMFCompareConstants() {
- // prevents instantiation
- }
-
- public static final int COMPARE_IMAGE_WIDTH = 22;
-
- public static final String INCOMING_COLOR = "INCOMING_COLOR"; //$NON-NLS-1$
-
- public static final String OUTGOING_COLOR = "OUTGOING_COLOR"; //$NON-NLS-1$
-
- public static final String CONFLICTING_COLOR = "CONFLICTING_COLOR"; //$NON-NLS-1$
-
- public static final String RESOLVED_COLOR = "RESOLVED_COLOR"; //$NON-NLS-1$
-
- // CompareConfiguration
-
- public static final String COMPARE_RESULT = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARE.RESULT"; //$NON-NLS-1$
-
- public static final String COMPARATOR = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARATOR"; //$NON-NLS-1$
-
- public static final String EDITING_DOMAIN = EMFCompareIDEUIPlugin.PLUGIN_ID + ".EDITING_DOMAIN"; //$NON-NLS-1$
-
- // 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$
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.ide.ui.internal;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public final class EMFCompareConstants {
+
+ private EMFCompareConstants() {
+ // prevents instantiation
+ }
+
+ public static final int COMPARE_IMAGE_WIDTH = 22;
+
+ public static final String INCOMING_COLOR = "INCOMING_COLOR"; //$NON-NLS-1$
+
+ public static final String OUTGOING_COLOR = "OUTGOING_COLOR"; //$NON-NLS-1$
+
+ public static final String CONFLICTING_COLOR = "CONFLICTING_COLOR"; //$NON-NLS-1$
+
+ public static final String RESOLVED_COLOR = "RESOLVED_COLOR"; //$NON-NLS-1$
+
+ // CompareConfiguration
+
+ public static final String COMPARE_RESULT = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARE.RESULT"; //$NON-NLS-1$
+
+ public static final String COMPARATOR = EMFCompareIDEUIPlugin.PLUGIN_ID + ".COMPARATOR"; //$NON-NLS-1$
+
+ public static final String EDITING_DOMAIN = EMFCompareIDEUIPlugin.PLUGIN_ID + ".EDITING_DOMAIN"; //$NON-NLS-1$
+
+ public static final String SELECTED_FILTERS = EMFCompareIDEUIPlugin.PLUGIN_ID + ".SELECTED_FILTERS"; //$NON-NLS-1$
+
+ public static final String SELECTED_GROUP = EMFCompareIDEUIPlugin.PLUGIN_ID + ".SELECTED_GROUP"; //$NON-NLS-1$
+
+ // 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$
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
index f2ef1513e..39ff1c246 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/EMFCompareIDEUIPlugin.java
@@ -67,7 +67,7 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
registry = new IAccessorFactory.RegistryImpl();
listener = new AccessorFactoryExtensionRegistryListener(PLUGIN_ID, ACCESSOR_FACTORY_PPID);
- extensionRegistry.addListener(listener, PLUGIN_ID + "." + ACCESSOR_FACTORY_PPID);
+ extensionRegistry.addListener(listener, PLUGIN_ID + "." + ACCESSOR_FACTORY_PPID); //$NON-NLS-1$
listener.readRegistry(extensionRegistry);
}
@@ -199,8 +199,8 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
try {
Integer.parseInt(rankingStr);
} catch (NumberFormatException nfe) {
- logError(element, "Attribute '" + ATT_RANKING
- + "' is malformed, should be an integer.");
+ logError(element, "Attribute '" + ATT_RANKING //$NON-NLS-1$
+ + "' is malformed, should be an integer."); //$NON-NLS-1$
}
logMissingAttribute(element, ATT_RANKING);
} else {
@@ -212,8 +212,8 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
factory.setRanking(Integer.parseInt(element.getAttribute(ATT_RANKING)));
IAccessorFactory previous = registry.add(factory);
if (previous != null) {
- log(IStatus.WARNING, "The factory '" + factory.getClass().getName()
- + "' is registered twice.");
+ log(IStatus.WARNING, "The factory '" + factory.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
}
} catch (CoreException e) {
logError(element, e.getMessage());
@@ -240,4 +240,5 @@ public class EMFCompareIDEUIPlugin extends AbstractUIPlugin {
log(IStatus.ERROR, string);
}
}
+
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java
deleted file mode 100644
index e932180c9..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterAction.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.filter;
-
-import com.google.common.base.Predicate;
-
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-
-/**
- * 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.
- * <p>
- * 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 <b>not</b> meet the
- * selected filters' criteria in order to be displayed).
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class FilterAction extends Action {
- /** The Predicate activate through this action. */
- private Predicate<? super EObject> predicate;
-
- /** The Filter that will be modified by the action. */
- private DifferenceFilter differenceFilter;
-
- /**
- * The "default" constructor for this action.
- * {@link #fromDiffPredicate(String, Predicate, DifferenceFilter)} can be used instead in order to create
- * an action which filter only aims at Diff elements.
- *
- * @param text
- * Will be used as the action's tooltip.
- * @param predicate
- * The predicate that this action will provide to the viewer's filter.
- * @param differenceFilter
- * The filter that this action will need to update.
- */
- public FilterAction(String text, Predicate<? super EObject> predicate, DifferenceFilter differenceFilter) {
- super(text, IAction.AS_CHECK_BOX);
- this.predicate = predicate;
- this.differenceFilter = differenceFilter;
- }
-
- /**
- * Constructs a filtering action that only aims at filtering out Diff elements from the view, ignoring all
- * other kind of objects.
- *
- * @param text
- * The tooltip of the new action.
- * @param diffPredicate
- * The predicate that this action will provide to the viewer's filter.
- * @param filter
- * The filter that this action will need to update.
- * @return The newly created action.
- */
- public static FilterAction fromDiffPredicate(String text, final Predicate<? super Diff> diffPredicate,
- DifferenceFilter filter) {
- final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
- public boolean apply(EObject input) {
- return input instanceof Diff && diffPredicate.apply((Diff)input);
- }
- };
- return new FilterAction(text, actualPredicate, filter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- if (isChecked()) {
- differenceFilter.addPredicate(predicate);
- } else {
- differenceFilter.removePredicate(predicate);
- }
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java
deleted file mode 100644
index 1888ee0d7..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/FilterActionMenu.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.filter;
-
-import static com.google.common.base.Predicates.instanceOf;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
-
-import org.eclipse.emf.compare.DifferenceKind;
-import org.eclipse.emf.compare.MatchResource;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class FilterActionMenu extends Action implements IMenuCreator {
- /** The Filter that will be modified by this menu's actions. */
- private final DifferenceFilter differenceFilter;
-
- /** Menu Manager that will contain our menu. */
- private MenuManager menuManager;
-
- /**
- * Constructs our filtering menu.
- *
- * @param differenceFilter
- * The filter for which we'll create actions.
- */
- public FilterActionMenu(DifferenceFilter differenceFilter) {
- super("", IAction.AS_DROP_DOWN_MENU);
- this.menuManager = new MenuManager();
- this.differenceFilter = differenceFilter;
- setMenuCreator(this);
- setToolTipText("Filters");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/filter.gif")); //$NON-NLS-1$
- createActions(menuManager);
- }
-
- /**
- * Create all of our filtering actions into the given menu.
- *
- * @param menu
- * The menu in which we are to create filter actions.
- */
- public void createActions(MenuManager menu) {
- // TODO make this extensible and use the extension point. Hardcoded for now.
- // The four "difference of kind" predicate
- menu.add(FilterAction.fromDiffPredicate("Changed Elements", ofKind(DifferenceKind.CHANGE),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Added Elements", ofKind(DifferenceKind.ADD),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Removed Elements", ofKind(DifferenceKind.DELETE),
- differenceFilter));
- menu.add(FilterAction.fromDiffPredicate("Moved Elements", ofKind(DifferenceKind.MOVE),
- differenceFilter));
- // And one to remove the ResourceMatch from the view.
- final FilterAction matchResourceFilter = new FilterAction("Resource Mappings",
- instanceOf(MatchResource.class), differenceFilter);
- // Make it checked by default, we need to run it once for that
- matchResourceFilter.setChecked(true);
- matchResourceFilter.run();
- menu.add(matchResourceFilter);
- }
-
- /**
- * {@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 menuManager.getMenu();
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java
deleted file mode 100644
index 94465b0df..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroupProvider.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.Comparison;
-
-/**
- * Instances of this class will be used by EMF Compare in order to provide difference grouping facilities to
- * the structural differences view.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public interface DifferenceGroupProvider {
- /**
- * 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.
- */
- Iterable<? extends DifferenceGroup> getGroups(Comparison comparison);
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java
deleted file mode 100644
index f6330107c..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupActionMenu.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class GroupActionMenu extends Action implements IMenuCreator {
- /** The difference grouper that will be affected by this menu's actions. */
- private final DifferenceGrouper differenceGrouper;
-
- /** Menu Manager that will contain our menu. */
- private MenuManager menuManager;
-
- /**
- * Constructs our grouping menu.
- *
- * @param tree
- * The tree viewer which will be used to display our groups.
- * @param comparison
- * The comparison which differences are to be split into groups.
- */
- public GroupActionMenu(DifferenceGrouper differenceGrouper) {
- super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
- this.menuManager = new MenuManager();
- this.differenceGrouper = differenceGrouper;
- setToolTipText("Groups");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/group.gif")); //$NON-NLS-1$
- setMenuCreator(this);
- createActions(menuManager);
- }
-
- /**
- * Create the grouping action in the given menu.
- *
- * @param menu
- */
- public void createActions(MenuManager menu) {
- // TODO make this extensible. we need to allow clients to add new groups to this list.
- final IAction defaultAction = new GroupAction("Default", differenceGrouper, null);
- defaultAction.setChecked(true);
- menu.add(defaultAction);
- menu.add(new GroupAction("By Kind", differenceGrouper, new KindGroupProvider()));
- menu.add(new GroupAction("By Metaclass", differenceGrouper, new MetamodelGroupProvider()));
- }
-
- /**
- * {@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 menuManager.getMenu();
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java
deleted file mode 100644
index 1faa3077a..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/KindGroupProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceKind;
-
-/**
- * This implementation of a {@link DifferenceGroupProvider} will be used to group the differences by their
- * {@link DifferenceKind kind} : additions, deletions, changes and moves.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class KindGroupProvider implements DifferenceGroupProvider {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
- */
- public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
- final List<Diff> diffs = comparison.getDifferences();
-
- final DifferenceGroup additions = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.ADD), "Additions");
- final DifferenceGroup deletions = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.DELETE), "Deletions");
- final DifferenceGroup changes = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.CHANGE), "Changes");
- final DifferenceGroup moves = new DefaultDifferenceGroup(comparison, diffs,
- ofKind(DifferenceKind.MOVE), "Moves");
-
- return ImmutableList.of(additions, deletions, changes, moves);
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
index 836e1db18..53a71ade3 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/save/SaveComparisonModelAction.java
@@ -1,98 +1,98 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.save;
-
-import static com.google.common.collect.Maps.newHashMap;
-
-import com.google.common.collect.ImmutableList;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
-import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class SaveComparisonModelAction extends Action {
-
- /**
- *
- */
- private static final ImmutableList<String> DIALOG_BUTTON_LABELS = ImmutableList.of("Replace", "Cancel");
-
- private CompareConfiguration configuration;
-
- /**
- * @param parent
- */
- public SaveComparisonModelAction(CompareConfiguration configuration) {
- this.configuration = configuration;
- setToolTipText("Save Comparison Model");
- setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
- "icons/full/toolb16/saveas_edit.gif")); //$NON-NLS-1$
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- Shell parent = configuration.getContainer().getWorkbenchPart().getSite().getShell();
-
- FileDialog fileDialog = new FileDialog(parent, SWT.SAVE);
- File file = new File(fileDialog.open());
- if (file.exists()) {
- MessageDialog messageDialog = new MessageDialog(parent, "File already exists", null, "File \""
- + file.toString() + "\" already exists. Do you want to replace the existing one?",
- MessageDialog.WARNING, DIALOG_BUTTON_LABELS.toArray(new String[0]), 1);
- int open = messageDialog.open();
- if (open == DIALOG_BUTTON_LABELS.indexOf("Replace")) {
- saveComparison(file);
- } // else do nothing
- } else {
- saveComparison(file);
- }
-
- super.run();
- }
-
- private void saveComparison(File file) {
- Comparison comparison = (Comparison)configuration.getProperty(EMFCompareConstants.COMPARE_RESULT);
- Resource resource = new XMIResourceImpl(URI.createFileURI(file.getAbsolutePath()));
- Copier copier = new Copier(false);
- EObject comparisonCopy = copier.copy(comparison);
- copier.copyReferences();
-
- resource.getContents().add(comparisonCopy);
- try {
- resource.save(newHashMap());
- } catch (IOException e) {
- EMFCompareIDEUIPlugin.getDefault().log(e);
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.ide.ui.internal.actions.save;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+import com.google.common.collect.ImmutableList;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class SaveComparisonModelAction extends Action {
+
+ /**
+ *
+ */
+ private static final ImmutableList<String> DIALOG_BUTTON_LABELS = ImmutableList.of("Replace", "Cancel");
+
+ private CompareConfiguration configuration;
+
+ /**
+ * @param parent
+ */
+ public SaveComparisonModelAction(CompareConfiguration configuration) {
+ this.configuration = configuration;
+ setToolTipText("Save Comparison Model");
+ setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EMFCompareIDEUIPlugin.PLUGIN_ID,
+ "icons/full/toolb16/saveas_edit.gif")); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ Shell parent = configuration.getContainer().getWorkbenchPart().getSite().getShell();
+
+ FileDialog fileDialog = new FileDialog(parent, SWT.SAVE);
+ File file = new File(fileDialog.open());
+ if (file.exists()) {
+ MessageDialog messageDialog = new MessageDialog(parent, "File already exists", null, "File \""
+ + file.toString() + "\" already exists. Do you want to replace the existing one?",
+ MessageDialog.WARNING, DIALOG_BUTTON_LABELS.toArray(new String[0]), 1);
+ int open = messageDialog.open();
+ if (open == DIALOG_BUTTON_LABELS.indexOf("Replace")) {
+ saveComparison(file);
+ } // else do nothing
+ } else {
+ saveComparison(file);
+ }
+
+ super.run();
+ }
+
+ private void saveComparison(File file) {
+ Comparison comparison = (Comparison)configuration.getProperty(EMFCompareConstants.COMPARE_RESULT);
+ Resource resource = new XMIResourceImpl(URI.createFileURI(file.getAbsolutePath()));
+ Copier copier = new Copier(false);
+ EObject comparisonCopy = copier.copy(comparison);
+ copier.copyReferences();
+
+ resource.getContents().add(comparisonCopy);
+ try {
+ resource.save(newHashMap());
+ } catch (IOException e) {
+ EMFCompareIDEUIPlugin.getDefault().log(e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
index 20fd69b93..91dfb66cb 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
@@ -1,558 +1,559 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer;
-
-import java.util.EventObject;
-import java.util.Iterator;
-import java.util.ResourceBundle;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.CompareNavigator;
-import org.eclipse.compare.ICompareNavigator;
-import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
-import org.eclipse.compare.internal.CompareHandlerService;
-import org.eclipse.compare.internal.Utilities;
-import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.common.command.CommandStackListener;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.domain.ICompareEditingDomain;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.EMFCompareColor;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider;
-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.IMergeViewerItem;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.ActionContributionItem;
-import org.eclipse.jface.action.ToolBarManager;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.ui.actions.ActionFactory;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer implements ISelectionChangedListener, ICompareColorProvider, IAdaptable {
-
- private static final String HANDLER_SERVICE = "fHandlerService";
-
- protected static final int HORIZONTAL = 1;
-
- protected static final int VERTICAL = 2;
-
- protected static final double HSPLIT = 0.5;
-
- protected static final double VSPLIT = 0.3;
-
- /**
- * Width of center bar
- */
- protected static final int CENTER_WIDTH = 34;
-
- private IMergeViewer fAncestor;
-
- private IMergeViewer fLeft;
-
- private IMergeViewer fRight;
-
- private ActionContributionItem fCopyDiffLeftToRightItem;
-
- private ActionContributionItem fCopyDiffRightToLeftItem;
-
- private final AtomicBoolean fSyncingSelections = new AtomicBoolean(false);
-
- private EMFCompareColor fColors;
-
- private final DynamicObject fDynamicObject;
-
- private CommandStackListener fCommandStackListener;
-
- private UndoAction undoAction;
-
- private RedoAction redoAction;
-
- /**
- * @param style
- * @param bundle
- * @param cc
- */
- protected EMFCompareContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
- super(style, bundle, cc);
- fDynamicObject = new DynamicObject(this);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider#getCompareColor()
- */
- public ICompareColor getCompareColor() {
- return fColors;
- }
-
- /**
- * @return the fEditingDomain
- */
- protected final ICompareEditingDomain getEditingDomain() {
- return (ICompareEditingDomain)getCompareConfiguration().getProperty(
- EMFCompareConstants.EDITING_DOMAIN);
- }
-
- /**
- * @return the fComparison
- */
- protected final Comparison getComparison() {
- return (Comparison)getCompareConfiguration().getProperty(EMFCompareConstants.COMPARE_RESULT);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Overriden to enhance visibility.
- * </p>
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#isThreeWay()
- */
- @Override
- public boolean isThreeWay() {
- // enhances visibility
- return super.isThreeWay();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateContent(java.lang.Object,
- * java.lang.Object, java.lang.Object)
- */
- @Override
- protected void updateContent(Object ancestor, Object left, Object right) {
- undoAction.setEditingDomain(getEditingDomain());
- redoAction.setEditingDomain(getEditingDomain());
-
- if (getEditingDomain() != null && fCommandStackListener == null) {
- fCommandStackListener = installCommandStackListener(undoAction, redoAction);
- }
-
- fAncestor.setInput(ancestor);
- fLeft.setInput(left);
- fRight.setInput(right);
- // must update selection after the three viewers input has been set
- // to avoid some NPE/AssertionError (they are calling each other on selectionChanged event to
- // synchronize their selection)
-
- IMergeViewerItem leftInitialItem = null;
- if (left instanceof IStructuralFeatureAccessor) {
- leftInitialItem = ((IStructuralFeatureAccessor)left).getInitialItem();
- }
-
- ISelection leftSelection = createSelectionOrEmpty(leftInitialItem);
- fLeft.setSelection(leftSelection, true); // others will synchronize on this one :)
-
- getCenterControl().redraw();
- }
-
- private ISelection createSelectionOrEmpty(final Object o) {
- final ISelection selection;
- if (o != null) {
- selection = new StructuredSelection(o);
- } else {
- selection = StructuredSelection.EMPTY;
- }
- return selection;
- }
-
- /**
- * Inhibits this method to avoid asking to save on each input change!!
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#doSave(java.lang.Object,
- * java.lang.Object)
- */
- @Override
- protected boolean doSave(Object newInput, Object oldInput) {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createControls(org.eclipse.swt.widgets.Composite)
- */
- @Override
- protected void createControls(Composite composite) {
- fAncestor = createMergeViewer(composite, MergeViewerSide.ANCESTOR);
- fAncestor.addSelectionChangedListener(this);
-
- fLeft = createMergeViewer(composite, MergeViewerSide.LEFT);
- fLeft.addSelectionChangedListener(this);
-
- fRight = createMergeViewer(composite, MergeViewerSide.RIGHT);
- fRight.addSelectionChangedListener(this);
-
- fColors = new EMFCompareColor(this, null, getCompareConfiguration());
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createToolItems(org.eclipse.jface.action.ToolBarManager)
- */
- @Override
- protected void createToolItems(ToolBarManager toolBarManager) {
- // Copy actions
- CompareConfiguration cc = getCompareConfiguration();
- if (cc.isRightEditable()) {
- Action copyLeftToRight = new Action() {
- @Override
- public void run() {
- copyDiff(true);
- // Select next diff
- navigate(true);
- }
- };
- Utilities.initAction(copyLeftToRight, getResourceBundle(), "action.CopyDiffLeftToRight."); //$NON-NLS-1$
- copyLeftToRight.setEnabled(false);
- fCopyDiffLeftToRightItem = new ActionContributionItem(copyLeftToRight);
- fCopyDiffLeftToRightItem.setVisible(true);
- toolBarManager.appendToGroup("merge", fCopyDiffLeftToRightItem); //$NON-NLS-1$
- getHandlerService().registerAction(copyLeftToRight, "org.eclipse.compare.copyLeftToRight"); //$NON-NLS-1$
- }
-
- if (cc.isLeftEditable()) {
- Action copyRightToLeft = new Action() {
- @Override
- public void run() {
- copyDiff(false);
- // Select next diff
- navigate(true);
- }
- };
- Utilities.initAction(copyRightToLeft, getResourceBundle(), "action.CopyDiffRightToLeft."); //$NON-NLS-1$
- copyRightToLeft.setEnabled(false);
- fCopyDiffRightToLeftItem = new ActionContributionItem(copyRightToLeft);
- fCopyDiffRightToLeftItem.setVisible(true);
- toolBarManager.appendToGroup("merge", fCopyDiffRightToLeftItem); //$NON-NLS-1$
- getHandlerService().registerAction(copyRightToLeft, "org.eclipse.compare.copyRightToLeft"); //$NON-NLS-1$
- }
-
- // Navigation
- final Action nextDiff = new Action() {
- @Override
- public void run() {
- navigate(true);
- }
- };
- Utilities.initAction(nextDiff, getResourceBundle(), "action.NextDiff.");
- ActionContributionItem contributionNextDiff = new ActionContributionItem(nextDiff);
- contributionNextDiff.setVisible(true);
- toolBarManager.appendToGroup("navigation", contributionNextDiff);
-
- final Action previousDiff = new Action() {
- @Override
- public void run() {
- navigate(false);
- }
- };
- Utilities.initAction(previousDiff, getResourceBundle(), "action.PrevDiff.");
- ActionContributionItem contributionPreviousDiff = new ActionContributionItem(previousDiff);
- contributionPreviousDiff.setVisible(true);
- toolBarManager.appendToGroup("navigation", contributionPreviousDiff);
-
- undoAction = new UndoAction(getEditingDomain());
- redoAction = new RedoAction(getEditingDomain());
-
- if (getEditingDomain() != null && fCommandStackListener == null) {
- fCommandStackListener = installCommandStackListener(undoAction, redoAction);
- }
-
- getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
- getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
- }
-
- private CommandStackListener installCommandStackListener(final UndoAction undoAction,
- final RedoAction redoAction) {
- CommandStackListener commandStackListener = new CommandStackListener() {
- public void commandStackChanged(EventObject event) {
- undoAction.update();
- redoAction.update();
- setLeftDirty(getEditingDomain().getCommandStack().isLeftSaveNeeded());
- setRightDirty(getEditingDomain().getCommandStack().isRightSaveNeeded());
- refresh();
- }
- };
- getEditingDomain().getCommandStack().addCommandStackListener(commandStackListener);
- return commandStackListener;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#copy(boolean)
- */
- @Override
- protected void copy(boolean leftToRight) {
- EList<Diff> differences = getComparison().getDifferences();
-
- final Command copyCommand = getEditingDomain().createCopyAllNonConflictingCommand(differences,
- leftToRight);
-
- getEditingDomain().getCommandStack().execute(copyCommand);
-
- // if (leftToRight) {
- // setRightDirty(true);
- // } else {
- // setLeftDirty(true);
- // }
- refresh();
- }
-
- /**
- * Called by the framework to navigate to the next (or previous) difference. This will open the content
- * viewer for the next (or previous) diff displayed in the structure viewer.
- *
- * @param next
- * <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
- * we should go to the previous instead.
- */
- protected void navigate(boolean next) {
- final Control control = getControl();
- if (control != null && !control.isDisposed()) {
- final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
- if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
- navigator.selectChange(next);
- }
- }
- }
-
- /**
- *
- */
- protected abstract void copyDiff(boolean leftToRight);
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeAncestor(int, int, int, int)
- */
- @Override
- protected void handleResizeAncestor(int x, int y, int width, int height) {
- if (width > 0) {
- getAncestorMergeViewer().getControl().setVisible(true);
- getAncestorMergeViewer().getControl().setBounds(x, y, width, height);
- } else {
- getAncestorMergeViewer().getControl().setVisible(false);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeLeftRight(int, int, int,
- * int, int, int)
- */
- @Override
- protected void handleResizeLeftRight(int x, int y, int width1, int centerWidth, int width2, int height) {
- fLeft.getControl().setBounds(x, y, width1, height);
- fRight.getControl().setBounds(x + width1 + centerWidth, y, width2, height);
- }
-
- protected abstract IMergeViewer createMergeViewer(Composite parent, MergeViewerSide side);
-
- @Override
- protected final int getCenterWidth() {
- return CENTER_WIDTH;
- }
-
- protected final CompareHandlerService getHandlerService() {
- return (CompareHandlerService)fDynamicObject.get(HANDLER_SERVICE);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getControl()
- */
- @Override
- public Composite getControl() {
- return (Composite)super.getControl();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createCenterControl(org.eclipse.swt.widgets.Composite)
- */
- @Override
- protected Control createCenterControl(Composite parent) {
- final Control ret = super.createCenterControl(parent);
-
- final PaintListener paintListener = new PaintListener() {
- public void paintControl(PaintEvent e) {
- paintCenter(e.gc);
- }
- };
- ret.addPaintListener(paintListener);
-
- ret.addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- ret.removePaintListener(paintListener);
- }
- });
-
- return ret;
- }
-
- protected abstract void paintCenter(GC g);
-
- public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
- if (adapter == CompareHandlerService.class) {
- return getHandlerService();
- }
- if (adapter == CompareHandlerService[].class) {
- return new CompareHandlerService[] {getHandlerService(), };
- }
- return null;
- }
-
- /**
- * @return the fAncestor
- */
- protected IMergeViewer getAncestorMergeViewer() {
- return fAncestor;
- }
-
- /**
- * @return the fLeft
- */
- protected IMergeViewer getLeftMergeViewer() {
- return fLeft;
- }
-
- /**
- * @return the fRight
- */
- protected IMergeViewer getRightMergeViewer() {
- return fRight;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
- */
- public void selectionChanged(SelectionChangedEvent event) {
- if (fSyncingSelections.compareAndSet(false, true)) { // prevents stack overflow :)
- try {
- ISelectionProvider selectionProvider = event.getSelectionProvider();
- ISelection selection = event.getSelection();
- synchronizeSelection(selectionProvider, selection);
- updateToolItems();
- } finally {
- fSyncingSelections.set(false);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateToolItems()
- */
- @Override
- protected void updateToolItems() {
- super.updateToolItems();
-
- Diff diff = getDiffFrom(getRightMergeViewer());
- if (diff == null) {
- diff = getDiffFrom(getLeftMergeViewer());
- }
- boolean enableCopy = false;
- if (diff != null) {
- enableCopy = true;
- }
-
- if (fCopyDiffLeftToRightItem != null) {
- fCopyDiffLeftToRightItem.getAction().setEnabled(enableCopy);
- }
- if (fCopyDiffRightToLeftItem != null) {
- fCopyDiffRightToLeftItem.getAction().setEnabled(enableCopy);
- }
- }
-
- /**
- * Checks the element selected in the given viewer in order to determine whether it can be adapted into a
- * Diff.
- *
- * @param viewer
- * The viewer which selection is to be checked.
- * @return The first of the Diffs selected in the given viewer, if any.
- */
- protected Diff getDiffFrom(IMergeViewer viewer) {
- Diff diff = null;
- final ISelection selection = viewer.getSelection();
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- final Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator();
- while (diff == null && selectedElements.hasNext()) {
- final Object element = selectedElements.next();
- if (element instanceof IMergeViewerItem) {
- diff = ((IMergeViewerItem)element).getDiff();
- }
- }
- }
- return diff;
- }
-
- private void synchronizeSelection(final ISelectionProvider selectionProvider, final ISelection selection) {
- if (selectionProvider == fLeft) {
- fRight.setSelection(selection, true);
- fAncestor.setSelection(selection, true);
- } else if (selectionProvider == fRight) {
- fLeft.setSelection(selection, true);
- fAncestor.setSelection(selection, true);
- } else { // selectionProvider == fAncestor
- fLeft.setSelection(selection, true);
- fRight.setSelection(selection, true);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
- */
- @Override
- protected void handleDispose(DisposeEvent event) {
- if (fCommandStackListener != null && getEditingDomain() != null) {
- getEditingDomain().getCommandStack().removeCommandStackListener(fCommandStackListener);
- }
- super.handleDispose(event);
- }
-}
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer;
+
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareNavigator;
+import org.eclipse.compare.ICompareNavigator;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.compare.internal.CompareHandlerService;
+import org.eclipse.compare.internal.Utilities;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
+import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.EMFCompareColor;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider;
+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.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.actions.ActionFactory;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer implements ISelectionChangedListener, ICompareColorProvider, IAdaptable {
+
+ private static final String HANDLER_SERVICE = "fHandlerService";
+
+ protected static final int HORIZONTAL = 1;
+
+ protected static final int VERTICAL = 2;
+
+ protected static final double HSPLIT = 0.5;
+
+ protected static final double VSPLIT = 0.3;
+
+ /**
+ * Width of center bar
+ */
+ protected static final int CENTER_WIDTH = 34;
+
+ private IMergeViewer fAncestor;
+
+ private IMergeViewer fLeft;
+
+ private IMergeViewer fRight;
+
+ private ActionContributionItem fCopyDiffLeftToRightItem;
+
+ private ActionContributionItem fCopyDiffRightToLeftItem;
+
+ private final AtomicBoolean fSyncingSelections = new AtomicBoolean(false);
+
+ private EMFCompareColor fColors;
+
+ private final DynamicObject fDynamicObject;
+
+ private CommandStackListener fCommandStackListener;
+
+ private UndoAction undoAction;
+
+ private RedoAction redoAction;
+
+ /**
+ * @param style
+ * @param bundle
+ * @param cc
+ */
+ protected EMFCompareContentMergeViewer(int style, ResourceBundle bundle, CompareConfiguration cc) {
+ super(style, bundle, cc);
+ fDynamicObject = new DynamicObject(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider#getCompareColor()
+ */
+ public ICompareColor getCompareColor() {
+ return fColors;
+ }
+
+ /**
+ * @return the fEditingDomain
+ */
+ protected final ICompareEditingDomain getEditingDomain() {
+ return (ICompareEditingDomain)getCompareConfiguration().getProperty(
+ EMFCompareConstants.EDITING_DOMAIN);
+ }
+
+ /**
+ * @return the fComparison
+ */
+ protected final Comparison getComparison() {
+ return (Comparison)getCompareConfiguration().getProperty(EMFCompareConstants.COMPARE_RESULT);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Overriden to enhance visibility.
+ * </p>
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#isThreeWay()
+ */
+ @Override
+ public boolean isThreeWay() {
+ // enhances visibility
+ return super.isThreeWay();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateContent(java.lang.Object,
+ * java.lang.Object, java.lang.Object)
+ */
+ @Override
+ protected void updateContent(Object ancestor, Object left, Object right) {
+ undoAction.setEditingDomain(getEditingDomain());
+ redoAction.setEditingDomain(getEditingDomain());
+
+ if (getEditingDomain() != null && fCommandStackListener == null) {
+ fCommandStackListener = installCommandStackListener(undoAction, redoAction);
+ }
+
+ fAncestor.setInput(ancestor);
+ fLeft.setInput(left);
+ fRight.setInput(right);
+ // must update selection after the three viewers input has been set
+ // to avoid some NPE/AssertionError (they are calling each other on selectionChanged event to
+ // synchronize their selection)
+
+ IMergeViewerItem leftInitialItem = null;
+ if (left instanceof ICompareAccessor) {
+ leftInitialItem = ((ICompareAccessor)left).getInitialItem();
+ }
+
+ ISelection leftSelection = createSelectionOrEmpty(leftInitialItem);
+ fLeft.setSelection(leftSelection, true); // others will synchronize on this one :)
+
+ getCenterControl().redraw();
+ }
+
+ private ISelection createSelectionOrEmpty(final Object o) {
+ final ISelection selection;
+ if (o != null) {
+ selection = new StructuredSelection(o);
+ } else {
+ selection = StructuredSelection.EMPTY;
+ }
+ return selection;
+ }
+
+ /**
+ * Inhibits this method to avoid asking to save on each input change!!
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#doSave(java.lang.Object,
+ * java.lang.Object)
+ */
+ @Override
+ protected boolean doSave(Object newInput, Object oldInput) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createControls(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected void createControls(Composite composite) {
+ fAncestor = createMergeViewer(composite, MergeViewerSide.ANCESTOR);
+ fAncestor.addSelectionChangedListener(this);
+
+ fLeft = createMergeViewer(composite, MergeViewerSide.LEFT);
+ fLeft.addSelectionChangedListener(this);
+
+ fRight = createMergeViewer(composite, MergeViewerSide.RIGHT);
+ fRight.addSelectionChangedListener(this);
+
+ fColors = new EMFCompareColor(this, null, getCompareConfiguration());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createToolItems(org.eclipse.jface.action.ToolBarManager)
+ */
+ @Override
+ protected void createToolItems(ToolBarManager toolBarManager) {
+ // Copy actions
+ CompareConfiguration cc = getCompareConfiguration();
+ if (cc.isRightEditable()) {
+ Action copyLeftToRight = new Action() {
+ @Override
+ public void run() {
+ copyDiff(true);
+ // Select next diff
+ navigate(true);
+ }
+ };
+ Utilities.initAction(copyLeftToRight, getResourceBundle(), "action.CopyDiffLeftToRight."); //$NON-NLS-1$
+ copyLeftToRight.setEnabled(false);
+ fCopyDiffLeftToRightItem = new ActionContributionItem(copyLeftToRight);
+ fCopyDiffLeftToRightItem.setVisible(true);
+ toolBarManager.appendToGroup("merge", fCopyDiffLeftToRightItem); //$NON-NLS-1$
+ getHandlerService().registerAction(copyLeftToRight, "org.eclipse.compare.copyLeftToRight"); //$NON-NLS-1$
+ }
+
+ if (cc.isLeftEditable()) {
+ Action copyRightToLeft = new Action() {
+ @Override
+ public void run() {
+ copyDiff(false);
+ // Select next diff
+ navigate(true);
+ }
+ };
+ Utilities.initAction(copyRightToLeft, getResourceBundle(), "action.CopyDiffRightToLeft."); //$NON-NLS-1$
+ copyRightToLeft.setEnabled(false);
+ fCopyDiffRightToLeftItem = new ActionContributionItem(copyRightToLeft);
+ fCopyDiffRightToLeftItem.setVisible(true);
+ toolBarManager.appendToGroup("merge", fCopyDiffRightToLeftItem); //$NON-NLS-1$
+ getHandlerService().registerAction(copyRightToLeft, "org.eclipse.compare.copyRightToLeft"); //$NON-NLS-1$
+ }
+
+ // Navigation
+ final Action nextDiff = new Action() {
+ @Override
+ public void run() {
+ navigate(true);
+ }
+ };
+ Utilities.initAction(nextDiff, getResourceBundle(), "action.NextDiff.");
+ ActionContributionItem contributionNextDiff = new ActionContributionItem(nextDiff);
+ contributionNextDiff.setVisible(true);
+ toolBarManager.appendToGroup("navigation", contributionNextDiff);
+
+ final Action previousDiff = new Action() {
+ @Override
+ public void run() {
+ navigate(false);
+ }
+ };
+ Utilities.initAction(previousDiff, getResourceBundle(), "action.PrevDiff.");
+ ActionContributionItem contributionPreviousDiff = new ActionContributionItem(previousDiff);
+ contributionPreviousDiff.setVisible(true);
+ toolBarManager.appendToGroup("navigation", contributionPreviousDiff);
+
+ undoAction = new UndoAction(getEditingDomain());
+ redoAction = new RedoAction(getEditingDomain());
+
+ if (getEditingDomain() != null && fCommandStackListener == null) {
+ fCommandStackListener = installCommandStackListener(undoAction, redoAction);
+ }
+
+ getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), undoAction);
+ getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), redoAction);
+ }
+
+ private CommandStackListener installCommandStackListener(final UndoAction undoAction,
+ final RedoAction redoAction) {
+ CommandStackListener commandStackListener = new CommandStackListener() {
+ public void commandStackChanged(EventObject event) {
+ undoAction.update();
+ redoAction.update();
+ setLeftDirty(getEditingDomain().getCommandStack().isLeftSaveNeeded());
+ setRightDirty(getEditingDomain().getCommandStack().isRightSaveNeeded());
+ refresh();
+ }
+ };
+ getEditingDomain().getCommandStack().addCommandStackListener(commandStackListener);
+ return commandStackListener;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#copy(boolean)
+ */
+ @Override
+ protected void copy(boolean leftToRight) {
+ EList<Diff> differences = getComparison().getDifferences();
+
+ final Command copyCommand = getEditingDomain().createCopyAllNonConflictingCommand(differences,
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
+
+ getEditingDomain().getCommandStack().execute(copyCommand);
+
+ // if (leftToRight) {
+ // setRightDirty(true);
+ // } else {
+ // setLeftDirty(true);
+ // }
+ refresh();
+ }
+
+ /**
+ * Called by the framework to navigate to the next (or previous) difference. This will open the content
+ * viewer for the next (or previous) diff displayed in the structure viewer.
+ *
+ * @param next
+ * <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
+ * we should go to the previous instead.
+ */
+ protected void navigate(boolean next) {
+ final Control control = getControl();
+ if (control != null && !control.isDisposed()) {
+ final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
+ if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
+ navigator.selectChange(next);
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ protected abstract void copyDiff(boolean leftToRight);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeAncestor(int, int, int, int)
+ */
+ @Override
+ protected void handleResizeAncestor(int x, int y, int width, int height) {
+ if (width > 0) {
+ getAncestorMergeViewer().getControl().setVisible(true);
+ getAncestorMergeViewer().getControl().setBounds(x, y, width, height);
+ } else {
+ getAncestorMergeViewer().getControl().setVisible(false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleResizeLeftRight(int, int, int,
+ * int, int, int)
+ */
+ @Override
+ protected void handleResizeLeftRight(int x, int y, int width1, int centerWidth, int width2, int height) {
+ fLeft.getControl().setBounds(x, y, width1, height);
+ fRight.getControl().setBounds(x + width1 + centerWidth, y, width2, height);
+ }
+
+ protected abstract IMergeViewer createMergeViewer(Composite parent, MergeViewerSide side);
+
+ @Override
+ protected final int getCenterWidth() {
+ return CENTER_WIDTH;
+ }
+
+ protected final CompareHandlerService getHandlerService() {
+ return (CompareHandlerService)fDynamicObject.get(HANDLER_SERVICE);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getControl()
+ */
+ @Override
+ public Composite getControl() {
+ return (Composite)super.getControl();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#createCenterControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createCenterControl(Composite parent) {
+ final Control ret = super.createCenterControl(parent);
+
+ final PaintListener paintListener = new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ paintCenter(e.gc);
+ }
+ };
+ ret.addPaintListener(paintListener);
+
+ ret.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ ret.removePaintListener(paintListener);
+ }
+ });
+
+ return ret;
+ }
+
+ protected abstract void paintCenter(GC g);
+
+ public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+ if (adapter == CompareHandlerService.class) {
+ return getHandlerService();
+ }
+ if (adapter == CompareHandlerService[].class) {
+ return new CompareHandlerService[] {getHandlerService(), };
+ }
+ return null;
+ }
+
+ /**
+ * @return the fAncestor
+ */
+ protected IMergeViewer getAncestorMergeViewer() {
+ return fAncestor;
+ }
+
+ /**
+ * @return the fLeft
+ */
+ protected IMergeViewer getLeftMergeViewer() {
+ return fLeft;
+ }
+
+ /**
+ * @return the fRight
+ */
+ protected IMergeViewer getRightMergeViewer() {
+ return fRight;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (fSyncingSelections.compareAndSet(false, true)) { // prevents stack overflow :)
+ try {
+ ISelectionProvider selectionProvider = event.getSelectionProvider();
+ ISelection selection = event.getSelection();
+ synchronizeSelection(selectionProvider, selection);
+ updateToolItems();
+ } finally {
+ fSyncingSelections.set(false);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#updateToolItems()
+ */
+ @Override
+ protected void updateToolItems() {
+ super.updateToolItems();
+
+ Diff diff = getDiffFrom(getRightMergeViewer());
+ if (diff == null) {
+ diff = getDiffFrom(getLeftMergeViewer());
+ }
+ boolean enableCopy = false;
+ if (diff != null) {
+ enableCopy = true;
+ }
+
+ if (fCopyDiffLeftToRightItem != null) {
+ fCopyDiffLeftToRightItem.getAction().setEnabled(enableCopy);
+ }
+ if (fCopyDiffRightToLeftItem != null) {
+ fCopyDiffRightToLeftItem.getAction().setEnabled(enableCopy);
+ }
+ }
+
+ /**
+ * Checks the element selected in the given viewer in order to determine whether it can be adapted into a
+ * Diff.
+ *
+ * @param viewer
+ * The viewer which selection is to be checked.
+ * @return The first of the Diffs selected in the given viewer, if any.
+ */
+ protected Diff getDiffFrom(IMergeViewer viewer) {
+ Diff diff = null;
+ final ISelection selection = viewer.getSelection();
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ final Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator();
+ while (diff == null && selectedElements.hasNext()) {
+ final Object element = selectedElements.next();
+ if (element instanceof IMergeViewerItem) {
+ diff = ((IMergeViewerItem)element).getDiff();
+ }
+ }
+ }
+ return diff;
+ }
+
+ private void synchronizeSelection(final ISelectionProvider selectionProvider, final ISelection selection) {
+ if (selectionProvider == fLeft) {
+ fRight.setSelection(selection, true);
+ fAncestor.setSelection(selection, true);
+ } else if (selectionProvider == fRight) {
+ fLeft.setSelection(selection, true);
+ fAncestor.setSelection(selection, true);
+ } else { // selectionProvider == fAncestor
+ fLeft.setSelection(selection, true);
+ fRight.setSelection(selection, true);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ protected void handleDispose(DisposeEvent event) {
+ if (fCommandStackListener != null && getEditingDomain() != null) {
+ getEditingDomain().getCommandStack().removeCommandStackListener(fCommandStackListener);
+ }
+ super.handleDispose(event);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
index bf46c8071..90b146fdd 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/ContentMergeViewerConstants.java
@@ -1,26 +1,28 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.accessor;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public final class ContentMergeViewerConstants {
-
- public static final String DIFF_NODE_TYPE = "emfcompare_diff"; //$NON-NLS-1$
-
- public static final String TEXT_DIFF_NODE_TYPE = "eText"; //$NON-NLS-1$
-
- public static final String EOBJECT_NODE_TYPE = "eobject"; //$NON-NLS-1$
-
- private ContentMergeViewerConstants() {
- }
-}
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer.accessor;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public final class ContentMergeViewerConstants {
+
+ public static final String DIFF_NODE_TYPE = "emfcompare_diff"; //$NON-NLS-1$
+
+ public static final String TEXT_DIFF_NODE_TYPE = "eText"; //$NON-NLS-1$
+
+ public static final String EOBJECT_NODE_TYPE = "eobject"; //$NON-NLS-1$
+
+ public static final String RESOURCE_CONTENTS_NODE_TYPE = "resource_contents"; //$NON-NLS-1$
+
+ private ContentMergeViewerConstants() {
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java
new file mode 100644
index 000000000..e865b8f73
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEResourceContentsAccessorImpl.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer.accessor;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ResourceContentsAccessorImpl;
+import org.eclipse.emf.ecore.provider.EcoreEditPlugin;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class IDEResourceContentsAccessorImpl extends ResourceContentsAccessorImpl implements ITypedElement, IStreamContentAccessor {
+
+ public IDEResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ super(diff, side);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getName()
+ */
+ public String getName() {
+ return this.getClass().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ public Image getImage() {
+ return ExtendedImageRegistry.getInstance().getImage(
+ EcoreEditPlugin.getPlugin().getImage("full/obj16/EObject")); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getType()
+ */
+ public String getType() {
+ return ContentMergeViewerConstants.RESOURCE_CONTENTS_NODE_TYPE;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.IStreamContentAccessor#getContents()
+ */
+ public InputStream getContents() throws CoreException {
+ /*
+ * #293926 : Whatever we return has no importance as long as it is not "null", this is only to make
+ * CompareUIPlugin#guessType happy. However, it is only happy if what we return resembles a text. Note
+ * that this bug has been fixed in 3.7.1, we're keeping this around for the compatibility with 3.5 and
+ * 3.6.
+ */
+ return new ByteArrayInputStream(new byte[] {' ' });
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEStringAttributeChangeAccessor.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEStringAttributeChangeAccessor.java
index 6439798af..869e4f15e 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEStringAttributeChangeAccessor.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/IDEStringAttributeChangeAccessor.java
@@ -10,19 +10,13 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
import org.eclipse.compare.IEditableContent;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.compare.AttributeChange;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.StringAttributeChangeAccessor;
-import org.eclipse.emf.compare.utils.ReferenceUtil;
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;
@@ -71,23 +65,6 @@ public class IDEStringAttributeChangeAccessor extends StringAttributeChangeAcces
/**
* {@inheritDoc}
*
- * @see org.eclipse.compare.IStreamContentAccessor#getContents()
- */
- @Override
- 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]);
- }
- }
-
- /**
- * {@inheritDoc}
- *
* @see org.eclipse.compare.IEditableContent#isEditable()
*/
public boolean isEditable() {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java
new file mode 100644
index 000000000..e47535ab5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/factory/IDEResourceContentsAccessorFactory.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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.ide.ui.internal.contentmergeviewer.accessor.factory;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory.AbstractAccessorFactory;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IDEResourceContentsAccessorImpl;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class IDEResourceContentsAccessorFactory extends AbstractAccessorFactory {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#isFactoryFor(java.lang.Object)
+ */
+ public boolean isFactoryFor(Object target) {
+ if (target instanceof ResourceAttachmentChange) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createLeft(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createLeft(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.LEFT);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createRight(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createRight(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.RIGHT);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory#createAncestor(org.eclipse.emf.common.notify.AdapterFactory,
+ * java.lang.Object)
+ */
+ public ITypedElement createAncestor(AdapterFactory adapterFactory, Object target) {
+ return new IDEResourceContentsAccessorImpl((Diff)target, MergeViewerSide.ANCESTOR);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
index 9ad9a9fee..6f4bfa15d 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewer.java
@@ -1,369 +1,371 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.table;
-
-import java.util.ResourceBundle;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.TableMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
-import org.eclipse.emf.edit.provider.IItemFontProvider;
-import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
-import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
-import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-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.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseWheelListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-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.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableContentMergeViewer extends EMFCompareContentMergeViewer {
-
- /**
- * Bundle name of the property file containing all displayed strings.
- */
- private static final String BUNDLE_NAME = TableContentMergeViewer.class.getName();
-
- private final ComposedAdapterFactory fAdapterFactory;
-
- private double[] fBasicCenterCurve;
-
- /**
- * Call the super constructor.
- *
- * @see TableContentMergeViewer
- */
- protected TableContentMergeViewer(Composite parent, CompareConfiguration config) {
- super(SWT.NONE, ResourceBundle.getBundle(BUNDLE_NAME), config);
- fAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
- fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
- fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
-
- buildControl(parent);
- setContentProvider(new TableContentMergeViewerContentProvider(config));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
- */
- @Override
- protected void handleDispose(DisposeEvent event) {
- fAdapterFactory.dispose();
- super.handleDispose(event);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getContents(boolean)
- */
- @Override
- protected byte[] getContents(boolean left) {
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#copyDiff(boolean)
- */
- @Override
- protected void copyDiff(boolean leftToRight) {
- final Diff diffToCopy = getDiffToCopy(getRightMergeViewer());
- if (diffToCopy != null) {
- Command copyCommand = getEditingDomain().createCopyCommand(diffToCopy, leftToRight);
- getEditingDomain().getCommandStack().execute(copyCommand);
-
- refresh();
- }
- }
-
- private Diff getDiffToCopy(MergeViewer mergeViewer) {
- Diff diffToCopy = null;
- ISelection selection = mergeViewer.getSelection();
- if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
- Object firstElement = ((IStructuredSelection)selection).getFirstElement();
- if (firstElement instanceof IMergeViewerItem) {
- diffToCopy = ((IMergeViewerItem)firstElement).getDiff();
- }
- }
- return diffToCopy;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getLeftMergeViewer()
- */
- @Override
- protected TableMergeViewer getLeftMergeViewer() {
- return (TableMergeViewer)super.getLeftMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getRightMergeViewer()
- */
- @Override
- protected TableMergeViewer getRightMergeViewer() {
- return (TableMergeViewer)super.getRightMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getAncestorMergeViewer()
- */
- @Override
- protected TableMergeViewer getAncestorMergeViewer() {
- return (TableMergeViewer)super.getAncestorMergeViewer();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite,
- * org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.IMergeViewer.MergeViewerSide)
- */
- @Override
- protected MergeViewer createMergeViewer(Composite parent, final MergeViewerSide side) {
- TableMergeViewer ret = new TableMergeViewer(parent, side, this);
- ret.getStructuredViewer().getTable().getVerticalBar().setVisible(false);
-
- ret.setContentProvider(new ArrayContentProvider() {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ArrayContentProvider#getElements(java.lang.Object)
- */
- @Override
- public Object[] getElements(Object inputElement) {
- if (inputElement instanceof IStructuralFeatureAccessor) {
- return super.getElements(((IStructuralFeatureAccessor)inputElement).getItems());
- }
- return super.getElements(inputElement);
- }
- });
- ret.setLabelProvider(new AdapterFactoryLabelProvider.FontAndColorProvider(fAdapterFactory, ret
- .getStructuredViewer()) {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object,
- * int)
- */
- @Override
- public Font getFont(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- final Object value = ((MatchedObject)object).getSideValue(side);
- if (value instanceof EObject && ((EObject)value).eIsProxy()) {
- return getFontFromObject(IItemFontProvider.ITALIC_FONT);
- }
- }
- return super.getFont(object, columnIndex);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnText(java.lang.Object,
- * int)
- */
- @Override
- public String getColumnText(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- final String text;
- final Object value = ((MatchedObject)object).getSideValue(side);
- if (value instanceof EObject && ((EObject)value).eIsProxy()) {
- text = "proxy : " + ((InternalEObject)value).eProxyURI().toString();
- } else {
- text = super.getColumnText(value, columnIndex);
- }
- return text;
- }
- return super.getColumnText(object, columnIndex);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnImage(java.lang.Object,
- * int)
- */
- @Override
- public Image getColumnImage(Object object, int columnIndex) {
- if (object instanceof MatchedObject) {
- return super.getColumnImage(((MatchedObject)object).getSideValue(side), columnIndex);
- }
- return super.getColumnImage(object, columnIndex);
- }
- });
- ret.getStructuredViewer().getTable().getVerticalBar().addListener(SWT.Selection, new Listener() {
- public void handleEvent(Event event) {
- redrawCenterControl();
- }
- });
-
- ret.getStructuredViewer().getTable().addMouseWheelListener(new MouseWheelListener() {
- public void mouseScrolled(MouseEvent e) {
- redrawCenterControl();
- }
- });
- ret.addSelectionChangedListener(new ISelectionChangedListener() {
- public void selectionChanged(SelectionChangedEvent event) {
- redrawCenterControl();
- }
- });
- return ret;
- }
-
- protected void redrawCenterControl() {
- getCenterControl().redraw();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#paintCenter(org.eclipse.swt.widgets.Canvas,
- * org.eclipse.swt.graphics.GC)
- */
- @Override
- protected void paintCenter(GC g) {
- TableMergeViewer leftMergeViewer = getLeftMergeViewer();
- TableMergeViewer rightMergeViewer = getRightMergeViewer();
-
- Table leftTable = leftMergeViewer.getStructuredViewer().getTable();
- Table rightTable = rightMergeViewer.getStructuredViewer().getTable();
-
- Rectangle leftClientArea = leftTable.getClientArea();
- Rectangle rightClientArea = rightTable.getClientArea();
-
- TableItem[] leftItems = leftTable.getItems();
- TableItem[] rightItems = rightTable.getItems();
-
- TableItem[] selection = leftTable.getSelection();
-
- for (TableItem leftItem : leftItems) {
- final boolean selected;
- if (selection.length > 0) {
- selected = leftItem == selection[0];
- } else {
- selected = false;
- }
- final Diff leftDiff = ((IMergeViewerItem)leftItem.getData()).getDiff();
-
- if (leftDiff != null && leftDiff.getState() == DifferenceState.UNRESOLVED) {
- TableItem rightItem = findRightTableItemFromLeftDiff(rightItems, leftDiff);
-
- if (rightItem != null) {
- Color strokeColor = getCompareColor().getStrokeColor(leftDiff, isThreeWay(), false,
- selected);
- g.setForeground(strokeColor);
- drawCenterLine(g, leftClientArea, rightClientArea, leftItem, rightItem);
- }
- }
- }
- }
-
- private void drawCenterLine(GC g, Rectangle leftClientArea, Rectangle rightClientArea,
- TableItem leftItem, TableItem rightItem) {
- Control control = getCenterControl();
- Point from = new Point(0, 0);
- Point to = new Point(0, 0);
-
- Rectangle leftBounds = leftItem.getBounds();
- Rectangle rightBounds = rightItem.getBounds();
-
- from.y = leftBounds.y + (leftBounds.height / 2) - leftClientArea.y + 1
- + getLeftMergeViewer().getVerticalOffset();
-
- to.x = control.getBounds().width;
- to.y = rightBounds.y + (rightBounds.height / 2) - rightClientArea.y + 1
- + getRightMergeViewer().getVerticalOffset();
-
- int[] points = getCenterCurvePoints(from, to);
- for (int i = 1; i < points.length; i++) {
- g.drawLine(from.x + i - 1, points[i - 1], i, points[i]);
- }
- }
-
- private TableItem findRightTableItemFromLeftDiff(TableItem[] rightItems, Diff leftDiff) {
- TableItem ret = null;
- for (int i = 0; i < rightItems.length && ret == null; i++) {
- TableItem rightItem = rightItems[i];
- final Diff rightDiff = ((IMergeViewerItem)rightItem.getData()).getDiff();
- if (leftDiff == rightDiff) {
- ret = rightItem;
- }
- }
- return ret;
- }
-
- private int[] getCenterCurvePoints(Point from, Point to) {
- int startx = from.x;
- int starty = from.y;
- int endx = to.x;
- int endy = to.y;
- if (fBasicCenterCurve == null) {
- buildBaseCenterCurve(endx - startx);
- }
- double height = endy - starty;
- height = height / 2;
- int width = endx - startx;
- int[] points = new int[width];
- for (int i = 0; i < width; i++) {
- points[i] = (int)(-height * fBasicCenterCurve[i] + height + starty);
- }
- return points;
- }
-
- private void buildBaseCenterCurve(int w) {
- double width = w;
- fBasicCenterCurve = new double[getCenterWidth()];
- for (int i = 0; i < getCenterWidth(); i++) {
- double r = i / width;
- fBasicCenterCurve[i] = Math.cos(Math.PI * r);
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.table;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
+import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.TableMergeViewer;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemFontProvider;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+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.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+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.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableContentMergeViewer extends EMFCompareContentMergeViewer {
+
+ /**
+ * Bundle name of the property file containing all displayed strings.
+ */
+ private static final String BUNDLE_NAME = TableContentMergeViewer.class.getName();
+
+ private final ComposedAdapterFactory fAdapterFactory;
+
+ private double[] fBasicCenterCurve;
+
+ /**
+ * Call the super constructor.
+ *
+ * @see TableContentMergeViewer
+ */
+ protected TableContentMergeViewer(Composite parent, CompareConfiguration config) {
+ super(SWT.NONE, ResourceBundle.getBundle(BUNDLE_NAME), config);
+ fAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+ fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
+ fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
+
+ buildControl(parent);
+ setContentProvider(new TableContentMergeViewerContentProvider(config));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
+ */
+ @Override
+ protected void handleDispose(DisposeEvent event) {
+ fAdapterFactory.dispose();
+ super.handleDispose(event);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getContents(boolean)
+ */
+ @Override
+ protected byte[] getContents(boolean left) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#copyDiff(boolean)
+ */
+ @Override
+ protected void copyDiff(boolean leftToRight) {
+ final Diff diffToCopy = getDiffToCopy(getRightMergeViewer());
+ if (diffToCopy != null) {
+ Command copyCommand = getEditingDomain().createCopyCommand(diffToCopy, leftToRight,
+ EMFCompareIDEPlugin.getDefault().getMergerRegistry());
+ getEditingDomain().getCommandStack().execute(copyCommand);
+
+ refresh();
+ }
+ }
+
+ private Diff getDiffToCopy(MergeViewer mergeViewer) {
+ Diff diffToCopy = null;
+ ISelection selection = mergeViewer.getSelection();
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ Object firstElement = ((IStructuredSelection)selection).getFirstElement();
+ if (firstElement instanceof IMergeViewerItem) {
+ diffToCopy = ((IMergeViewerItem)firstElement).getDiff();
+ }
+ }
+ return diffToCopy;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getLeftMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getLeftMergeViewer() {
+ return (TableMergeViewer)super.getLeftMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getRightMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getRightMergeViewer() {
+ return (TableMergeViewer)super.getRightMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#getAncestorMergeViewer()
+ */
+ @Override
+ protected TableMergeViewer getAncestorMergeViewer() {
+ return (TableMergeViewer)super.getAncestorMergeViewer();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite,
+ * org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.IMergeViewer.MergeViewerSide)
+ */
+ @Override
+ protected MergeViewer createMergeViewer(Composite parent, final MergeViewerSide side) {
+ TableMergeViewer ret = new TableMergeViewer(parent, side, this);
+ ret.getStructuredViewer().getTable().getVerticalBar().setVisible(false);
+
+ ret.setContentProvider(new ArrayContentProvider() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ArrayContentProvider#getElements(java.lang.Object)
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof ICompareAccessor) {
+ return super.getElements(((ICompareAccessor)inputElement).getItems());
+ }
+ return super.getElements(inputElement);
+ }
+ });
+ ret.setLabelProvider(new AdapterFactoryLabelProvider.FontAndColorProvider(fAdapterFactory, ret
+ .getStructuredViewer()) {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object,
+ * int)
+ */
+ @Override
+ public Font getFont(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ final Object value = ((MatchedObject)object).getSideValue(side);
+ if (value instanceof EObject && ((EObject)value).eIsProxy()) {
+ return getFontFromObject(IItemFontProvider.ITALIC_FONT);
+ }
+ }
+ return super.getFont(object, columnIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnText(java.lang.Object,
+ * int)
+ */
+ @Override
+ public String getColumnText(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ final String text;
+ final Object value = ((MatchedObject)object).getSideValue(side);
+ if (value instanceof EObject && ((EObject)value).eIsProxy()) {
+ text = "proxy : " + ((InternalEObject)value).eProxyURI().toString();
+ } else {
+ text = super.getColumnText(value, columnIndex);
+ }
+ return text;
+ }
+ return super.getColumnText(object, columnIndex);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getColumnImage(java.lang.Object,
+ * int)
+ */
+ @Override
+ public Image getColumnImage(Object object, int columnIndex) {
+ if (object instanceof MatchedObject) {
+ return super.getColumnImage(((MatchedObject)object).getSideValue(side), columnIndex);
+ }
+ return super.getColumnImage(object, columnIndex);
+ }
+ });
+ ret.getStructuredViewer().getTable().getVerticalBar().addListener(SWT.Selection, new Listener() {
+ public void handleEvent(Event event) {
+ redrawCenterControl();
+ }
+ });
+
+ ret.getStructuredViewer().getTable().addMouseWheelListener(new MouseWheelListener() {
+ public void mouseScrolled(MouseEvent e) {
+ redrawCenterControl();
+ }
+ });
+ ret.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ redrawCenterControl();
+ }
+ });
+ return ret;
+ }
+
+ protected void redrawCenterControl() {
+ getCenterControl().redraw();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#paintCenter(org.eclipse.swt.widgets.Canvas,
+ * org.eclipse.swt.graphics.GC)
+ */
+ @Override
+ protected void paintCenter(GC g) {
+ TableMergeViewer leftMergeViewer = getLeftMergeViewer();
+ TableMergeViewer rightMergeViewer = getRightMergeViewer();
+
+ Table leftTable = leftMergeViewer.getStructuredViewer().getTable();
+ Table rightTable = rightMergeViewer.getStructuredViewer().getTable();
+
+ Rectangle leftClientArea = leftTable.getClientArea();
+ Rectangle rightClientArea = rightTable.getClientArea();
+
+ TableItem[] leftItems = leftTable.getItems();
+ TableItem[] rightItems = rightTable.getItems();
+
+ TableItem[] selection = leftTable.getSelection();
+
+ for (TableItem leftItem : leftItems) {
+ final boolean selected;
+ if (selection.length > 0) {
+ selected = leftItem == selection[0];
+ } else {
+ selected = false;
+ }
+ final Diff leftDiff = ((IMergeViewerItem)leftItem.getData()).getDiff();
+
+ if (leftDiff != null && leftDiff.getState() == DifferenceState.UNRESOLVED) {
+ TableItem rightItem = findRightTableItemFromLeftDiff(rightItems, leftDiff);
+
+ if (rightItem != null) {
+ Color strokeColor = getCompareColor().getStrokeColor(leftDiff, isThreeWay(), false,
+ selected);
+ g.setForeground(strokeColor);
+ drawCenterLine(g, leftClientArea, rightClientArea, leftItem, rightItem);
+ }
+ }
+ }
+ }
+
+ private void drawCenterLine(GC g, Rectangle leftClientArea, Rectangle rightClientArea,
+ TableItem leftItem, TableItem rightItem) {
+ Control control = getCenterControl();
+ Point from = new Point(0, 0);
+ Point to = new Point(0, 0);
+
+ Rectangle leftBounds = leftItem.getBounds();
+ Rectangle rightBounds = rightItem.getBounds();
+
+ from.y = leftBounds.y + (leftBounds.height / 2) - leftClientArea.y + 1
+ + getLeftMergeViewer().getVerticalOffset();
+
+ to.x = control.getBounds().width;
+ to.y = rightBounds.y + (rightBounds.height / 2) - rightClientArea.y + 1
+ + getRightMergeViewer().getVerticalOffset();
+
+ int[] points = getCenterCurvePoints(from, to);
+ for (int i = 1; i < points.length; i++) {
+ g.drawLine(from.x + i - 1, points[i - 1], i, points[i]);
+ }
+ }
+
+ private TableItem findRightTableItemFromLeftDiff(TableItem[] rightItems, Diff leftDiff) {
+ TableItem ret = null;
+ for (int i = 0; i < rightItems.length && ret == null; i++) {
+ TableItem rightItem = rightItems[i];
+ final Diff rightDiff = ((IMergeViewerItem)rightItem.getData()).getDiff();
+ if (leftDiff == rightDiff) {
+ ret = rightItem;
+ }
+ }
+ return ret;
+ }
+
+ private int[] getCenterCurvePoints(Point from, Point to) {
+ int startx = from.x;
+ int starty = from.y;
+ int endx = to.x;
+ int endy = to.y;
+ if (fBasicCenterCurve == null) {
+ buildBaseCenterCurve(endx - startx);
+ }
+ double height = endy - starty;
+ height = height / 2;
+ int width = endx - startx;
+ int[] points = new int[width];
+ for (int i = 0; i < width; i++) {
+ points[i] = (int)(-height * fBasicCenterCurve[i] + height + starty);
+ }
+ return points;
+ }
+
+ private void buildBaseCenterCurve(int w) {
+ double width = w;
+ fBasicCenterCurve = new double[getCenterWidth()];
+ for (int i = 0; i < getCenterWidth(); i++) {
+ double r = i / width;
+ fBasicCenterCurve[i] = Math.cos(Math.PI * r);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
index e2346f277..26e71fc2b 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/table/TableContentMergeViewerContentProvider.java
@@ -1,207 +1,207 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.table;
-
-import static org.eclipse.emf.compare.ide.utils.ResourceUtil.saveAllResources;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.eclipse.compare.CompareConfiguration;
-import org.eclipse.compare.ITypedElement;
-import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
-import org.eclipse.compare.structuremergeviewer.ICompareInput;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableContentMergeViewerContentProvider implements IMergeViewerContentProvider {
-
- public static final char ANCESTOR_CONTRIBUTOR = 'A';
-
- public static final char RIGHT_CONTRIBUTOR = 'R';
-
- public static final char LEFT_CONTRIBUTOR = 'L';
-
- private CompareConfiguration fCompareConfiguration;
-
- private String fAncestorError;
-
- private String fLeftError;
-
- private String fRightError;
-
- public TableContentMergeViewerContentProvider(CompareConfiguration cc) {
- fCompareConfiguration = cc;
- }
-
- public void dispose() {
- // empty default implementation
- }
-
- public void inputChanged(Viewer v, Object o1, Object o2) {
- // we are not interested since we have no state
- }
-
- // ---- ancestor
-
- public void setAncestorError(String errorMessage) {
- fAncestorError = errorMessage;
- }
-
- public String getAncestorLabel(Object element) {
- if (fAncestorError != null) {
- return fAncestorError;
- }
- return fCompareConfiguration.getAncestorLabel(element);
- }
-
- public Image getAncestorImage(Object element) {
- if (fAncestorError != null) {
- return null;
- }
- return fCompareConfiguration.getAncestorImage(element);
- }
-
- public Object getAncestorContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getAncestor();
- }
- return null;
- }
-
- public boolean showAncestor(Object element) {
- if (element instanceof ICompareInput) {
- return true; // fix for #45239: Show ancestor for incoming and outgoing changes
- }
- // return (((ICompareInput)element).getKind() & Differencer.DIRECTION_MASK) ==
- // Differencer.CONFLICTING;
- return false;
- }
-
- // ---- left
-
- public void setLeftError(String errorMessage) {
- fLeftError = errorMessage;
- }
-
- public String getLeftLabel(Object element) {
- if (fLeftError != null) {
- return fLeftError;
- }
- return fCompareConfiguration.getLeftLabel(element);
- }
-
- public Image getLeftImage(Object element) {
- if (fLeftError != null) {
- return null;
- }
- return fCompareConfiguration.getLeftImage(element);
- }
-
- public Object getLeftContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getLeft();
- }
- return null;
- }
-
- public boolean isLeftEditable(Object element) {
- return fCompareConfiguration.isLeftEditable();
- }
-
- public void saveLeftContent(Object element, byte[] bytes) {
- if (element instanceof ICompareInput) {
- ICompareInput node = (ICompareInput)element;
- ITypedElement left = node.getLeft();
- if (left instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)left).getComparison();
- EList<Match> matches = comparison.getMatches();
- EObject leftEObject = null;
- for (Match match : matches) {
- leftEObject = match.getLeft();
- if (leftEObject != null) {
- break;
- }
- }
- if (leftEObject != null) {
- Resource eResource = leftEObject.eResource();
- ResourceSet resourceSet = eResource.getResourceSet();
- saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
- Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
- }
- }
- }
- }
-
- // ---- right
-
- public void setRightError(String errorMessage) {
- fRightError = errorMessage;
- }
-
- public String getRightLabel(Object element) {
- if (fRightError != null) {
- return fRightError;
- }
- return fCompareConfiguration.getRightLabel(element);
- }
-
- public Image getRightImage(Object element) {
- if (fRightError != null) {
- return null;
- }
- return fCompareConfiguration.getRightImage(element);
- }
-
- public Object getRightContent(Object element) {
- if (element instanceof ICompareInput) {
- return ((ICompareInput)element).getRight();
- }
- return null;
- }
-
- public boolean isRightEditable(Object element) {
- return fCompareConfiguration.isRightEditable();
- }
-
- public void saveRightContent(Object element, byte[] bytes) {
- if (element instanceof ICompareInput) {
- ICompareInput node = (ICompareInput)element;
- ITypedElement right = node.getRight();
- if (right instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)right).getComparison();
- EList<Match> matches = comparison.getMatches();
- EObject rightEObject = null;
- for (Match match : matches) {
- rightEObject = match.getRight();
- if (rightEObject != null) {
- break;
- }
- }
- if (rightEObject != null) {
- Resource eResource = rightEObject.eResource();
- ResourceSet resourceSet = eResource.getResourceSet();
- saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
- Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
- }
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.table;
+
+import static org.eclipse.emf.compare.ide.utils.ResourceUtil.saveAllResources;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableContentMergeViewerContentProvider implements IMergeViewerContentProvider {
+
+ public static final char ANCESTOR_CONTRIBUTOR = 'A';
+
+ public static final char RIGHT_CONTRIBUTOR = 'R';
+
+ public static final char LEFT_CONTRIBUTOR = 'L';
+
+ private CompareConfiguration fCompareConfiguration;
+
+ private String fAncestorError;
+
+ private String fLeftError;
+
+ private String fRightError;
+
+ public TableContentMergeViewerContentProvider(CompareConfiguration cc) {
+ fCompareConfiguration = cc;
+ }
+
+ public void dispose() {
+ // empty default implementation
+ }
+
+ public void inputChanged(Viewer v, Object o1, Object o2) {
+ // we are not interested since we have no state
+ }
+
+ // ---- ancestor
+
+ public void setAncestorError(String errorMessage) {
+ fAncestorError = errorMessage;
+ }
+
+ public String getAncestorLabel(Object element) {
+ if (fAncestorError != null) {
+ return fAncestorError;
+ }
+ return fCompareConfiguration.getAncestorLabel(element);
+ }
+
+ public Image getAncestorImage(Object element) {
+ if (fAncestorError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getAncestorImage(element);
+ }
+
+ public Object getAncestorContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getAncestor();
+ }
+ return null;
+ }
+
+ public boolean showAncestor(Object element) {
+ if (element instanceof ICompareInput) {
+ return true; // fix for #45239: Show ancestor for incoming and outgoing changes
+ }
+ // return (((ICompareInput)element).getKind() & Differencer.DIRECTION_MASK) ==
+ // Differencer.CONFLICTING;
+ return false;
+ }
+
+ // ---- left
+
+ public void setLeftError(String errorMessage) {
+ fLeftError = errorMessage;
+ }
+
+ public String getLeftLabel(Object element) {
+ if (fLeftError != null) {
+ return fLeftError;
+ }
+ return fCompareConfiguration.getLeftLabel(element);
+ }
+
+ public Image getLeftImage(Object element) {
+ if (fLeftError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getLeftImage(element);
+ }
+
+ public Object getLeftContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getLeft();
+ }
+ return null;
+ }
+
+ public boolean isLeftEditable(Object element) {
+ return fCompareConfiguration.isLeftEditable();
+ }
+
+ public void saveLeftContent(Object element, byte[] bytes) {
+ if (element instanceof ICompareInput) {
+ ICompareInput node = (ICompareInput)element;
+ ITypedElement left = node.getLeft();
+ if (left instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)left).getComparison();
+ EList<Match> matches = comparison.getMatches();
+ EObject leftEObject = null;
+ for (Match match : matches) {
+ leftEObject = match.getLeft();
+ if (leftEObject != null) {
+ break;
+ }
+ }
+ if (leftEObject != null) {
+ Resource eResource = leftEObject.eResource();
+ ResourceSet resourceSet = eResource.getResourceSet();
+ saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
+ Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
+ }
+ }
+ }
+ }
+
+ // ---- right
+
+ public void setRightError(String errorMessage) {
+ fRightError = errorMessage;
+ }
+
+ public String getRightLabel(Object element) {
+ if (fRightError != null) {
+ return fRightError;
+ }
+ return fCompareConfiguration.getRightLabel(element);
+ }
+
+ public Image getRightImage(Object element) {
+ if (fRightError != null) {
+ return null;
+ }
+ return fCompareConfiguration.getRightImage(element);
+ }
+
+ public Object getRightContent(Object element) {
+ if (element instanceof ICompareInput) {
+ return ((ICompareInput)element).getRight();
+ }
+ return null;
+ }
+
+ public boolean isRightEditable(Object element) {
+ return fCompareConfiguration.isRightEditable();
+ }
+
+ public void saveRightContent(Object element, byte[] bytes) {
+ if (element instanceof ICompareInput) {
+ ICompareInput node = (ICompareInput)element;
+ ITypedElement right = node.getRight();
+ if (right instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)right).getComparison();
+ EList<Match> matches = comparison.getMatches();
+ EObject rightEObject = null;
+ for (Match match : matches) {
+ rightEObject = match.getRight();
+ if (rightEObject != null) {
+ break;
+ }
+ }
+ if (rightEObject != null) {
+ Resource eResource = rightEObject.eResource();
+ ResourceSet resourceSet = eResource.getResourceSet();
+ saveAllResources(resourceSet, ImmutableMap.of(Resource.OPTION_SAVE_ONLY_IF_CHANGED,
+ Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER));
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
index 22a45a32a..d3324a3bb 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
@@ -33,14 +33,18 @@ import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.command.ICompareCopyCommand;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.AttributeChangeNode;
+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.EStructuralFeature;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.ChangeCommand;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
@@ -87,7 +91,7 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer {
final Comparison comparison = attributeChange.getMatch().getComparison();
final Command copyCommand = fEditingDomain.createCopyAllNonConflictingCommand(comparison
- .getDifferences(), leftToRight);
+ .getDifferences(), leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
fEditingDomain.getCommandStack().execute(copyCommand);
refresh();
@@ -99,7 +103,8 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer {
if (input instanceof AttributeChangeNode) {
final AttributeChange attributeChange = ((AttributeChangeNode)input).getTarget();
- final Command copyCommand = fEditingDomain.createCopyCommand(attributeChange, leftToRight);
+ final Command copyCommand = fEditingDomain.createCopyCommand(attributeChange, leftToRight,
+ EMFCompareIDEPlugin.getDefault().getMergerRegistry());
fEditingDomain.getCommandStack().execute(copyCommand);
refresh();
@@ -130,32 +135,41 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer {
if (oldInput instanceof AttributeChangeNode) {
final AttributeChange diff = ((AttributeChangeNode)oldInput).getTarget();
final EAttribute eAttribute = diff.getAttribute();
- Match match = diff.getMatch();
- final EObject left = match.getLeft();
- final EObject right = match.getRight();
- Object oldLeftValue = ReferenceUtil.safeEGet(left, eAttribute);
- Object oldRightValue = ReferenceUtil.safeEGet(right, eAttribute);
- final String newLeftValue = new String(getContents(true));
- final Object newRightValue = new String(getContents(false));
- if (!newLeftValue.equals(oldLeftValue) && getCompareConfiguration().isLeftEditable()) {
- // Save the change on left side
- fEditingDomain.getCommandStack().execute(
- new UpdateModelAndRejectDiffCommand(fEditingDomain.getChangeRecorder(), left,
- eAttribute, newLeftValue, diff, true));
- }
- if (!newRightValue.equals(oldRightValue) && getCompareConfiguration().isRightEditable()) {
- // Save the change on right side
- fEditingDomain.getCommandStack().execute(
- new UpdateModelAndRejectDiffCommand(fEditingDomain.getChangeRecorder(), right,
- eAttribute, newRightValue, diff, false));
-
- }
+ final Match match = diff.getMatch();
+ final IEqualityHelper equalityHelper = match.getComparison().getEqualityHelper();
+ updateModel(diff, eAttribute, equalityHelper, match.getLeft(), true);
+ updateModel(diff, eAttribute, equalityHelper, match.getRight(), false);
}
}
super.setInput(newInput);
}
+ private void updateModel(final AttributeChange diff, final EAttribute eAttribute,
+ final IEqualityHelper equalityHelper, final EObject eObject, boolean isLeft) {
+ final String oldValue = getStringValue(eObject, eAttribute);
+ final String newValue = new String(getContents(isLeft));
+
+ final boolean oldAndNewEquals = equalityHelper.matchingAttributeValues(newValue, oldValue);
+ if (eObject != null && !oldAndNewEquals && getCompareConfiguration().isLeftEditable()) {
+ // Save the change on left side
+ fEditingDomain.getCommandStack().execute(
+ new UpdateModelAndRejectDiffCommand(fEditingDomain.getChangeRecorder(), eObject,
+ eAttribute, newValue, diff, isLeft));
+ }
+ }
+
+ 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);
+ }
+
/**
* @return the fDynamicObject
*/
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewerContentProvider.java
index 4bab9d525..4f5c006e6 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewerContentProvider.java
@@ -135,6 +135,7 @@ public class EMFCompareTextMergeViewerContentProvider implements IMergeViewerCon
}
if (element instanceof ICompareInput) {
Object left = ((ICompareInput)element).getLeft();
+ // TODO: MBA use adapterfactory
if (left == null && element instanceof IDiffElement) {
IDiffElement parent = ((IDiffElement)element).getParent();
if (parent instanceof ICompareInput) {
@@ -206,6 +207,7 @@ public class EMFCompareTextMergeViewerContentProvider implements IMergeViewerCon
if (element instanceof ICompareInput) {
Object right = ((ICompareInput)element).getRight();
if (right == null && element instanceof IDiffElement) {
+ // TODO: MBA use adapterfactory
IDiffContainer parent = ((IDiffElement)element).getParent();
if (parent instanceof ICompareInput) {
right = ((ICompareInput)parent).getRight();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewer.java
index 064c11e88..8c9c40ce9 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewer.java
@@ -16,11 +16,11 @@ import java.util.ResourceBundle;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.TreeMergeViewer;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IEObjectAccessor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
@@ -145,7 +145,7 @@ public class TreeContentMergeViewer extends EMFCompareContentMergeViewer {
List<Diff> differences = getComparison().getDifferences((EObject)firstElement);
final Command command = getEditingDomain().createCopyAllNonConflictingCommand(differences,
- leftToRight);
+ leftToRight, EMFCompareIDEPlugin.getDefault().getMergerRegistry());
getEditingDomain().getCommandStack().execute(command);
refresh();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewerContentProvider.java
index 89158b648..3283d8945 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/tree/TreeContentMergeViewerContentProvider.java
@@ -50,7 +50,8 @@ public class TreeContentMergeViewerContentProvider implements IMergeViewerConten
private final Comparison fComparison;
/**
- * Creates a new {@link TreeContentMergeViewerContentProvider} and stored the given {@link CompareConfiguration}.
+ * Creates a new {@link TreeContentMergeViewerContentProvider} and stored the given
+ * {@link CompareConfiguration}.
*
* @param cc
* the {@link CompareConfiguration} that will be used to get label and image of left, right and
@@ -111,6 +112,7 @@ public class TreeContentMergeViewerContentProvider implements IMergeViewerConten
Object ret = compareInput.getAncestor();
// if no ancestor and element is a diff, try to reach the ancestor of parent, recursively
if (ret == null && element instanceof IDiffElement) {
+ // TODO: MBA use adapterfactory
IDiffContainer parent = ((IDiffElement)compareInput).getParent();
ret = getAncestorContent(parent);
}
@@ -162,6 +164,7 @@ public class TreeContentMergeViewerContentProvider implements IMergeViewerConten
Object ret = compareInput.getLeft();
// if no left and element is a diff, try to reach the left of parent, recursively
if (ret == null && element instanceof IDiffElement) {
+ // TODO: MBA use adapterfactory
IDiffContainer parent = ((IDiffElement)compareInput).getParent();
ret = getLeftContent(parent);
}
@@ -240,6 +243,7 @@ public class TreeContentMergeViewerContentProvider implements IMergeViewerConten
Object ret = compareInput.getRight();
// if no right and element is a diff, try to reach the right of parent, recursively
if (ret == null && element instanceof IDiffElement) {
+ // TODO: MBA use adapterfactory
IDiffContainer parent = ((IDiffElement)compareInput).getParent();
ret = getRightContent(parent);
}
@@ -260,6 +264,7 @@ public class TreeContentMergeViewerContentProvider implements IMergeViewerConten
} else if (element instanceof ICompareInput) {
Object right = ((ICompareInput)element).getRight();
if (right == null && element instanceof IDiffElement) {
+ // TODO: MBA use adapterfactory
IDiffContainer parent = ((IDiffElement)element).getParent();
if (parent instanceof ICompareInput) {
right = ((ICompareInput)parent).getRight();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffContainer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffContainer.java
deleted file mode 100644
index c9fcde5ec..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffContainer.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.structuremergeviewer;
-
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.toArray;
-import static com.google.common.collect.Iterables.transform;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-
-import java.util.Collection;
-
-import org.eclipse.compare.structuremergeviewer.IDiffContainer;
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class AbstractEDiffContainer extends AbstractEDiffElement implements IDiffContainer {
-
- /**
- * @param adapterFactory
- */
- public AbstractEDiffContainer(AdapterFactory adapterFactory) {
- super(adapterFactory);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffContainer#hasChildren()
- */
- public boolean hasChildren() {
- boolean ret = false;
- Adapter treeItemContentProvider = getAdapterFactory().adapt(getTarget(),
- ITreeItemContentProvider.class);
- if (treeItemContentProvider instanceof ITreeItemContentProvider) {
- ret = ((ITreeItemContentProvider)treeItemContentProvider).hasChildren(target);
- }
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffContainer#getChildren()
- */
- public IDiffElement[] getChildren() {
- Iterable<IDiffElement> ret = ImmutableList.of();
- Adapter treeItemContentProvider = getAdapterFactory().adapt(target, ITreeItemContentProvider.class);
- if (treeItemContentProvider instanceof ITreeItemContentProvider) {
- Collection<?> children = ((ITreeItemContentProvider)treeItemContentProvider).getChildren(target);
- ret = adapt(children, getAdapterFactory(), IDiffElement.class);
- }
-
- return toArray(ret, IDiffElement.class);
- }
-
- /**
- * Always throws {@link UnsupportedOperationException}. This {@link AbstractEDiffContainer} is adapted
- * from a diff EObject and cannot be modified directly.
- *
- * @param child
- * the child to add
- * @throws UnsupportedOperationException
- * @see org.eclipse.compare.structuremergeviewer.IDiffContainer#add(org.eclipse.compare.structuremergeviewer.IDiffElement)
- */
- public void add(IDiffElement child) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Always throws {@link UnsupportedOperationException}. This {@link AbstractEDiffContainer} is adapted
- * from a diff EObject and cannot be modified directly.
- *
- * @param child
- * the child to add
- * @throws UnsupportedOperationException
- * @see org.eclipse.compare.structuremergeviewer.IDiffContainer#removeToRoot(org.eclipse.compare.structuremergeviewer.IDiffElement)
- */
- public void removeToRoot(IDiffElement child) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Adapts each elements of the the given <code>iterable</code> to the given <code>type</code> by using the
- * given <code>adapterFactory</code>.
- *
- * @param <T>
- * the type of returned elements.
- * @param iterable
- * the iterable to transform.
- * @param adapterFactory
- * the {@link AdapterFactory} used to adapt elements
- * @param type
- * the target type of adapted elements
- * @return an iterable with element of type <code>type</code>.
- */
- protected static <T> Iterable<T> adapt(Iterable<?> iterable, final AdapterFactory adapterFactory,
- final Class<T> type) {
- Function<Object, Object> adaptFunction = new Function<Object, Object>() {
- public Object apply(Object input) {
- return adapterFactory.adapt(input, type);
- }
- };
- return filter(transform(iterable, adaptFunction), type);
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffElement.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffElement.java
deleted file mode 100644
index f0d1422bb..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffElement.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.structuremergeviewer;
-
-import org.eclipse.compare.structuremergeviewer.Differencer;
-import org.eclipse.compare.structuremergeviewer.IDiffContainer;
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.edit.provider.IItemLabelProvider;
-import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
-import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * An EMF {@link Adapter} implementing the {@link IDiffElement} interface.
- * <p>
- * It is delegating {@link #getImage()} and {@link #getName()} to an adapter retrieved from an
- * {@link AdapterFactory}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class AbstractEDiffElement extends AdapterImpl implements IDiffElement {
-
- /**
- * The {@link AdapterFactory} used to implement {@link #getName()} and {@link #getImage()}.
- */
- private final AdapterFactory fAdapterFactory;
-
- /**
- * Simple constructor storing the given {@link AdapterFactory}.
- *
- * @param adapterFactory
- * the factory.
- */
- public AbstractEDiffElement(AdapterFactory adapterFactory) {
- fAdapterFactory = adapterFactory;
- }
-
- @Override
- public boolean isAdapterForType(Object type) {
- return type == fAdapterFactory;
- }
-
- /**
- * Final accessor to the {@link AdapterFactory} for sub classses.
- *
- * @return the wrapped {@link AdapterFactory}.
- */
- protected final AdapterFactory getAdapterFactory() {
- return fAdapterFactory;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getName()
- */
- public String getName() {
- String ret = null;
- Adapter adapter = getAdapterFactory().adapt(target, IItemLabelProvider.class);
- if (adapter instanceof IItemLabelProvider) {
- ret = ((IItemLabelProvider)adapter).getText(target);
- }
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getImage()
- */
- public Image getImage() {
- Image ret = null;
- Adapter adapter = getAdapterFactory().adapt(target, IItemLabelProvider.class);
- if (adapter instanceof IItemLabelProvider) {
- Object imageObject = ((IItemLabelProvider)adapter).getImage(target);
- ret = ExtendedImageRegistry.getInstance().getImage(imageObject);
- }
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getType()
- */
- public String getType() {
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.structuremergeviewer.IDiffElement#getKind()
- */
- public int getKind() {
- return Differencer.NO_CHANGE;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.structuremergeviewer.IDiffElement#getParent()
- */
- public IDiffContainer getParent() {
- IDiffContainer ret = null;
- if (target instanceof EObject) {
- Adapter treeItemContentProvider = getAdapterFactory().adapt(target,
- ITreeItemContentProvider.class);
- if (treeItemContentProvider instanceof ITreeItemContentProvider) {
- ret = getParentAndAdaptAsIDiffContainer((ITreeItemContentProvider)treeItemContentProvider);
- }
- }
- return ret;
- }
-
- /**
- * @param treeItemContentProvider
- * @return
- */
- private IDiffContainer getParentAndAdaptAsIDiffContainer(ITreeItemContentProvider treeItemContentProvider) {
- IDiffContainer ret = null;
- Object parent = treeItemContentProvider.getParent(target);
- if (parent instanceof EObject) {
- Object diffContainer = getAdapterFactory().adapt(parent, IDiffContainer.class);
- if (diffContainer instanceof IDiffContainer) {
- ret = (IDiffContainer)diffContainer;
- }
- }
- return ret;
- }
-
- /**
- * Always throws {@link UnsupportedOperationException}. This {@link AbstractEDiffElement} is adapted from
- * a diff EObject and cannot be modified directly.
- *
- * @param parent
- * the parent to set
- * @see org.eclipse.compare.structuremergeviewer.IDiffElement#setParent(org.eclipse.compare.structuremergeviewer.IDiffContainer)
- * @throws UnsupportedOperationException
- */
- public void setParent(IDiffContainer parent) {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffNode.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffNode.java
index 943129613..a7d8107ac 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffNode.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/AbstractEDiffNode.java
@@ -11,20 +11,26 @@
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.IAccessorFactory.Registry;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.swt.graphics.Image;
/**
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public abstract class AbstractEDiffNode extends AbstractEDiffContainer implements ICompareInput {
+public abstract class AbstractEDiffNode extends AdapterImpl implements ICompareInput {
/**
*
@@ -32,13 +38,35 @@ public abstract class AbstractEDiffNode extends AbstractEDiffContainer implement
private final ListenerList fListener;
/**
+ * The {@link AdapterFactory} used to implement {@link #getName()} and {@link #getImage()}.
+ */
+ private final AdapterFactory fAdapterFactory;
+
+ /**
+ * Simple constructor storing the given {@link AdapterFactory}.
+ *
* @param adapterFactory
+ * the factory.
*/
public AbstractEDiffNode(AdapterFactory adapterFactory) {
- super(adapterFactory);
+ fAdapterFactory = adapterFactory;
fListener = new ListenerList();
}
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return type == fAdapterFactory;
+ }
+
+ /**
+ * Final accessor to the {@link AdapterFactory} for sub classses.
+ *
+ * @return the wrapped {@link AdapterFactory}.
+ */
+ protected final AdapterFactory getAdapterFactory() {
+ return fAdapterFactory;
+ }
+
/**
* {@inheritDoc}
*
@@ -92,6 +120,34 @@ public abstract class AbstractEDiffNode extends AbstractEDiffContainer implement
/**
* {@inheritDoc}
*
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ public Image getImage() {
+ Image ret = null;
+ Adapter adapter = getAdapterFactory().adapt(target, IItemLabelProvider.class);
+ if (adapter instanceof IItemLabelProvider) {
+ Object imageObject = ((IItemLabelProvider)adapter).getImage(target);
+ ret = ExtendedImageRegistry.getInstance().getImage(imageObject);
+ }
+ return ret;
+ }
+
+ public int getKind() {
+ return Differencer.NO_CHANGE;
+ }
+
+ public String getName() {
+ String ret = null;
+ Adapter adapter = getAdapterFactory().adapt(target, IItemLabelProvider.class);
+ if (adapter instanceof IItemLabelProvider) {
+ ret = ((IItemLabelProvider)adapter).getText(target);
+ }
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.eclipse.compare.structuremergeviewer.ICompareInput#getAncestor()
*/
public ITypedElement getAncestor() {
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DiffNodeComparer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DiffNodeComparer.java
index 53250f592..cbb779b68 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DiffNodeComparer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/DiffNodeComparer.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
+import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.jface.viewers.IElementComparer;
@@ -49,13 +50,13 @@ public class DiffNodeComparer implements IElementComparer {
*/
public boolean equals(Object a, Object b) {
final boolean equal;
- if (a instanceof AbstractEDiffElement && b instanceof AbstractEDiffElement) {
- final Notifier targetA = ((AbstractEDiffElement)a).getTarget();
+ if (a instanceof Adapter && b instanceof Adapter) {
+ final Notifier targetA = ((Adapter)a).getTarget();
if (targetA == null) {
// Fall back to default behavior
equal = a.equals(b);
} else {
- equal = targetA.equals(((AbstractEDiffElement)b).getTarget());
+ equal = targetA.equals(((Adapter)b).getTarget());
}
} else if (delegate != null) {
equal = delegate.equals(a, b);
@@ -74,8 +75,8 @@ public class DiffNodeComparer implements IElementComparer {
*/
public int hashCode(Object element) {
final int hashCode;
- if (element instanceof AbstractEDiffElement) {
- final Notifier target = ((AbstractEDiffElement)element).getTarget();
+ if (element instanceof Adapter) {
+ final Notifier target = ((Adapter)element).getTarget();
if (target == null) {
// Fall back to default behavior
hashCode = element.hashCode();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
index 139363528..ce01d30bd 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -12,9 +12,13 @@ package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
import static com.google.common.collect.Lists.newArrayList;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.EventObject;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -24,7 +28,6 @@ import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.DiffTreeViewer;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
@@ -41,15 +44,18 @@ import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.EMFCompareIDE;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.actions.filter.DifferenceFilter;
-import org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionMenu;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGrouper;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.GroupActionMenu;
import org.eclipse.emf.compare.ide.ui.internal.actions.save.SaveComparisonModelAction;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.CompareConfigurationExtension;
import org.eclipse.emf.compare.ide.ui.internal.editor.ComparisonScopeInput;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ComparisonNode;
import org.eclipse.emf.compare.ide.ui.logical.EMFSynchronizationModel;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions.FilterActionMenu;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions.GroupActionMenu;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DefaultGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
@@ -57,10 +63,18 @@ import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IElementComparer;
+import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;
@@ -81,19 +95,34 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
private ICompareEditingDomain editingDomain;
+ /** The comparator used for this structure merge viewer */
+ private EMFCompareStructureMergeViewerComparator structureMergeViewerComparator;
+
/**
* The difference filter that will be applied to the structure viewer. Note that this will be initialized
* from {@link #createToolItems(ToolBarManager)} since that method is called from the super-constructor
* and we cannot init ourselves beforehand.
*/
- private DifferenceFilter differenceFilter;
+ private StructureMergeViewerFilter structureMergeViewerFilter;
/**
* This will be used by our adapter factory in order to group together the differences located under the
* Comparison. Note that this will be initialized from {@link #createToolItems(ToolBarManager)} since that
* method is called from the super-constructor and we cannot init ourselves beforehand.
*/
- private DifferenceGrouper differenceGrouper;
+ private StructureMergeViewerGrouper structureMergeViewerGrouper;
+
+ private MenuManager groupsMenuManager;
+
+ private MenuManager filtersMenuManager;
+
+ private GroupActionMenu groupActionMenu;
+
+ private DefaultGroupProvider defaultGroupProvider;
+
+ private FilterActionMenu filterActionMenu;
+
+ private EventBus eventBus;
/**
* @param parent
@@ -106,10 +135,12 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
fAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
fAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
- boolean leftIsLocal = CompareConfigurationExtension.getBoolean(configuration, "LEFT_IS_LOCAL", false); //$NON-NLS-1$
- setLabelProvider(new EMFCompareStructureMergeViewerLabelProvider(fAdapterFactory, this, leftIsLocal));
+ structureMergeViewerComparator = new EMFCompareStructureMergeViewerComparator();
+
+ setLabelProvider(new DelegatingStyledCellLabelProvider(
+ new EMFCompareStructureMergeViewerLabelProvider(fAdapterFactory, this)));
setContentProvider(new EMFCompareStructureMergeViewerContentProvider(fAdapterFactory,
- differenceGrouper));
+ structureMergeViewerGrouper));
if (parent instanceof CompareViewerSwitchingPane) {
fParent = (CompareViewerSwitchingPane)parent;
@@ -125,6 +156,49 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
// Wrap the defined comparer in our own.
setComparer(new DiffNodeComparer(super.getComparer()));
+
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.StructuredViewer#getComparator()
+ */
+ @Override
+ public ViewerComparator getComparator() {
+ return structureMergeViewerComparator;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Subscribe
+ public void recordFilterSelectionChange(IDifferenceFilterSelectionChangeEvent event) {
+ final Object property = getCompareConfiguration().getProperty(EMFCompareConstants.SELECTED_FILTERS);
+ final Collection<IDifferenceFilter> selectedFilters;
+ if (property == null) {
+ selectedFilters = new HashSet<IDifferenceFilter>();
+ } else {
+ selectedFilters = (Collection<IDifferenceFilter>)property;
+ }
+ switch (event.getAction()) {
+ case ADD:
+ selectedFilters.add(event.getFilter());
+ break;
+ case REMOVE:
+ selectedFilters.remove(event.getFilter());
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_FILTERS, selectedFilters);
+ }
+
+ @Subscribe
+ public void recordGroupProviderSelectionChange(IDifferenceGroupProvider differenceGroupProvider) {
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_GROUP, differenceGroupProvider);
}
/**
@@ -211,7 +285,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
editingDomain.getCommandStack().addCommandStackListener(this);
- compareInputChanged(compareResult);
+ compareInputChanged(scope, compareResult);
}
} else {
ResourceSet leftResourceSet = null;
@@ -261,6 +335,8 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
unload(originResourceSet);
getCompareConfiguration().setProperty(EMFCompareConstants.COMPARE_RESULT, null);
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_FILTERS, null);
+ getCompareConfiguration().setProperty(EMFCompareConstants.SELECTED_GROUP, null);
fRoot = null;
}
}
@@ -270,7 +346,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
EMFCompareConstants.EDITING_DOMAIN);
editingDomain.getCommandStack().addCommandStackListener(this);
- compareInputChanged(input.getTarget());
+ compareInputChanged(null, input.getTarget());
}
void compareInputChanged(ComparisonScopeInput input, IProgressMonitor monitor) {
@@ -282,7 +358,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
EMFCompareConstants.COMPARATOR);
Comparison comparison = comparator.compare(input.getComparisonScope(), BasicMonitor
.toMonitor(monitor));
- compareInputChanged(comparison);
+ compareInputChanged(null, comparison);
}
private static void unload(ResourceSet resourceSet) {
@@ -304,9 +380,11 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
return null;
}
- void compareInputChanged(final Comparison comparison) {
+ void compareInputChanged(final IComparisonScope scope, final Comparison comparison) {
+ fRoot = fAdapterFactory.adapt(comparison, ICompareInput.class);
+ groupActionMenu.createActions(scope, comparison);
+ filterActionMenu.createActions(scope, comparison);
getCompareConfiguration().setProperty(EMFCompareConstants.COMPARE_RESULT, comparison);
- fRoot = fAdapterFactory.adapt(comparison, IDiffElement.class);
getCompareConfiguration().getContainer().runAsynchronously(new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
@@ -360,44 +438,92 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
@Override
protected void createToolItems(ToolBarManager toolbarManager) {
super.createToolItems(toolbarManager);
-
+ groupActionMenu = new GroupActionMenu(getStructureMergeViewerGrouper(), getGroupsMenuManager(),
+ getDefaultGroupProvider());
+ filterActionMenu = new FilterActionMenu(getStructureMergeViewerFilter(), getFiltersMenuManager());
toolbarManager.add(new SaveComparisonModelAction(getCompareConfiguration()));
- toolbarManager.add(new GroupActionMenu(getDifferenceGrouper()));
- toolbarManager.add(new FilterActionMenu(getDifferenceFilter()));
+ toolbarManager.add(groupActionMenu);
+ toolbarManager.add(filterActionMenu);
}
/**
- * Returns the difference filter that is to be applied on the structure viewer.
+ * Returns the viewer filter that is to be applied on the structure viewer.
* <p>
* Note that this will be called from {@link #createToolItems(ToolBarManager)}, which is called from the
- * super-constructor, when we have had no time to initialize the {@link #differenceFilter} field.
+ * super-constructor, when we have had no time to initialize the {@link #structureMergeViewerFilter}
+ * field.
* </p>
*
* @return The difference filter that is to be applied on the structure viewer.
*/
- protected DifferenceFilter getDifferenceFilter() {
- if (differenceFilter == null) {
- differenceFilter = new DifferenceFilter();
- differenceFilter.install(this);
+ protected StructureMergeViewerFilter getStructureMergeViewerFilter() {
+ if (structureMergeViewerFilter == null) {
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ structureMergeViewerFilter = new StructureMergeViewerFilter(eventBus);
+ structureMergeViewerFilter.install(this);
}
- return differenceFilter;
+ return structureMergeViewerFilter;
}
/**
- * Returns the difference grouper that is to be applied on the structure viewer.
+ * Returns the viewer grouper that is to be applied on the structure viewer.
* <p>
* Note that this will be called from {@link #createToolItems(ToolBarManager)}, which is called from the
- * super-constructor, when we have had no time to initialize the {@link #differenceGrouper} field.
+ * super-constructor, when we have had no time to initialize the {@link #structureMergeViewerGrouper}
+ * field.
* </p>
*
- * @return The difference grouper that is to be applied on the structure viewer.
+ * @return The viewer grouper grouper that is to be applied on the structure viewer.
*/
- protected DifferenceGrouper getDifferenceGrouper() {
- if (differenceGrouper == null) {
- differenceGrouper = new DifferenceGrouper();
- differenceGrouper.install(this);
+ protected StructureMergeViewerGrouper getStructureMergeViewerGrouper() {
+ if (structureMergeViewerGrouper == null) {
+ if (eventBus == null) {
+ eventBus = new EventBus();
+ eventBus.register(this);
+ }
+ structureMergeViewerGrouper = new StructureMergeViewerGrouper(eventBus);
+ structureMergeViewerGrouper.install(this);
}
- return differenceGrouper;
+ return structureMergeViewerGrouper;
+ }
+
+ /**
+ * Returns the menu manager that is to be applied to groups on the structure viewer.
+ *
+ * @return The menu manager that is to be applied to groups on the structure viewer.
+ */
+ public MenuManager getGroupsMenuManager() {
+ if (groupsMenuManager == null) {
+ groupsMenuManager = new MenuManager();
+ }
+ return groupsMenuManager;
+ }
+
+ /**
+ * Returns the menu manager that is to be applied to filters on the structure viewer.
+ *
+ * @return The menu manager that is to be applied to filters on the structure viewer.
+ */
+ public MenuManager getFiltersMenuManager() {
+ if (filtersMenuManager == null) {
+ filtersMenuManager = new MenuManager();
+ }
+ return filtersMenuManager;
+ }
+
+ /**
+ * Returns the default group provider that is to be applied on the structure viewer.
+ *
+ * @return The default group provider that is to be applied on the structure viewer.
+ */
+ public DefaultGroupProvider getDefaultGroupProvider() {
+ if (defaultGroupProvider == null) {
+ defaultGroupProvider = new DefaultGroupProvider();
+ }
+ return defaultGroupProvider;
}
/**
@@ -453,7 +579,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
if (!affectedObjects.isEmpty()) {
List<Object> adaptedAffectedObject = newArrayList();
for (Object affectedObject : affectedObjects) {
- adaptedAffectedObject.add(fAdapterFactory.adapt(affectedObject, IDiffElement.class));
+ adaptedAffectedObject.add(fAdapterFactory.adapt(affectedObject, ICompareInput.class));
}
setSelection(new StructuredSelection(adaptedAffectedObject), true);
}
@@ -461,4 +587,67 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
// FIXME, should recompute the difference, something happened outside of this compare editor
}
}
+
+ /**
+ * Use our own {@link ViewerComparator} in order to manage {@link IStyledLabelProvider} and
+ * {@link DelegatingStyledCellLabelProvider} cases.
+ */
+ private static class EMFCompareStructureMergeViewerComparator extends ViewerComparator {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer,
+ * java.lang.Object, java.lang.Object)
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ int cat1 = category(e1);
+ int cat2 = category(e2);
+
+ if (cat1 != cat2) {
+ return cat1 - cat2;
+ }
+
+ String name1 = getLabel(viewer, e1);
+ String name2 = getLabel(viewer, e2);
+
+ // use the comparator to compare the strings
+ return getComparator().compare(name1, name2);
+ }
+
+ /**
+ * Returns the appropriate label of the given object based on the label provider of the given viewer.
+ *
+ * @param viewer
+ * The given {@link Viewer}.
+ * @param e1
+ * The given object for which we want the label.
+ * @return The appropriate label based on the label provider of the given viewer.
+ */
+ private String getLabel(Viewer viewer, Object e1) {
+ String name1;
+ if (viewer == null || !(viewer instanceof ContentViewer)) {
+ name1 = e1.toString();
+ } else {
+ IBaseLabelProvider prov = ((ContentViewer)viewer).getLabelProvider();
+ if (prov instanceof ILabelProvider) {
+ ILabelProvider lprov = (ILabelProvider)prov;
+ name1 = lprov.getText(e1);
+ } else if (prov instanceof IStyledLabelProvider) {
+ name1 = ((IStyledLabelProvider)prov).getStyledText(e1).getString();
+ } else if (prov instanceof DelegatingStyledCellLabelProvider) {
+ name1 = ((DelegatingStyledCellLabelProvider)prov).getStyledStringProvider()
+ .getStyledText(e1).getString();
+ } else {
+ name1 = e1.toString();
+ }
+ }
+ if (name1 == null) {
+ name1 = "";//$NON-NLS-1$
+ }
+ return name1;
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
index 479f777cf..562b32a00 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerContentProvider.java
@@ -10,46 +10,41 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer;
+import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.isEmpty;
import static com.google.common.collect.Iterables.toArray;
-import static org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffContainer.adapt;
+import static com.google.common.collect.Iterables.transform;
+import com.google.common.base.Function;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
-import org.eclipse.compare.structuremergeviewer.IDiffContainer;
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGrouper;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ComparisonNode;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
-class EMFCompareStructureMergeViewerContentProvider implements ITreeContentProvider {
+class EMFCompareStructureMergeViewerContentProvider extends AdapterFactoryContentProvider {
- private final DifferenceGrouper fDifferenceGrouper;
-
- private final AdapterFactory fAdapterFactory;
+ private final StructureMergeViewerGrouper fViewerGrouper;
EMFCompareStructureMergeViewerContentProvider(AdapterFactory adapterFactory,
- DifferenceGrouper differenceGrouper) {
- this.fAdapterFactory = adapterFactory;
- this.fDifferenceGrouper = differenceGrouper;
- }
-
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- // empty implementation
- }
-
- public void dispose() {
+ StructureMergeViewerGrouper structureMergeViewerGrouper) {
+ super(adapterFactory);
+ this.fViewerGrouper = structureMergeViewerGrouper;
}
+ @Override
public Object getParent(Object element) {
final Object ret;
- if (element instanceof IDiffElement) {
- ret = ((IDiffElement)element).getParent();
+ if (element instanceof Adapter) {
+ ret = getAdapterFactory().adapt(super.getParent(((Adapter)element).getTarget()),
+ ICompareInput.class);
} else if (element instanceof DifferenceGroup) {
ret = ((DifferenceGroup)element).getComparison();
} else {
@@ -58,57 +53,85 @@ class EMFCompareStructureMergeViewerContentProvider implements ITreeContentProvi
return ret;
}
+ @Override
public final boolean hasChildren(Object element) {
final boolean ret;
if (element instanceof ComparisonNode) {
Comparison target = ((ComparisonNode)element).getTarget();
- final Iterable<? extends DifferenceGroup> groups = fDifferenceGrouper.getGroups(target);
+ final Iterable<? extends DifferenceGroup> groups = fViewerGrouper.getGroups(target);
if (isEmpty(groups)) {
- ret = doHasChildren((ComparisonNode)element);
+ ret = super.hasChildren(((Adapter)element).getTarget());
} else {
ret = true;
}
- } else if (element instanceof IDiffContainer) {
- ret = doHasChildren((IDiffContainer)element);
} else if (element instanceof DifferenceGroup) {
ret = !isEmpty(((DifferenceGroup)element).getDifferences());
+ } else if (element instanceof Adapter) {
+ ret = super.hasChildren(((Adapter)element).getTarget());
} else {
ret = false;
}
return ret;
}
- private boolean doHasChildren(IDiffContainer element) {
- return element.hasChildren();
- }
-
+ @Override
public final Object[] getChildren(Object element) {
final Object[] ret;
if (element instanceof ComparisonNode) {
Comparison target = ((ComparisonNode)element).getTarget();
- final Iterable<? extends DifferenceGroup> groups = fDifferenceGrouper.getGroups(target);
+ final Iterable<? extends DifferenceGroup> groups = fViewerGrouper.getGroups(target);
if (!isEmpty(groups)) {
ret = Iterables.toArray(groups, DifferenceGroup.class);
} else {
- ret = doGetChildren((IDiffContainer)element);
+ Iterable<ICompareInput> compareInputs = adapt(super.getChildren(((Adapter)element)
+ .getTarget()), getAdapterFactory(), ICompareInput.class);
+ ret = toArray(compareInputs, ICompareInput.class);
}
- } else if (element instanceof IDiffContainer) {
- ret = doGetChildren((IDiffContainer)element);
} else if (element instanceof DifferenceGroup) {
Iterable<? extends Diff> differences = ((DifferenceGroup)element).getDifferences();
- Iterable<IDiffElement> diffNodes = adapt(differences, fAdapterFactory, IDiffElement.class);
- ret = toArray(diffNodes, IDiffElement.class);
+ Iterable<ICompareInput> compareInputs = adapt(differences, getAdapterFactory(),
+ ICompareInput.class);
+ ret = toArray(compareInputs, ICompareInput.class);
+ } else if (element instanceof Adapter) {
+ Iterable<ICompareInput> compareInputs = adapt(super.getChildren(((Adapter)element).getTarget()),
+ getAdapterFactory(), ICompareInput.class);
+ ret = toArray(compareInputs, ICompareInput.class);
} else {
ret = new Object[0];
}
return ret;
}
- private Object[] doGetChildren(IDiffContainer diffContainer) {
- return diffContainer.getChildren();
- }
-
+ @Override
public Object[] getElements(Object element) {
return getChildren(element);
}
+
+ /**
+ * Adapts each elements of the the given <code>iterable</code> to the given <code>type</code> by using the
+ * given <code>adapterFactory</code>.
+ *
+ * @param <T>
+ * the type of returned elements.
+ * @param iterable
+ * the iterable to transform.
+ * @param adapterFactory
+ * the {@link AdapterFactory} used to adapt elements
+ * @param type
+ * the target type of adapted elements
+ * @return an iterable with element of type <code>type</code>.
+ */
+ static <T> Iterable<T> adapt(Iterable<?> iterable, final AdapterFactory adapterFactory,
+ final Class<T> type) {
+ Function<Object, Object> adaptFunction = new Function<Object, Object>() {
+ public Object apply(Object input) {
+ return adapterFactory.adapt(input, type);
+ }
+ };
+ return filter(transform(iterable, adaptFunction), type);
+ }
+
+ static <T> Iterable<T> adapt(Object[] iterable, final AdapterFactory adapterFactory, final Class<T> type) {
+ return adapt(Lists.newArrayList(iterable), adapterFactory, type);
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
index ddb2d0274..a6d58f446 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewerLabelProvider.java
@@ -1,131 +1,149 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.structuremergeviewer;
-
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
-import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.DiffNode;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ImageProvider;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.MatchNode;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareCompositeImageDescriptor;
-import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-
-class EMFCompareStructureMergeViewerLabelProvider extends AdapterFactoryLabelProvider.FontAndColorProvider {
-
- private final boolean fLeftIsLocal;
-
- private final ImageProvider imgProvider;
-
- /**
- * @param adapterFactory
- */
- public EMFCompareStructureMergeViewerLabelProvider(AdapterFactory adapterFactory, Viewer viewer,
- boolean leftIsLocal) {
- super(adapterFactory, viewer);
- fLeftIsLocal = leftIsLocal;
- imgProvider = new ImageProvider(fLeftIsLocal);
- }
-
- @Override
- public String getText(Object element) {
- final String ret;
- if (element instanceof IDiffElement) {
- ret = ((IDiffElement)element).getName();
- } else if (element instanceof DifferenceGroup) {
- ret = ((DifferenceGroup)element).getName();
- } else {
- ret = super.getText(element);
- }
- return ret;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object)
- */
- @Override
- public Font getFont(Object object) {
- if (object instanceof AbstractEDiffElement) {
- return super.getFont(((AbstractEDiffElement)object).getTarget());
- }
- return super.getFont(object);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getForeground(java.lang.Object)
- */
- @Override
- public Color getForeground(Object object) {
- if (object instanceof AbstractEDiffElement) {
- return super.getForeground(((AbstractEDiffElement)object).getTarget());
- }
- return super.getForeground(object);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getBackground(java.lang.Object)
- */
- @Override
- public Color getBackground(Object object) {
- if (object instanceof AbstractEDiffElement) {
- return super.getBackground(((AbstractEDiffElement)object).getTarget());
- }
- return super.getBackground(object);
- }
-
- @Override
- public Image getImage(Object element) {
- final Image ret;
- if (element instanceof DiffNode) {
- Diff target = ((DiffNode)element).getTarget();
- ImageDescriptor overlay = imgProvider.getImageDescriptorOverlay(target);
- Image base = super.getImage(target);
- EMFCompareCompositeImageDescriptor descriptor = new EMFCompareCompositeImageDescriptor(base,
- overlay, EMFCompareConstants.COMPARE_IMAGE_WIDTH, !fLeftIsLocal);
- ret = EMFCompareIDEUIPlugin.getDefault().getImage(descriptor);
- } else if (element instanceof MatchNode) {
- Match target = ((MatchNode)element).getTarget();
- ImageDescriptor overlay = imgProvider.getImageDescriptorOverlay(target);
- Image base = super.getImage(target);
- EMFCompareCompositeImageDescriptor descriptor = new EMFCompareCompositeImageDescriptor(base,
- overlay, EMFCompareConstants.COMPARE_IMAGE_WIDTH, !fLeftIsLocal);
- ret = EMFCompareIDEUIPlugin.getDefault().getImage(descriptor);
- } else if (element instanceof AbstractEDiffElement) {
- ret = ((AbstractEDiffElement)element).getImage();
- } else if (element instanceof DifferenceGroup) {
- final Image groupImage = ((DifferenceGroup)element).getImage();
- if (groupImage != null) {
- ret = groupImage;
- } else {
- ret = EMFCompareIDEUIPlugin.getDefault().getImage("icons/full/toolb16/group.gif"); //$NON-NLS-1$
- }
- } else {
- ret = super.getImage(element);
- }
-
- return ret;
- }
-}
+/*******************************************************************************
+ * 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.ide.ui.internal.structuremergeviewer;
+
+import com.google.common.base.Preconditions;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.compare.ide.ui.internal.util.StyledStringConverter;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+class EMFCompareStructureMergeViewerLabelProvider extends AdapterFactoryLabelProvider.FontAndColorProvider implements IStyledLabelProvider {
+
+ /**
+ * @param adapterFactory
+ */
+ public EMFCompareStructureMergeViewerLabelProvider(AdapterFactory adapterFactory, Viewer viewer) {
+ super(adapterFactory, viewer);
+ }
+
+ @Override
+ public String getText(Object element) {
+ return getStyledText(element).getString();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getFont(java.lang.Object)
+ */
+ @Override
+ public Font getFont(Object object) {
+ if (object instanceof Adapter) {
+ return super.getFont(((Adapter)object).getTarget());
+ }
+ return super.getFont(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getForeground(java.lang.Object)
+ */
+ @Override
+ public Color getForeground(Object object) {
+ if (object instanceof Adapter) {
+ return super.getForeground(((Adapter)object).getTarget());
+ }
+ return super.getForeground(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider#getBackground(java.lang.Object)
+ */
+ @Override
+ public Color getBackground(Object object) {
+ if (object instanceof Adapter) {
+ return super.getBackground(((Adapter)object).getTarget());
+ }
+ return super.getBackground(object);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ final Image ret;
+ if (element instanceof Adapter) {
+ ret = super.getImage(((Adapter)element).getTarget());
+ } else if (element instanceof DifferenceGroup) {
+ final Image groupImage = ((DifferenceGroup)element).getImage();
+ if (groupImage != null) {
+ ret = groupImage;
+ } else {
+ ret = EMFCompareRCPUIPlugin.getImage("icons/full/toolb16/group.gif"); //$NON-NLS-1$
+ }
+ } else {
+ ret = super.getImage(element);
+ }
+
+ return ret;
+ }
+
+ public StyledString getStyledText(Object element) {
+ final StyledString ret;
+ if (element instanceof Adapter) {
+ Notifier target = ((Adapter)element).getTarget();
+ StyledString styledText = getStyledText(getAdapterFactory(), target);
+ if (styledText == null) {
+ ret = new StyledString(super.getText(target));
+ } else {
+ ret = styledText;
+ }
+ } else if (element instanceof DifferenceGroup) {
+ ret = new StyledString(((DifferenceGroup)element).getName());
+ } else {
+ ret = new StyledString(super.getText(element));
+ }
+ return ret;
+
+ }
+
+ /**
+ * Returns the styled text string of the given <code>object</code> by adapting it to
+ * {@link IItemStyledLabelProvider} and asking for its
+ * {@link IItemStyledLabelProvider#getStyledText(Object) text}. Returns null if <code>object</code> is
+ * null.
+ *
+ * @param adapterFactory
+ * the adapter factory to adapt from
+ * @param object
+ * the object from which we want a text
+ * @return the text, or null if object is null.
+ * @throws NullPointerException
+ * if <code>adapterFactory</code> is null.
+ */
+ private static StyledString getStyledText(final AdapterFactory adapterFactory, final Object object) {
+ Preconditions.checkNotNull(adapterFactory);
+ if (object == null) {
+ return null;
+ }
+
+ Object itemStyledLabelProvider = adapterFactory.adapt(object, IItemStyledLabelProvider.class);
+ if (itemStyledLabelProvider instanceof IItemStyledLabelProvider) {
+ StyledStringConverter stringConverter = new StyledStringConverter();
+ return stringConverter.toJFaceStyledString(((IItemStyledLabelProvider)itemStyledLabelProvider)
+ .getStyledText(object));
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/AttributeChangeNode.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/AttributeChangeNode.java
index 1b9c758ad..8e2e01d19 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/AttributeChangeNode.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/AttributeChangeNode.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;
-import org.eclipse.compare.ITypedElement;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.AttributeChange;
@@ -40,14 +39,4 @@ public class AttributeChangeNode extends DiffNode {
public AttributeChange getTarget() {
return (AttributeChange)super.getTarget();
}
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffElement#getType()
- */
- @Override
- public String getType() {
- return ITypedElement.TEXT_TYPE;
- }
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/CompareNodeAdapterFactory.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/CompareNodeAdapterFactory.java
index b30a27c73..1ed9c125c 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/CompareNodeAdapterFactory.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/CompareNodeAdapterFactory.java
@@ -14,10 +14,7 @@ import static com.google.common.collect.Lists.newArrayList;
import java.util.Collection;
-import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
-import org.eclipse.compare.structuremergeviewer.IDiffContainer;
-import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
@@ -54,9 +51,6 @@ public class CompareNodeAdapterFactory extends CompareAdapterFactory implements
/**
* Creates an {@link ComposeableAdapterFactory} with the following supported types:
* <ul>
- * <li>{@link IDiffElement}</li>,
- * <li>{@link IDiffContainer}</li>,
- * <li>{@link ITypedElement}</li>,
* <li>{@link ICompareInput}</li>.
* </ul>
*
@@ -64,9 +58,6 @@ public class CompareNodeAdapterFactory extends CompareAdapterFactory implements
* This will be used by the comparison adapter to group differences together.
*/
public CompareNodeAdapterFactory() {
- supportedTypes.add(IDiffElement.class);
- supportedTypes.add(IDiffContainer.class);
- supportedTypes.add(ITypedElement.class);
supportedTypes.add(ICompareInput.class);
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/ConflictNode.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/ConflictNode.java
index 2c638cab0..e9fcb0457 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/ConflictNode.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/ConflictNode.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider;
-import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffNode;
@@ -41,14 +40,4 @@ public class ConflictNode extends AbstractEDiffNode {
public Conflict getTarget() {
return (Conflict)super.getTarget();
}
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffElement#getKind()
- */
- @Override
- public int getKind() {
- return Differencer.CONFLICTING;
- }
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/MatchNode.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/MatchNode.java
index 3e6783fae..b3293ce2f 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/MatchNode.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/provider/MatchNode.java
@@ -23,7 +23,6 @@ import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.accessor.ContentMergeViewerConstants;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffNode;
import org.eclipse.emf.ecore.EObject;
@@ -84,16 +83,6 @@ public class MatchNode extends AbstractEDiffNode {
/**
* {@inheritDoc}
*
- * @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffElement#getType()
- */
- @Override
- public String getType() {
- return ContentMergeViewerConstants.EOBJECT_NODE_TYPE;
- }
-
- /**
- * {@inheritDoc}
- *
* @see org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.AbstractEDiffElement#getKind()
*/
@Override
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/StyledStringConverter.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/StyledStringConverter.java
new file mode 100644
index 000000000..4e7601eda
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/StyledStringConverter.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.ide.ui.internal.util;
+
+import org.eclipse.emf.common.util.URI;
+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.provider.utils.IStyledString.Style.UnderLineStyle;
+import org.eclipse.emf.edit.ui.provider.ExtendedColorRegistry;
+import org.eclipse.emf.edit.ui.provider.ExtendedFontRegistry;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.StyledString.Styler;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.TextStyle;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class StyledStringConverter {
+
+ public StyledStringConverter() {
+
+ }
+
+ public StyledString toJFaceStyledString(IComposedStyledString composedStyledString) {
+ StyledString ret = new StyledString();
+ for (IStyledString styledString : composedStyledString) {
+ Style style = styledString.getStyle();
+ String str = styledString.getString();
+ if (style == IStyledString.Style.NO_STYLE) {
+ ret.append(str);
+ } else if (style == IStyledString.Style.COUNTER_STYLER) {
+ ret.append(str, StyledString.COUNTER_STYLER);
+ } else if (style == IStyledString.Style.DECORATIONS_STYLER) {
+ ret.append(str, StyledString.DECORATIONS_STYLER);
+ } else if (style == IStyledString.Style.QUALIFIER_STYLER) {
+ ret.append(str, StyledString.QUALIFIER_STYLER);
+ } else {
+ ret.append(str, toJFaceStyle(style));
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * @param style
+ * @return
+ */
+ private Styler toJFaceStyle(final Style style) {
+ return new Styler() {
+ @Override
+ public void applyStyles(TextStyle textStyle) {
+ textStyle.font = getFont(style.getFont());
+
+ textStyle.background = getColor(style.getBackgoundColor());
+ textStyle.foreground = getColor(style.getForegroundColor());
+
+ textStyle.strikeout = style.isStrikedout();
+ textStyle.strikeoutColor = getColor(style.getStrikeoutColor());
+
+ textStyle.borderColor = getColor(style.getBorderColor());
+ switch (style.getBorderStyle()) {
+ case SOLID:
+ textStyle.borderStyle = SWT.BORDER_SOLID;
+ break;
+ case DOT:
+ textStyle.borderStyle = SWT.BORDER_DOT;
+ break;
+ case DASH:
+ textStyle.borderStyle = SWT.BORDER_DASH;
+ break;
+ case NONE:
+ textStyle.borderStyle = SWT.NONE;
+ break;
+ }
+
+ if (style.getUnderlineStyle() != UnderLineStyle.NONE) {
+ textStyle.underline = true;
+ textStyle.underlineColor = getColor(style.getUnderlineColor());
+ switch (style.getUnderlineStyle()) {
+ case SINGLE:
+ textStyle.underlineStyle = SWT.UNDERLINE_SINGLE;
+ break;
+ case DOUBLE:
+ textStyle.underlineStyle = SWT.UNDERLINE_DOUBLE;
+ break;
+ case ERROR:
+ textStyle.underlineStyle = SWT.UNDERLINE_ERROR;
+ break;
+ case LINK:
+ textStyle.underlineStyle = SWT.UNDERLINE_LINK;
+ break;
+ case SQUIGGLE:
+ textStyle.underlineStyle = SWT.UNDERLINE_SQUIGGLE;
+ break;
+ }
+ }
+ }
+ };
+ }
+
+ private static Color getColor(URI colorURI) {
+ return ExtendedColorRegistry.INSTANCE.getColor(null, null, colorURI);
+ }
+
+ private static Font getFont(URI fontURI) {
+ return ExtendedFontRegistry.INSTANCE.getFont(null, fontURI);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide/plugin.xml b/plugins/org.eclipse.emf.compare.ide/plugin.xml
index 50819e738..a86b75aef 100644
--- a/plugins/org.eclipse.emf.compare.ide/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.ide/plugin.xml
@@ -15,4 +15,27 @@
<plugin>
<extension-point id="org.eclipse.emf.compare.postProcessor" name="Post Processor" schema="schema/PostProcess.exsd"/>
<extension-point id="load_on_demand_policy" name="Load on Demand Policy" schema="schema/load_on_demand_policy.exsd"/>
+ <extension-point id="mergerExtension" name="Merger Extension" schema="schema/MergerExtension.exsd"/>
+
+ <extension point="org.eclipse.emf.ecore.generated_package">
+ <package
+ uri="http://www.eclipse.org/emf/compare"
+ class="org.eclipse.emf.compare.ComparePackage"
+ genModel="model/compare.genmodel"/>
+ </extension>
+ <extension
+ point="org.eclipse.emf.compare.ide.mergerExtension">
+ <merger
+ class="org.eclipse.emf.compare.merge.ResourceAttachmentChangeMerger"
+ ranking="10">
+ </merger>
+ <merger
+ class="org.eclipse.emf.compare.merge.ReferenceChangeMerger"
+ ranking="10">
+ </merger>
+ <merger
+ class="org.eclipse.emf.compare.merge.AttributeChangeMerger"
+ ranking="10">
+ </merger>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.compare.ide/schema/MergerExtension.exsd b/plugins/org.eclipse.emf.compare.ide/schema/MergerExtension.exsd
new file mode 100644
index 000000000..5391f784f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide/schema/MergerExtension.exsd
@@ -0,0 +1,129 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.compare.ide" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.emf.compare.ide" id="mergerExtension" name="Merger Extension"/>
+ </appinfo>
+ <documentation>
+ This can be used to provide your own mergers to either replace existing ones or implement mergers for custom differences.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="merger" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="merger">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.compare.merge.IMerger"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="ranking" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 3.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;extension point=&quot;org.eclipse.emf.compare.ide.mergerExtension&quot;&gt;
+ &lt;merger
+ class=&quot;org.eclipse.emf.compare.merge.ResourceAttachmentChangeMerger&quot;
+ ranking=&quot;10&quot;&gt;
+ &lt;/merger&gt;
+ &lt;merger
+ class=&quot;org.eclipse.emf.compare.merge.ReferenceChangeMerger&quot;
+ ranking=&quot;10&quot;&gt;
+ &lt;/merger&gt;
+ &lt;merger
+ class=&quot;org.eclipse.emf.compare.merge.AttributeChangeMerger&quot;
+ ranking=&quot;10&quot;&gt;
+ &lt;/merger&gt;
+&lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ See org.eclipse.emf.compare.ide/plugin.xml for existing contributions.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2011, 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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/EMFCompareIDEPlugin.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/EMFCompareIDEPlugin.java
index 74dad90f6..61cd9ec77 100644
--- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/EMFCompareIDEPlugin.java
+++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/EMFCompareIDEPlugin.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 Obeo.
+ * Copyright (c) 2011, 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
@@ -10,7 +10,10 @@
*******************************************************************************/
package org.eclipse.emf.compare.ide;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
@@ -20,6 +23,8 @@ import org.eclipse.emf.compare.ide.internal.policy.LoadOnDemandPolicyRegistryImp
import org.eclipse.emf.compare.ide.internal.policy.LoadOnDemandPolicyRegistryListener;
import org.eclipse.emf.compare.ide.policy.ILoadOnDemandPolicy;
import org.eclipse.emf.compare.ide.policy.ILoadOnDemandPolicy.Registry;
+import org.eclipse.emf.compare.ide.utils.AbstractRegistryEventListener;
+import org.eclipse.emf.compare.merge.IMerger;
import org.osgi.framework.BundleContext;
/**
@@ -34,6 +39,13 @@ public class EMFCompareIDEPlugin extends Plugin {
/** The id of the load on demand policy extension point. */
public static final String LOAD_ON_DEMAND_POLICY_PPID = "load_on_demand_policy"; //$NON-NLS-1$
+ /**
+ * The id of the merger extension point.
+ *
+ * @since 3.0
+ */
+ public static final String MERGER_EXTENSION_PPID = "mergerExtension"; //$NON-NLS-1$
+
/** This plugin's shared instance. */
private static EMFCompareIDEPlugin plugin;
@@ -51,6 +63,12 @@ public class EMFCompareIDEPlugin extends Plugin {
/** The registry listener that will be used to react to load on demand policy changes. */
private LoadOnDemandPolicyRegistryListener loadOnDemandRegistryListener;
+ /** The registry listener that will be used to react to merger extension changes. */
+ private AbstractRegistryEventListener mergerRegistryListener;
+
+ /** The registry that will hold references to all mergers. */
+ private IMerger.Registry mergerRegistry;
+
/**
* {@inheritDoc}
*
@@ -74,8 +92,14 @@ public class EMFCompareIDEPlugin extends Plugin {
this.loadOnDemandRegistryListener = new LoadOnDemandPolicyRegistryListener(loadOnDemandRegistry,
PLUGIN_ID, LOAD_ON_DEMAND_POLICY_PPID);
- registry.addListener(loadOnDemandRegistryListener, PLUGIN_ID + "." + LOAD_ON_DEMAND_POLICY_PPID);
+ registry.addListener(loadOnDemandRegistryListener, PLUGIN_ID + '.' + LOAD_ON_DEMAND_POLICY_PPID);
loadOnDemandRegistryListener.readRegistry(registry);
+
+ mergerRegistry = new IMerger.RegistryImpl();
+ mergerRegistryListener = new MergerExtensionRegistryListener(PLUGIN_ID, MERGER_EXTENSION_PPID);
+ registry.addListener(mergerRegistryListener, PLUGIN_ID + '.' + MERGER_EXTENSION_PPID);
+ mergerRegistryListener.readRegistry(registry);
+
}
/**
@@ -103,6 +127,16 @@ public class EMFCompareIDEPlugin extends Plugin {
}
/**
+ * Returns the merger registry to which extension will be registered.
+ *
+ * @return the merger registry to which extension will be registered
+ * @since 3.0
+ */
+ public IMerger.Registry getMergerRegistry() {
+ return mergerRegistry;
+ }
+
+ /**
* Log the given message with the given severity to the logger of this plugin.
*
* @param severity
@@ -131,4 +165,89 @@ public class EMFCompareIDEPlugin extends Plugin {
public static EMFCompareIDEPlugin getDefault() {
return plugin;
}
+
+ /**
+ * Listener for contributions to the merger extension.
+ */
+ private class MergerExtensionRegistryListener extends AbstractRegistryEventListener {
+
+ /** TAG_MERGER. */
+ static final String TAG_MERGER = "merger"; //$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$
+
+ /**
+ * Constructor.
+ *
+ * @param pluginID
+ * The plugin id.
+ * @param extensionPointID
+ * The extension point id.
+ */
+ public MergerExtensionRegistryListener(String pluginID, String extensionPointID) {
+ super(pluginID, extensionPointID);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.utils.AbstractRegistryEventListener#readElement(org.eclipse.core.runtime.IConfigurationElement,
+ * org.eclipse.emf.compare.ide.utils.AbstractRegistryEventListener.Action)
+ */
+ @Override
+ protected boolean readElement(IConfigurationElement element, Action b) {
+ if (element.getName().equals(TAG_MERGER)) {
+ if (element.getAttribute(ATT_CLASS) == null) {
+ logMissingAttribute(element, ATT_CLASS);
+ } else if (element.getAttribute(ATT_RANKING) == null) {
+ String rankingStr = element.getAttribute(ATT_RANKING);
+ try {
+ Integer.parseInt(rankingStr);
+ } catch (NumberFormatException nfe) {
+ logError(element, EMFCompareIDEMessages.getString("malformed.extension.attribute", //$NON-NLS-1$
+ ATT_RANKING));
+ }
+ logMissingAttribute(element, ATT_RANKING);
+ } else {
+ switch (b) {
+ case ADD:
+ try {
+ IMerger merger = (IMerger)element.createExecutableExtension(ATT_CLASS);
+ merger.setRanking(Integer.parseInt(element.getAttribute(ATT_RANKING)));
+ IMerger previous = mergerRegistry.add(merger);
+ if (previous != null) {
+ log(IStatus.WARNING, EMFCompareIDEMessages.getString(
+ "duplicate.extension", merger.getClass().getName())); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ logError(element, e.getMessage());
+ }
+ break;
+ case REMOVE:
+ mergerRegistry.remove(element.getAttribute(ATT_CLASS));
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.utils.AbstractRegistryEventListener#logError(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String)
+ */
+ @Override
+ protected void logError(IConfigurationElement element, String string) {
+ log(IStatus.ERROR, string);
+ }
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/emfcompareidemessages.properties b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/emfcompareidemessages.properties
index 1aa7f9dfd..84e35f0fd 100644
--- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/emfcompareidemessages.properties
+++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/emfcompareidemessages.properties
@@ -10,4 +10,7 @@
################################################################################
## note : apostrophes need to be doubled in these messages or they'll be ignored
synchronize.job.label = Querying EMF synchronization state
-storage.adapt.failure = Failed to retrieve an actual file revision for {0} \ No newline at end of file
+storage.adapt.failure = Failed to retrieve an actual file revision for {0}
+
+malformed.extension.attribute = Attribute {0} is malformed, should be an integer.
+duplicate.extension = The factory {0} is registered twice. \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java
index efdef520a..8f87e6ce1 100644
--- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java
+++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/NotLoadingResourceSet.java
@@ -26,9 +26,7 @@ import java.util.Set;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.compare.ide.EMFCompareIDEPlugin;
@@ -135,13 +133,35 @@ public final class NotLoadingResourceSet extends ResourceSetImpl {
while (resourceContent.hasNext()) {
final EObject eObject = resourceContent.next();
resolveCrossReferences(eObject);
- final TreeIterator<EObject> childContent = basicEAllContents(eObject);
- while (childContent.hasNext()) {
- final EObject child = childContent.next();
+ resolveChildren(eObject);
+ }
+ resource.getContents().addAll(roots);
+ }
+
+ /**
+ * Recursively resolve all children of the given EObject, including (but stopping at) any proxy.
+ *
+ * @param eObject
+ * The eObject which children we are to resolve.
+ */
+ private void resolveChildren(EObject eObject) {
+ final List<EObject> list = eObject.eContents();
+ final ListIterator<EObject> childContent = ((InternalEList<EObject>)list).basicListIterator();
+ while (childContent.hasNext()) {
+ final EObject child = childContent.next();
+ if (child.eIsProxy()) {
+ final URI proxyURI = ((InternalEObject)child).eProxyURI();
+ final Resource targetRes = getResource(proxyURI.trimFragment(), false);
+ if (targetRes != null) {
+ // resolve this one
+ list.get(childContent.previousIndex());
+ }
+ resolveCrossReferences(child);
+ } else {
resolveCrossReferences(child);
+ resolveChildren(child);
}
}
- resource.getContents().addAll(roots);
}
/**
@@ -165,28 +185,4 @@ public final class NotLoadingResourceSet extends ResourceSetImpl {
}
}
}
-
- /**
- * An implementation of {@link EObject#eAllContents()} that will not resolve its proxies.
- *
- * @param eObject
- * The eobject for which contents we need an iterator.
- * @return The created {@link TreeIterator}.
- */
- private TreeIterator<EObject> basicEAllContents(final EObject eObject) {
- return new AbstractTreeIterator<EObject>(eObject, false) {
- /** Generated SUID. */
- private static final long serialVersionUID = 6874121606163401152L;
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.util.AbstractTreeIterator#getChildren(java.lang.Object)
- */
- @Override
- public Iterator<EObject> getChildren(Object obj) {
- return ((InternalEList<EObject>)((EObject)obj).eContents()).basicIterator();
- }
- };
- }
}
diff --git a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/SyncResourceSet.java b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/SyncResourceSet.java
index 0af8d8f37..2889275a2 100644
--- a/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/SyncResourceSet.java
+++ b/plugins/org.eclipse.emf.compare.ide/src/org/eclipse/emf/compare/ide/internal/utils/SyncResourceSet.java
@@ -355,7 +355,12 @@ public final class SyncResourceSet extends ResourceSetImpl {
final TreeIterator<EObject> childContent = basicEAllContents(eObject);
while (childContent.hasNext()) {
final EObject child = childContent.next();
- resolveCrossReferences(child);
+ if (child.eIsProxy()) {
+ final URI proxyURI = ((InternalEObject)child).eProxyURI();
+ getResource(proxyURI.trimFragment(), false);
+ } else {
+ resolveCrossReferences(child);
+ }
}
}
resource.getContents().addAll(roots);
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
index 0f4be9429..5cea7b380 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/META-INF/MANIFEST.MF
@@ -2,8 +2,8 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.emf.compare.rcp.ui;singleton:=true
-Bundle-Version: 2.1.0.qualifier
-Bundle-Activator: org.eclipse.emf.compare.rcp.ui.Activator
+Bundle-Version: 3.0.0.qualifier
+Bundle-Activator: org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin
Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
@@ -11,10 +11,14 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0",
org.eclipse.emf.edit.ui;bundle-version="2.5.0",
org.eclipse.emf.compare;bundle-version="2.0.1",
org.eclipse.emf.compare.edit;bundle-version="2.0.1",
- org.eclipse.ui,
org.eclipse.emf.ecore.xmi;bundle-version="2.5.0"
-Export-Package: org.eclipse.emf.compare.rcp.ui.mergeviewer,
- org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor
+Export-Package: org.eclipse.emf.compare.rcp.ui,
+ org.eclipse.emf.compare.rcp.ui.mergeviewer,
+ org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.actions,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters,
+ org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups
Import-Package: com.google.common.base;version="[10.0.0,11.0.0)",
com.google.common.cache;version="[10.0.0,11.0.0)",
- com.google.common.collect;version="[10.0.0,11.0.0)"
+ com.google.common.collect;version="[10.0.0,11.0.0)",
+ com.google.common.eventbus;version="[10.0.0,11.0.0)"
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/build.properties b/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
index 5ebcb2d4b..06dc0bb29 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/build.properties
@@ -1,7 +1,12 @@
-source.. = src/
-output.. = bin/
-bin.includes = META-INF/,\
- plugin.properties,\
- .,\
- about.html
-src.includes = about.html
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ plugin.properties,\
+ .,\
+ about.html,\
+ plugin.xml,\
+ icons/,\
+ schema/
+src.includes = about.html,\
+ icons/,\
+ schema/
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif
index 6fe6f0e10..6fe6f0e10 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/filter.gif
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/filter.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif
index 2e1e2b938..2e1e2b938 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/icons/full/toolb16/group.gif
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/icons/full/toolb16/group.gif
Binary files differ
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml
new file mode 100644
index 000000000..b76137a6a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/plugin.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+
+<!--
+ 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
+-->
+
+<plugin>
+ <extension-point id="groups" name="EMF Compare Groups" schema="schema/groups.exsd"/>
+ <extension-point id="filters" name="EMF Compare Filters" schema="schema/filters.exsd"/>
+ <extension
+ point="org.eclipse.emf.compare.rcp.ui.groups">
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.KindGroupProvider"
+ label="By Kind">
+ </group>
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.MetamodelGroupProvider"
+ label="By Metaclass">
+ </group>
+ <group
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.ThreeWayComparisonGroupProvider"
+ label="By Side">
+ </group>
+ </extension>
+ <extension
+ point="org.eclipse.emf.compare.rcp.ui.filters">
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.ChangedElementsFilter"
+ label="Changed elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.AddedElementsFilter"
+ label="Added elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.RemovedElementsFilter"
+ label="Removed elements">
+ </filter>
+ <filter
+ activeByDefault="false"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.MovedElementsFilter"
+ label="Moved elements">
+ </filter>
+ <filter
+ activeByDefault="true"
+ class="org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.EmptyMatchedResourcesFilter"
+ label="Empty Resource Mappings">
+ </filter>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml b/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
index c090d2591..5ccefac42 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>org.eclipse.emf.compare</groupId>
<artifactId>org.eclipse.emf.compare.rcp.ui</artifactId>
- <version>2.1.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd b/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd
new file mode 100644
index 000000000..01c561fa2
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/schema/filters.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.compare.rcp.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.emf.compare.rcp.ui" id="filters" name="EMF Compare Filters"/>
+ </appinfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="filter" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="filter">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionProvider.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.compare.ide.ui.internal.actions.filter.FilterActionProvider"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-readable label for this filter This will be displayed in the EMF Compare UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="activeByDefault" type="boolean" use="required">
+ <annotation>
+ <documentation>
+ The initial activation state of the filter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd b/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd
new file mode 100644
index 000000000..0a8b45fe5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/schema/groups.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.emf.compare.rcp.ui" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.emf.compare.rcp.ui" id="groups" name="EMF Compare Groups"/>
+ </appinfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="group" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="group">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="activeByDefault" type="boolean" use="required">
+ <annotation>
+ <documentation>
+ The initial activation state of the filter.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java
deleted file mode 100644
index f57c07fb2..000000000
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/Activator.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/** ****************************************************************************
- * Copyright (c) 2012 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;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle.
- */
-public class Activator extends AbstractUIPlugin {
-
- /**
- * The plug-in ID.
- */
- public static final String PLUGIN_ID = "org.eclipse.emf.compare.rcp.ui"; //$NON-NLS-1$
-
- /**
- * the shared instance.
- */
- private static Activator plugin;
-
- /** keep track of resources that should be freed when exiting. */
- private static Map<String, Image> resourcesMapper = new HashMap<String, Image>();
-
- /**
- * The constructor.
- */
- public Activator() {
-
- }
-
- /*
- * (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;
- }
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
- */
- @Override
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- disposeCachedImages();
- super.stop(context);
- }
-
- /**
- * Returns the shared instance.
- *
- * @return the shared instance
- */
- public static Activator getDefault() {
- return plugin;
- }
-
- /**
- * <p>
- * returns a plugin image. The returned image does not need to be explicitly disposed.
- * </p>
- *
- * @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;
- }
-
- /**
- * <p>
- * returns a plugin image descriptor.
- * </p>
- *
- * @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<Image> iterator = resourcesMapper.values().iterator();
- while (iterator.hasNext()) {
- iterator.next().dispose();
- }
- resourcesMapper.clear();
- }
-
-}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java
new file mode 100644
index 000000000..47c18313c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/EMFCompareRCPUIPlugin.java
@@ -0,0 +1,365 @@
+/** ****************************************************************************
+ * 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;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+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.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+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$
+
+ /**
+ * the shared instance.
+ */
+ private static EMFCompareRCPUIPlugin plugin;
+
+ /** keep track of resources that should be freed when exiting. */
+ private static Map<String, Image> resourcesMapper = new HashMap<String, Image>();
+
+ private AbstractRegistryEventListener groupProviderRegistryListener;
+
+ private IDifferenceGroupProvider.Registry groupProviderRegistry;
+
+ private AbstractRegistryEventListener filterRegistryListener;
+
+ private IDifferenceFilter.Registry filterRegistry;
+
+ /**
+ * 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();
+
+ groupProviderRegistry = new IDifferenceGroupProvider.RegistryImpl();
+
+ groupProviderRegistryListener = new DifferenceGroupProviderExtensionRegistryListener(PLUGIN_ID,
+ GROUP_PROVIDER_PPID);
+ extensionRegistry.addListener(groupProviderRegistryListener, PLUGIN_ID + "." + GROUP_PROVIDER_PPID); //$NON-NLS-1$
+ groupProviderRegistryListener.readRegistry(extensionRegistry);
+
+ filterRegistry = new IDifferenceFilter.RegistryImpl();
+
+ filterRegistryListener = new FilterExtensionRegistryListener(PLUGIN_ID, FILTER_PROVIDER_PPID);
+ extensionRegistry.addListener(filterRegistryListener, PLUGIN_ID + "." + FILTER_PROVIDER_PPID); //$NON-NLS-1$
+ filterRegistryListener.readRegistry(extensionRegistry);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ Platform.getExtensionRegistry().removeListener(filterRegistryListener);
+ filterRegistry = null;
+ Platform.getExtensionRegistry().removeListener(groupProviderRegistryListener);
+ 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
+ */
+ public IDifferenceGroupProvider.Registry getDifferenceGroupProviderRegistry() {
+ return groupProviderRegistry;
+ }
+
+ public IDifferenceFilter.Registry getFilterActionRegistry() {
+ return filterRegistry;
+ }
+
+ /**
+ * <p>
+ * returns a plugin image. The returned image does not need to be explicitly disposed.
+ * </p>
+ *
+ * @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;
+ }
+
+ /**
+ * <p>
+ * returns a plugin image descriptor.
+ * </p>
+ *
+ * @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<Image> iterator = resourcesMapper.values().iterator();
+ while (iterator.hasNext()) {
+ iterator.next().dispose();
+ }
+ resourcesMapper.clear();
+ }
+
+ private class DifferenceGroupProviderExtensionRegistryListener extends AbstractRegistryEventListener {
+
+ static final String TAG_GROUP_PROVIDER = "group"; //$NON-NLS-1$
+
+ static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ static final String ATT_LABEL = "label"; //$NON-NLS-1$
+
+ static final String ATT_ACTIVE = "activeByDefault"; //$NON-NLS-1$
+
+ /**
+ * @param pluginID
+ * @param extensionPointID
+ * @param registry
+ */
+ public DifferenceGroupProviderExtensionRegistryListener(String pluginID, String extensionPointID) {
+ super(pluginID, extensionPointID);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#readElement(org.eclipse.core.runtime.IConfigurationElement,
+ * org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener.Action)
+ */
+ @SuppressWarnings("boxing")
+ @Override
+ protected boolean readElement(IConfigurationElement element, Action b) {
+ if (element.getName().equals(TAG_GROUP_PROVIDER)) {
+ if (element.getAttribute(ATT_CLASS) == null) {
+ logMissingAttribute(element, ATT_CLASS);
+ } else if (element.getAttribute(ATT_LABEL) == null) {
+ logMissingAttribute(element, ATT_LABEL);
+ } else if (element.getAttribute(ATT_ACTIVE) == null) {
+ logMissingAttribute(element, ATT_ACTIVE);
+ } else {
+ switch (b) {
+ case ADD:
+ try {
+ IDifferenceGroupProvider provider = (IDifferenceGroupProvider)element
+ .createExecutableExtension(ATT_CLASS);
+ provider.setLabel(element.getAttribute(ATT_LABEL));
+ if (Boolean.valueOf(element.getAttribute(ATT_ACTIVE))) {
+ provider.setDefaultSelected(true);
+ } else {
+ provider.setDefaultSelected(false);
+ }
+ IDifferenceGroupProvider previous = groupProviderRegistry.add(provider);
+ if (previous != null) {
+ log(IStatus.WARNING, "The provider '" + provider.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ logError(element, e.getMessage());
+ }
+ break;
+ case REMOVE:
+ groupProviderRegistry.remove(element.getAttribute(ATT_CLASS));
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#logError(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String)
+ */
+ @Override
+ protected void logError(IConfigurationElement element, String string) {
+ log(IStatus.ERROR, string);
+ }
+ }
+
+ private class FilterExtensionRegistryListener extends AbstractRegistryEventListener {
+
+ static final String TAG_FILTER_ACTION = "filter"; //$NON-NLS-1$
+
+ static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ static final String ATT_LABEL = "label"; //$NON-NLS-1$
+
+ static final String ATT_ACTIVE = "activeByDefault"; //$NON-NLS-1$
+
+ /**
+ * @param pluginID
+ * @param extensionPointID
+ * @param registry
+ */
+ public FilterExtensionRegistryListener(String pluginID, String extensionPointID) {
+ super(pluginID, extensionPointID);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#readElement(org.eclipse.core.runtime.IConfigurationElement,
+ * org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener.Action)
+ */
+ @SuppressWarnings("boxing")
+ @Override
+ protected boolean readElement(IConfigurationElement element, Action b) {
+ if (element.getName().equals(TAG_FILTER_ACTION)) {
+ if (element.getAttribute(ATT_CLASS) == null) {
+ logMissingAttribute(element, ATT_CLASS);
+ } else if (element.getAttribute(ATT_LABEL) == null) {
+ logMissingAttribute(element, ATT_LABEL);
+ } else if (element.getAttribute(ATT_ACTIVE) == null) {
+ logMissingAttribute(element, ATT_ACTIVE);
+ } else {
+ switch (b) {
+ case ADD:
+ try {
+ IDifferenceFilter filter = (IDifferenceFilter)element
+ .createExecutableExtension(ATT_CLASS);
+ filter.setLabel(element.getAttribute(ATT_LABEL));
+ if (Boolean.valueOf(element.getAttribute(ATT_ACTIVE))) {
+ filter.setDefaultSelected(true);
+ } else {
+ filter.setDefaultSelected(false);
+ }
+ IDifferenceFilter previous = filterRegistry.add(filter);
+ if (previous != null) {
+ log(IStatus.WARNING, "The filter '" + filter.getClass().getName() //$NON-NLS-1$
+ + "' is registered twice."); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ logError(element, e.getMessage());
+ }
+ break;
+ case REMOVE:
+ filterRegistry.remove(element.getAttribute(ATT_CLASS));
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.internal.util.AbstractRegistryEventListener#logError(org.eclipse.core.runtime.IConfigurationElement,
+ * java.lang.String)
+ */
+ @Override
+ protected void logError(IConfigurationElement element, String string) {
+ log(IStatus.ERROR, string);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java
new file mode 100644
index 000000000..f46606c56
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/util/AbstractRegistryEventListener.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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 org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryEventListener;
+
+/**
+ * Abstract utility class to listen to the {@link IExtensionRegistry}. It provides base implementation to
+ * {@link #added(IExtension[])} and {@link #removed(IExtension[])}. Users must implement
+ * {@link #readElement(IConfigurationElement, Action)} according to their extension schema.
+ * <p>
+ * The helper method {@link #readRegistry()} is browsing already registered extension to the extension
+ * registry making it easy to read the registry after having added the listener to it.
+ * <p>
+ * {@link #readRegistry()} is delegating to {@link #readElement(IConfigurationElement, Action)}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class AbstractRegistryEventListener implements IRegistryEventListener {
+
+ /**
+ * Enumeration that says if the {@link IConfigurationElement} is to be added or removed from the
+ * {@link IExtensionRegistry}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ protected static enum Action {
+ /**
+ * The {@link IConfigurationElement} is to be added.
+ */
+ ADD,
+ /**
+ * The {@link IConfigurationElement} is to be removed.
+ */
+ REMOVE
+ }
+
+ /**
+ * The plugin ID which declare the extension point to be monitored.
+ */
+ private final String pluginID;
+
+ /**
+ * The extension point ID to be monitored.
+ */
+ private final String extensionPointID;
+
+ /**
+ * Creates a new registry event listener.
+ *
+ * @param pluginID
+ * The plugin ID which declare the extension point to be monitored.
+ * @param extensionPointID
+ * The extension point ID to be monitored
+ */
+ public AbstractRegistryEventListener(String pluginID, String extensionPointID) {
+ this.pluginID = pluginID;
+ this.extensionPointID = extensionPointID;
+ }
+
+ /**
+ * Reads the given registry and call {@link #readElement(IConfigurationElement, Action)} as the read
+ * {@link IConfigurationElement} were just added to it.
+ *
+ * @param extensionRegistry
+ * the registry to read.
+ */
+ public void readRegistry(IExtensionRegistry extensionRegistry) {
+ IExtensionPoint point = extensionRegistry.getExtensionPoint(pluginID, extensionPointID);
+ if (point != null) {
+ IConfigurationElement[] elements = point.getConfigurationElements();
+ for (int i = 0; i < elements.length; i++) {
+ internalReadElement(elements[i], Action.ADD);
+ }
+ }
+ }
+
+ /**
+ * Reads the given {@code element}. This method can be call when the element is added or remove. The
+ * {@code action} reflect it. It returns true if the element is recognized as valid regarding the
+ * monitored extension point. It will be call on sub elements recursively for all recognized ones.
+ *
+ * @param element
+ * the element to be read.
+ * @param action
+ * is the element added or removed.
+ * @return true if the element is recognized as valid regarding the monitored extension point.
+ */
+ protected abstract boolean readElement(IConfigurationElement element, Action action);
+
+ /**
+ * Reads the given element and, if recognized, browse recursively the children and try to read it.
+ *
+ * @param element
+ * the element to be read.
+ * @param action
+ * is the element added or removed.
+ */
+ private void internalReadElement(IConfigurationElement element, Action action) {
+ boolean recognized = readElement(element, action);
+ if (recognized) {
+ IConfigurationElement[] children = element.getChildren();
+ for (int i = 0; i < children.length; ++i) {
+ internalReadElement(children[i], action);
+ }
+ } else {
+ logError(element, "Error processing extension: " + element); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Delegates the logging of a missing attribute to {@link #logError(IConfigurationElement, String)} with a
+ * proper message.
+ *
+ * @param element
+ * the element to which an attribute is missing.
+ * @param attributeName
+ * the name of the missing attribute.
+ */
+ protected void logMissingAttribute(IConfigurationElement element, String attributeName) {
+ logError(element, "The required attribute '" + attributeName + "' not defined"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ /**
+ * Log the error to any mean (often the current plugin logger).
+ *
+ * @param element
+ * the element from which comes to the error.
+ * @param string
+ * the message to be logged.
+ */
+ protected abstract void logError(IConfigurationElement element, String string);
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtension[])
+ */
+ public void added(IExtension[] extensions) {
+ for (IExtension extension : extensions) {
+ if (extension.getExtensionPointUniqueIdentifier().equals(extensionPointID)) {
+ IConfigurationElement[] configurationElement = extension.getConfigurationElements();
+ for (int j = 0; j < configurationElement.length; ++j) {
+ internalReadElement(configurationElement[j], Action.ADD);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtension[])
+ */
+ public void removed(IExtension[] extensions) {
+ for (IExtension extension : extensions) {
+ if (extension.getExtensionPointUniqueIdentifier().equals(extensionPointID)) {
+ IConfigurationElement[] configurationElement = extension.getConfigurationElements();
+ for (int j = 0; j < configurationElement.length; ++j) {
+ internalReadElement(configurationElement[j], Action.REMOVE);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtensionPoint[])
+ */
+ public void added(IExtensionPoint[] extensionPoints) {
+ // no need to listen to this.
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtensionPoint[])
+ */
+ public void removed(IExtensionPoint[] extensionPoints) {
+ // no need to listen to this.
+ }
+
+ /**
+ * Simple utility class to create proxy of extension that are
+ * {@link IConfigurationElement#createExecutableExtension(String) instantiable}.
+ * <p>
+ * No test of the {@link IConfigurationElement#isValid() validity} of the wrapped
+ * {@link IConfigurationElement} is performed. As such you should always extend this class while listening
+ * to the {@link IExtensionRegistry} and react properly the removal of the wrapped
+ * {@link IConfigurationElement}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ public static class PluginClassDescriptor {
+ /**
+ * The element from which create an instance.
+ */
+ protected IConfigurationElement element;
+
+ /**
+ * The name of the attribute that holds the class full name to be instantiated.
+ */
+ protected String attributeName;
+
+ /**
+ * Creates a new descriptor for given element keeping the class name to be instantiated in an
+ * attribute named {@code attributeName}.
+ *
+ * @param element
+ * The element from which create an instance.
+ * @param attributeName
+ * The name of the attribute that holds the class full name to be instantiated.
+ */
+ public PluginClassDescriptor(IConfigurationElement element, String attributeName) {
+ this.element = element;
+ this.attributeName = attributeName;
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @return the new instance.
+ * @throws RuntimeException
+ * wraps a CoreException if an instance of the executable extension could not be created
+ * for any reason.
+ */
+ public Object createInstance() {
+ try {
+ return element.createExecutableExtension(attributeName);
+ } catch (CoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
index 188116623..ebd4bfbf1 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/MergeViewerInfoViewer.java
@@ -1,176 +1,192 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.jface.viewers.ContentViewer;
-import org.eclipse.jface.viewers.ILabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-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;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class MergeViewerInfoViewer extends ContentViewer {
-
- private final MergeViewerSide fSide;
-
- private final Composite fControl;
-
- private final Label fEObjectIcon;
-
- private final Label fEObjectLabel;
-
- private final Label fFeatureIcon;
-
- private final Label fFeatureLabel;
-
- private ISelection fSelection;
-
- private Object fInput;
-
- /**
- *
- */
- public MergeViewerInfoViewer(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 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);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
- */
- @Override
- public void setSelection(ISelection selection, boolean reveal) {
- fSelection = selection;
- }
-
-}
+/*******************************************************************************
+ * 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.mergeviewer;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ResourceContentsAccessorImpl;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jface.viewers.ContentViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+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;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class MergeViewerInfoViewer extends ContentViewer {
+
+ private final MergeViewerSide fSide;
+
+ private final Composite fControl;
+
+ private final Label fEObjectIcon;
+
+ private final Label fEObjectLabel;
+
+ private final Label fFeatureIcon;
+
+ private final Label fFeatureLabel;
+
+ private ISelection fSelection;
+
+ private Object fInput;
+
+ /**
+ *
+ */
+ public MergeViewerInfoViewer(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 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("resource contents"); //$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/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
index 3cff35862..0b3cdaa94 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/TableMergeViewer.java
@@ -1,310 +1,310 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor;
-import org.eclipse.jface.viewers.IBaseLabelProvider;
-import org.eclipse.jface.viewers.IContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.graphics.Region;
-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.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Widget;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class TableMergeViewer extends StructuredMergeViewer {
-
- private final ICompareColorProvider fColorProvider;
-
- private TableViewer fTableViewer;
-
- private MergeViewerInfoViewer fInfoViewer;
-
- public TableMergeViewer(Composite parent, MergeViewerSide side, ICompareColorProvider colorProvider) {
- super(parent, side);
- fColorProvider = colorProvider;
-
- getStructuredViewer().getTable().addListener(SWT.EraseItem, new Listener() {
- public void handleEvent(Event event) {
- TableMergeViewer.this.handleEraseItemEvent(event);
- }
- });
-
- getStructuredViewer().getTable().addListener(SWT.MeasureItem, new ItemResizeListener());
-
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#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 MergeViewerInfoViewer(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.MergeViewer.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer()
- */
- @Override
- public final TableViewer getStructuredViewer() {
- return fTableViewer;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#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.mergeviewer.MergeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)
- */
- @Override
- public void setLabelProvider(IBaseLabelProvider labelProvider) {
- super.setLabelProvider(labelProvider);
- fInfoViewer.setLabelProvider(labelProvider);
- }
-
- /**
- * {@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);
- }
-
- private void handleEraseItemEvent(Event event) {
- TableItem tableItem = (TableItem)event.item;
- Object data = tableItem.getData();
-
- if (data instanceof InsertionPoint) {
- InsertionPoint insertionPoint = (InsertionPoint)data;
- paintItemDiffBox(event, insertionPoint.getDiff(), getBoundsForInsertionPoint(event));
- } else if (data instanceof IMergeViewerItem) {
- Diff diff = ((IMergeViewerItem)data).getDiff();
- if (diff != null) {
- paintItemDiffBox(event, diff, getBounds(event));
- }
- }
- }
-
- private void paintItemDiffBox(Event event, Diff diff, Rectangle bounds) {
- event.detail &= ~SWT.HOT;
-
- if (diff.getState() == DifferenceState.DISCARDED || diff.getState() == DifferenceState.MERGED) {
- return;
- }
-
- GC g = event.gc;
- Color oldBackground = g.getBackground();
- Color oldForeground = g.getForeground();
-
- setDiffColorsToGC(g, diff, isSelected(event));
- g.fillRectangle(bounds);
- g.drawRectangle(bounds);
-
- if (getSide() == MergeViewerSide.LEFT) {
- drawLineFromBoxToCenter(event, bounds, g);
- } else {
- drawLineFromCenterToBox(event, bounds, g);
- }
-
- 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);
- }
- }
-
- private void drawLineFromCenterToBox(Event event, Rectangle boxBounds, GC g) {
- TableItem tableItem = (TableItem)event.item;
- Rectangle itemBounds = tableItem.getBounds();
- Point from = new Point(0, 0);
- from.y = itemBounds.y + (itemBounds.height / 2);
- Point to = new Point(boxBounds.x, from.y);
- g.drawLine(from.x, from.y, to.x, to.y);
- }
-
- private void drawLineFromBoxToCenter(Event event, Rectangle boxBounds, GC g) {
- TableItem tableItem = (TableItem)event.item;
- Rectangle itemBounds = tableItem.getBounds();
- Rectangle clientArea = tableItem.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;
- g.drawLine(from.x, from.y, to.x, to.y);
- }
-
- static boolean isSelected(Event event) {
- return (event.detail & SWT.SELECTED) != 0;
- }
-
- private static Rectangle getBounds(Event event) {
- TableItem tableItem = (TableItem)event.item;
- Table table = tableItem.getParent();
- Rectangle tableBounds = table.getClientArea();
- Rectangle itemBounds = tableItem.getBounds();
-
- Rectangle fill = new Rectangle(0, 0, 0, 0);
- fill.x = 2;
- fill.y = itemBounds.y + 2;
- // +x to add the icon and the expand "+" if we are in a tree
- fill.width = itemBounds.width + itemBounds.x;
- fill.height = itemBounds.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.
- int columnCount = table.getColumnCount();
- if (event.index == columnCount - 1 || columnCount == 0) {
- int width = tableBounds.x + tableBounds.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;
- }
-
- private static Rectangle getBoundsForInsertionPoint(Event event) {
- Rectangle fill = getBounds(event);
- TableItem tableItem = (TableItem)event.item;
- Rectangle tableBounds = tableItem.getParent().getClientArea();
- fill.y = fill.y + 6;
- fill.width = tableBounds.width / 4;
- fill.height = fill.height - 12;
-
- return fill;
- }
-
- private void setDiffColorsToGC(GC g, Diff diff, boolean selected) {
- boolean isThreeWay = false;
- if (getInput() instanceof IStructuralFeatureAccessor) {
- Comparison comparison = ((IStructuralFeatureAccessor)getInput()).getComparison();
- isThreeWay = comparison.isThreeWay();
- }
- g.setForeground(fColorProvider.getCompareColor().getStrokeColor(diff, isThreeWay, false, selected));
- g.setBackground(fColorProvider.getCompareColor().getFillColor(diff, isThreeWay, false, selected));
- }
-
- /**
- * 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 <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
- private static class ItemResizeListener implements Listener {
- /** The last item we resized. Will be used to workaround a windows-specific bug. */
- private Widget fLastWidget;
-
- /**
- * The height to which we've resized the last item. Will be used to workaround a windows-specific bug.
- */
- private int fLastHeight;
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
- */
- public void handleEvent(Event event) {
- // Windows bug: prevents StackOverflow
- if (event.item == fLastWidget && event.height == fLastHeight) {
- return;
- }
-
- fLastWidget = event.item;
- fLastHeight = event.height;
- int newHeight = (int)(event.gc.getFontMetrics().getHeight() * 1.33d);
- // If odd, make even
- if ((newHeight & 1) == 1) {
- newHeight += 1;
- }
- event.height = newHeight;
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.Viewer#refresh()
- */
- @Override
- public void refresh() {
- fInfoViewer.refresh();
- fTableViewer.refresh();
- }
-
-}
+/*******************************************************************************
+ * 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.mergeviewer;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.ICompareAccessor;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Region;
+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.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TableMergeViewer extends StructuredMergeViewer {
+
+ private final ICompareColorProvider fColorProvider;
+
+ private TableViewer fTableViewer;
+
+ private MergeViewerInfoViewer fInfoViewer;
+
+ public TableMergeViewer(Composite parent, MergeViewerSide side, ICompareColorProvider colorProvider) {
+ super(parent, side);
+ fColorProvider = colorProvider;
+
+ getStructuredViewer().getTable().addListener(SWT.EraseItem, new Listener() {
+ public void handleEvent(Event event) {
+ TableMergeViewer.this.handleEraseItemEvent(event);
+ }
+ });
+
+ getStructuredViewer().getTable().addListener(SWT.MeasureItem, new ItemResizeListener());
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#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 MergeViewerInfoViewer(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.MergeViewer.ui.internal.contentmergeviewer.AbstractMergeViewer#getStructuredViewer()
+ */
+ @Override
+ public final TableViewer getStructuredViewer() {
+ return fTableViewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.MergeViewer#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.mergeviewer.MergeViewer#setLabelProvider(org.eclipse.jface.viewers.IBaseLabelProvider)
+ */
+ @Override
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {
+ super.setLabelProvider(labelProvider);
+ fInfoViewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * {@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);
+ }
+
+ private void handleEraseItemEvent(Event event) {
+ TableItem tableItem = (TableItem)event.item;
+ Object data = tableItem.getData();
+
+ if (data instanceof InsertionPoint) {
+ InsertionPoint insertionPoint = (InsertionPoint)data;
+ paintItemDiffBox(event, insertionPoint.getDiff(), getBoundsForInsertionPoint(event));
+ } else if (data instanceof IMergeViewerItem) {
+ Diff diff = ((IMergeViewerItem)data).getDiff();
+ if (diff != null) {
+ paintItemDiffBox(event, diff, getBounds(event));
+ }
+ }
+ }
+
+ private void paintItemDiffBox(Event event, Diff diff, Rectangle bounds) {
+ event.detail &= ~SWT.HOT;
+
+ if (diff.getState() == DifferenceState.DISCARDED || diff.getState() == DifferenceState.MERGED) {
+ return;
+ }
+
+ GC g = event.gc;
+ Color oldBackground = g.getBackground();
+ Color oldForeground = g.getForeground();
+
+ setDiffColorsToGC(g, diff, isSelected(event));
+ g.fillRectangle(bounds);
+ g.drawRectangle(bounds);
+
+ if (getSide() == MergeViewerSide.LEFT) {
+ drawLineFromBoxToCenter(event, bounds, g);
+ } else {
+ drawLineFromCenterToBox(event, bounds, g);
+ }
+
+ 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);
+ }
+ }
+
+ private void drawLineFromCenterToBox(Event event, Rectangle boxBounds, GC g) {
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle itemBounds = tableItem.getBounds();
+ Point from = new Point(0, 0);
+ from.y = itemBounds.y + (itemBounds.height / 2);
+ Point to = new Point(boxBounds.x, from.y);
+ g.drawLine(from.x, from.y, to.x, to.y);
+ }
+
+ private void drawLineFromBoxToCenter(Event event, Rectangle boxBounds, GC g) {
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle itemBounds = tableItem.getBounds();
+ Rectangle clientArea = tableItem.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;
+ g.drawLine(from.x, from.y, to.x, to.y);
+ }
+
+ static boolean isSelected(Event event) {
+ return (event.detail & SWT.SELECTED) != 0;
+ }
+
+ private static Rectangle getBounds(Event event) {
+ TableItem tableItem = (TableItem)event.item;
+ Table table = tableItem.getParent();
+ Rectangle tableBounds = table.getClientArea();
+ Rectangle itemBounds = tableItem.getBounds();
+
+ Rectangle fill = new Rectangle(0, 0, 0, 0);
+ fill.x = 2;
+ fill.y = itemBounds.y + 2;
+ // +x to add the icon and the expand "+" if we are in a tree
+ fill.width = itemBounds.width + itemBounds.x;
+ fill.height = itemBounds.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.
+ int columnCount = table.getColumnCount();
+ if (event.index == columnCount - 1 || columnCount == 0) {
+ int width = tableBounds.x + tableBounds.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;
+ }
+
+ private static Rectangle getBoundsForInsertionPoint(Event event) {
+ Rectangle fill = getBounds(event);
+ TableItem tableItem = (TableItem)event.item;
+ Rectangle tableBounds = tableItem.getParent().getClientArea();
+ fill.y = fill.y + 6;
+ fill.width = tableBounds.width / 4;
+ fill.height = fill.height - 12;
+
+ return fill;
+ }
+
+ private void setDiffColorsToGC(GC g, Diff diff, boolean selected) {
+ boolean isThreeWay = false;
+ if (getInput() instanceof ICompareAccessor) {
+ Comparison comparison = ((ICompareAccessor)getInput()).getComparison();
+ isThreeWay = comparison.isThreeWay();
+ }
+ g.setForeground(fColorProvider.getCompareColor().getStrokeColor(diff, isThreeWay, false, selected));
+ g.setBackground(fColorProvider.getCompareColor().getFillColor(diff, isThreeWay, false, selected));
+ }
+
+ /**
+ * 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 <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+ private static class ItemResizeListener implements Listener {
+ /** The last item we resized. Will be used to workaround a windows-specific bug. */
+ private Widget fLastWidget;
+
+ /**
+ * The height to which we've resized the last item. Will be used to workaround a windows-specific bug.
+ */
+ private int fLastHeight;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+ */
+ public void handleEvent(Event event) {
+ // Windows bug: prevents StackOverflow
+ if (event.item == fLastWidget && event.height == fLastHeight) {
+ return;
+ }
+
+ fLastWidget = event.item;
+ fLastHeight = event.height;
+ int newHeight = (int)(event.gc.getFontMetrics().getHeight() * 1.33d);
+ // If odd, make even
+ if ((newHeight & 1) == 1) {
+ newHeight += 1;
+ }
+ event.height = newHeight;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.Viewer#refresh()
+ */
+ @Override
+ public void refresh() {
+ fInfoViewer.refresh();
+ fTableViewer.refresh();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java
new file mode 100644
index 000000000..62c601db4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicResourceContentsAccessorImpl.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+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.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public abstract class BasicResourceContentsAccessorImpl 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;
+
+ /** The list of sibling differences of the performed difference. */
+ private final ImmutableList<Diff> fDifferences;
+
+ /**
+ * @param diff
+ * The difference performed.
+ * @param side
+ * The side on which the difference is located.
+ */
+ public BasicResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ fDiff = diff;
+ fSide = side;
+ fOwnerMatch = diff.getMatch();
+ fDifferences = computeDifferences();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getComparison()
+ */
+ public Comparison getComparison() {
+ return fOwnerMatch.getComparison();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getInitialItem()
+ */
+ public IMergeViewerItem getInitialItem() {
+ IMergeViewerItem ret = null;
+ ImmutableList<? extends IMergeViewerItem> 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.mergeviewer.accessor.IResourceContentsAccessor#getResource(org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide)
+ */
+ public Resource getResource(MergeViewerSide side) {
+ Resource resource = null;
+ Collection<MatchResource> matchResources = fOwnerMatch.getComparison().getMatchedResources();
+ final String diffResourceURI = ((ResourceAttachmentChange)fDiff).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) {
+ URI resourceURI = resource.getURI();
+ if (diffResourceURI.equals(resourceURI.toString())) {
+ return resource;
+ }
+ }
+ }
+ return resource;
+ }
+
+ /**
+ * Returns the contents of the current resource on the given side.
+ *
+ * @param side
+ * The given side.
+ * @return The contents of the current resource on the given side.
+ */
+ public List<EObject> getResourceContents(MergeViewerSide side) {
+ Resource resource = getResource(side);
+ if (resource != null) {
+ return resource.getContents();
+ }
+ return Collections.emptyList();
+
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns the list of sibling differences of the current difference.
+ *
+ * @return The list of sibling differences of the current difference.
+ */
+ protected final ImmutableList<Diff> getDifferences() {
+ return fDifferences;
+ }
+
+ /**
+ * Computes the list of sibling differences of the current difference.
+ *
+ * @return The list of sibling differences of the current difference.
+ */
+ protected ImmutableList<Diff> computeDifferences() {
+ Iterable<EObject> concat = Iterables.concat(getResourceContents(MergeViewerSide.LEFT),
+ getResourceContents(MergeViewerSide.RIGHT), getResourceContents(MergeViewerSide.ANCESTOR));
+
+ final Comparison comparison = fOwnerMatch.getComparison();
+ Iterable<Match> matches = transform(concat, new Function<EObject, Match>() {
+ public Match apply(EObject eObject) {
+ return comparison.getMatch(eObject);
+ }
+ });
+ Iterable<Diff> siblingDifferences = concat(transform(matches, new Function<Match, List<Diff>>() {
+ public List<Diff> apply(Match match) {
+ return match.getDifferences();
+ }
+ }));
+ Predicate<? super Diff> diffFilter = and(instanceOf(ResourceAttachmentChange.class),
+ not(hasConflict(ConflictKind.PSEUDO)));
+ return ImmutableSet.<Diff> copyOf(filter(siblingDifferences, diffFilter)).asList();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
index a04ff7a43..20be7077a 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/BasicStructuralFeatureAccessorImpl.java
@@ -1,152 +1,164 @@
-/*******************************************************************************
-
- * Copyright (c) 2012 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.accessor;
-
-import static com.google.common.base.Predicates.and;
-import static com.google.common.base.Predicates.not;
-import static com.google.common.collect.Iterables.filter;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
-import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.AttributeChange;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.ConflictKind;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ReferenceChange;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public abstract class BasicStructuralFeatureAccessorImpl implements IStructuralFeatureAccessor {
-
- private final Diff fDiff;
-
- private final MergeViewerSide fSide;
-
- private final Match fOwnerMatch;
-
- private final EStructuralFeature fStructuralFeature;
-
- private final ImmutableList<Diff> fDifferences;
-
- public BasicStructuralFeatureAccessorImpl(Diff diff, MergeViewerSide side) {
- fDiff = diff;
- fSide = side;
- fOwnerMatch = diff.getMatch();
- fStructuralFeature = getAffectedFeature(diff);
- fDifferences = computeDifferences();
- }
-
- public Comparison getComparison() {
- return fOwnerMatch.getComparison();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IStructuralFeatureAccessor#getInitialItem()
- */
- public IMergeViewerItem getInitialItem() {
- IMergeViewerItem ret = null;
- ImmutableList<? extends IMergeViewerItem> items = getItems();
- for (IMergeViewerItem item : items) {
- Diff diff = item.getDiff();
- if (diff == fDiff) {
- ret = item;
- }
- }
- return ret;
- }
-
- public EObject getEObject(MergeViewerSide side) {
- final EObject eObject;
- switch (side) {
- case ANCESTOR:
- eObject = fOwnerMatch.getOrigin();
- break;
- case LEFT:
- eObject = fOwnerMatch.getLeft();
- break;
- case RIGHT:
- eObject = fOwnerMatch.getRight();
- break;
- default:
- throw new IllegalStateException();
- }
- return eObject;
- }
-
- /**
- * @return the fStructuralFeature
- */
- public EStructuralFeature getStructuralFeature() {
- return fStructuralFeature;
- }
-
- /**
- * @return the fSide
- */
- protected final MergeViewerSide getSide() {
- return fSide;
- }
-
- /**
- * @return the fDifferences
- */
- protected final ImmutableList<Diff> getDifferences() {
- return fDifferences;
- }
-
- protected ImmutableList<Diff> computeDifferences() {
- List<Diff> siblingDifferences = fOwnerMatch.getDifferences();
- // We'll display all diffs on the same reference, excluding the pseudo conflicts.
- Predicate<? super Diff> diffFilter = and(onFeature(fStructuralFeature.getName()),
- not(hasConflict(ConflictKind.PSEUDO)));
- return ImmutableList.copyOf(filter(siblingDifferences, diffFilter));
- }
-
- /**
- * 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. <code>null</code> if none.
- */
- protected 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 {
- feature = null;
- }
- return feature;
- }
-
- /**
- * @return the fDiff
- */
- protected final Diff getInitialDiff() {
- return fDiff;
- }
-}
+/*******************************************************************************
+
+ * Copyright (c) 2012 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.accessor;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.Iterables.filter;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.onFeature;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class BasicStructuralFeatureAccessorImpl implements IStructuralFeatureAccessor {
+
+ private final Diff fDiff;
+
+ private final MergeViewerSide fSide;
+
+ private final Match fOwnerMatch;
+
+ private final EStructuralFeature fStructuralFeature;
+
+ private final ImmutableList<Diff> fDifferences;
+
+ public BasicStructuralFeatureAccessorImpl(Diff diff, MergeViewerSide side) {
+ fDiff = diff;
+ fSide = side;
+ fOwnerMatch = diff.getMatch();
+ fStructuralFeature = getAffectedFeature(diff);
+ fDifferences = computeDifferences();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getComparison()
+ */
+ public Comparison getComparison() {
+ return fOwnerMatch.getComparison();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem()
+ */
+ public IMergeViewerItem getInitialItem() {
+ IMergeViewerItem ret = null;
+ ImmutableList<? extends IMergeViewerItem> 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.mergeviewer.accessor.IStructuralFeatureAccessor#getInitialItem()
+ */
+ public EObject getEObject(MergeViewerSide side) {
+ final EObject eObject;
+ switch (side) {
+ case ANCESTOR:
+ eObject = fOwnerMatch.getOrigin();
+ break;
+ case LEFT:
+ eObject = fOwnerMatch.getLeft();
+ break;
+ case RIGHT:
+ eObject = fOwnerMatch.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return eObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IStructuralFeatureAccessor#getStructuralFeature()
+ */
+ public EStructuralFeature getStructuralFeature() {
+ return fStructuralFeature;
+ }
+
+ /**
+ * @return the fSide
+ */
+ protected final MergeViewerSide getSide() {
+ return fSide;
+ }
+
+ /**
+ * @return the fDifferences
+ */
+ protected final ImmutableList<Diff> getDifferences() {
+ return fDifferences;
+ }
+
+ protected ImmutableList<Diff> computeDifferences() {
+ List<Diff> siblingDifferences = fOwnerMatch.getDifferences();
+ // We'll display all diffs on the same reference, excluding the pseudo conflicts.
+ Predicate<? super Diff> diffFilter = and(onFeature(fStructuralFeature.getName()),
+ not(hasConflict(ConflictKind.PSEUDO)));
+ return ImmutableList.copyOf(filter(siblingDifferences, diffFilter));
+ }
+
+ /**
+ * 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. <code>null</code> if none.
+ */
+ protected 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 {
+ feature = null;
+ }
+ return feature;
+ }
+
+ /**
+ * @return the fDiff
+ */
+ protected final Diff getInitialDiff() {
+ return fDiff;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
index b79db66f0..6579c2af0 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/EObjectAccessor.java
@@ -1,287 +1,287 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.accessor;
-
-import com.google.common.collect.Maps;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.AdapterFactory;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.rcp.ui.Activator;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.utils.ReferenceUtil;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
-import org.eclipse.emf.edit.provider.IItemLabelProvider;
-import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * A {@link ITypedElement} that can be used as input of TreeContentMergeViewer. It is implementing
- * {@link IStreamContentAccessor} to be able to compare XMI serialization of wrapped {@link EObject}.
- *
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class EObjectAccessor implements IEObjectAccessor {
-
- /**
- * The wrapped {@link EObject}.
- */
- // private final EObject fEObject;
-
- /**
- * The adapter factory that will be used to get the name and the image of the wrapped EObject.
- */
- private final AdapterFactory fAdapterFactory;
-
- private final Match fOwnerMatch;
-
- private final MergeViewerSide fSide;
-
- /**
- * Creates a new object wrapping the given <code>eObject</code>.
- *
- * @param adapterFactory
- * the adapter factory to get the image from.
- * @param eObject
- * the {@link EObject} to wrap.
- */
- public EObjectAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) {
- fAdapterFactory = adapterFactory;
- fOwnerMatch = match;
- fSide = side;
- }
-
- /**
- * @return the fSide
- */
- protected final MergeViewerSide getSide() {
- return fSide;
- }
-
- protected EObject getEObject(MergeViewerSide side) {
- final EObject eObject;
- switch (side) {
- case ANCESTOR:
- eObject = fOwnerMatch.getOrigin();
- break;
- case LEFT:
- eObject = fOwnerMatch.getLeft();
- break;
- case RIGHT:
- eObject = fOwnerMatch.getRight();
- break;
- default:
- throw new IllegalStateException();
- }
- return eObject;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getName()
- */
- public String getName() {
- return getEObject(getSide()).eClass().getName();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.compare.ITypedElement#getImage()
- */
- public Image getImage() {
- Adapter adapter = fAdapterFactory.adapt(getEObject(), IItemLabelProvider.class);
- if (adapter instanceof IItemLabelProvider) {
- Object image = ((IItemLabelProvider)adapter).getImage(getEObject());
- return ExtendedImageRegistry.getInstance().getImage(image);
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IEObjectAccessor#getEObject()
- */
- public EObject getEObject() {
- return getEObject(getSide());
- }
-
- public InputStream getContents() throws CoreException {
- XMIResourceImpl r = new XMIResourceImpl(URI.createURI("dummy.xmi")); //$NON-NLS-1$
-
- final ProperContentCopier copier = new ProperContentCopier();
- final EObject copy = copier.copy(getEObject());
- copier.copyReferences();
-
- r.getContents().add(copy);
- StringWriter sw = new StringWriter();
- try {
- r.save(sw, Maps.newHashMap());
- } catch (IOException e) {
- throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
- }
- // Assume that the platform locale is appropriate.
- return new ByteArrayInputStream(sw.toString().getBytes());
- }
-
- private class ProperContentCopier extends EcoreUtil.Copier {
- /** Generated SUID. */
- private static final long serialVersionUID = -5458049632291531717L;
-
- public ProperContentCopier() {
- this.resolveProxies = false;
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
- * EObject). We're only making sure not to resolve any proxy to another resource.
- * </p>
- *
- * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyContainment(org.eclipse.emf.ecore.EReference,
- * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
- */
- @Override
- protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
- if (!eObject.eIsSet(eReference)) {
- return;
- }
-
- if (eReference.isMany()) {
- final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
- @SuppressWarnings("unchecked")
- List<EObject> target = (List<EObject>)copyEObject.eGet(getTarget(eReference), resolveProxies);
- if (!source.hasNext()) {
- target.clear();
- } else {
- while (source.hasNext()) {
- final EObject next = source.next();
- target.add(copy(next));
- }
- }
- } else {
- /*
- * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
- * multi-valued containment features. Will it honor it for unique features?
- */
- EObject childEObject = (EObject)eObject.eGet(eReference, resolveProxies);
- if (childEObject == null) {
- copyEObject.eSet(getTarget(eReference), null);
- } else {
- copyEObject.eSet(getTarget(eReference), copy(childEObject));
- }
- }
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
- * EObject). We're only making sure not to resolve any proxy to another resource.
- * </p>
- *
- * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyReference(org.eclipse.emf.ecore.EReference,
- * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
- */
- @Override
- protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
- if (!eObject.eIsSet(eReference)) {
- return;
- }
-
- if (eReference.isMany()) {
- final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
- @SuppressWarnings("unchecked")
- InternalEList<EObject> target = (InternalEList<EObject>)copyEObject.eGet(
- getTarget(eReference), false);
- if (!source.hasNext()) {
- target.clear();
- } else {
- boolean isBidirectional = eReference.getEOpposite() != null;
- int index = 0;
- while (source.hasNext()) {
- final EObject next = source.next();
- final EObject copyReferencedEObject = get(next);
-
- if (copyReferencedEObject == null) {
- if (useOriginalReferences && !isBidirectional) {
- target.addUnique(index, next);
- ++index;
- }
- } else {
- if (isBidirectional) {
- int position = target.indexOf(copyReferencedEObject);
- if (position == -1) {
- target.addUnique(index, copyReferencedEObject);
- } else if (index != position) {
- target.move(index, copyReferencedEObject);
- }
- } else {
- target.addUnique(index, copyReferencedEObject);
- }
- ++index;
- }
- }
- }
- } else {
- /*
- * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
- * multi-valued containment features. Will it honor it for unique features?
- */
- final Object referencedEObject = eObject.eGet(eReference, resolveProxies);
- if (referencedEObject == null) {
- copyEObject.eSet(getTarget(eReference), null);
- } else {
- final Object copyReferencedEObject = get(referencedEObject);
- if (copyReferencedEObject == null) {
- if (useOriginalReferences && eReference.getEOpposite() == null) {
- copyEObject.eSet(getTarget(eReference), referencedEObject);
- }
- } else {
- copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
- }
- }
- }
- }
- }
-
- private final class BoundProperContentIterator extends EcoreUtil.ProperContentIterator<EObject> {
- public BoundProperContentIterator(EObject eObject, EReference eReference) {
- super(eObject, false);
- // Calling super-constructor since we need to, but we'll override what it just did
- @SuppressWarnings("unchecked")
- final List<EObject> contents = (List<EObject>)ReferenceUtil.safeEGet(eObject, eReference);
- if (contents instanceof InternalEList<?>) {
- this.iterator = ((InternalEList<EObject>)contents).basicIterator();
- } else {
- this.iterator = contents.iterator();
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.accessor;
+
+import com.google.common.collect.Maps;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.utils.ReferenceUtil;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A {@link ITypedElement} that can be used as input of TreeContentMergeViewer. It is implementing
+ * {@link IStreamContentAccessor} to be able to compare XMI serialization of wrapped {@link EObject}.
+ *
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class EObjectAccessor implements IEObjectAccessor {
+
+ /**
+ * The wrapped {@link EObject}.
+ */
+ // private final EObject fEObject;
+
+ /**
+ * The adapter factory that will be used to get the name and the image of the wrapped EObject.
+ */
+ private final AdapterFactory fAdapterFactory;
+
+ private final Match fOwnerMatch;
+
+ private final MergeViewerSide fSide;
+
+ /**
+ * Creates a new object wrapping the given <code>eObject</code>.
+ *
+ * @param adapterFactory
+ * the adapter factory to get the image from.
+ * @param eObject
+ * the {@link EObject} to wrap.
+ */
+ public EObjectAccessor(AdapterFactory adapterFactory, Match match, MergeViewerSide side) {
+ fAdapterFactory = adapterFactory;
+ fOwnerMatch = match;
+ fSide = side;
+ }
+
+ /**
+ * @return the fSide
+ */
+ protected final MergeViewerSide getSide() {
+ return fSide;
+ }
+
+ protected EObject getEObject(MergeViewerSide side) {
+ final EObject eObject;
+ switch (side) {
+ case ANCESTOR:
+ eObject = fOwnerMatch.getOrigin();
+ break;
+ case LEFT:
+ eObject = fOwnerMatch.getLeft();
+ break;
+ case RIGHT:
+ eObject = fOwnerMatch.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return eObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getName()
+ */
+ public String getName() {
+ return getEObject(getSide()).eClass().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ public Image getImage() {
+ Adapter adapter = fAdapterFactory.adapt(getEObject(), IItemLabelProvider.class);
+ if (adapter instanceof IItemLabelProvider) {
+ Object image = ((IItemLabelProvider)adapter).getImage(getEObject());
+ return ExtendedImageRegistry.getInstance().getImage(image);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.provider.IEObjectAccessor#getEObject()
+ */
+ public EObject getEObject() {
+ return getEObject(getSide());
+ }
+
+ public InputStream getContents() throws CoreException {
+ XMIResourceImpl r = new XMIResourceImpl(URI.createURI("dummy.xmi")); //$NON-NLS-1$
+
+ final ProperContentCopier copier = new ProperContentCopier();
+ final EObject copy = copier.copy(getEObject());
+ copier.copyReferences();
+
+ r.getContents().add(copy);
+ StringWriter sw = new StringWriter();
+ try {
+ r.save(sw, Maps.newHashMap());
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, EMFCompareRCPUIPlugin.PLUGIN_ID, e.getMessage(), e));
+ }
+ // Assume that the platform locale is appropriate.
+ return new ByteArrayInputStream(sw.toString().getBytes());
+ }
+
+ private class ProperContentCopier extends EcoreUtil.Copier {
+ /** Generated SUID. */
+ private static final long serialVersionUID = -5458049632291531717L;
+
+ public ProperContentCopier() {
+ this.resolveProxies = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
+ * EObject). We're only making sure not to resolve any proxy to another resource.
+ * </p>
+ *
+ * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyContainment(org.eclipse.emf.ecore.EReference,
+ * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) {
+ if (!eObject.eIsSet(eReference)) {
+ return;
+ }
+
+ if (eReference.isMany()) {
+ final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
+ @SuppressWarnings("unchecked")
+ List<EObject> target = (List<EObject>)copyEObject.eGet(getTarget(eReference), resolveProxies);
+ if (!source.hasNext()) {
+ target.clear();
+ } else {
+ while (source.hasNext()) {
+ final EObject next = source.next();
+ target.add(copy(next));
+ }
+ }
+ } else {
+ /*
+ * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
+ * multi-valued containment features. Will it honor it for unique features?
+ */
+ EObject childEObject = (EObject)eObject.eGet(eReference, resolveProxies);
+ if (childEObject == null) {
+ copyEObject.eSet(getTarget(eReference), null);
+ } else {
+ copyEObject.eSet(getTarget(eReference), copy(childEObject));
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Implementation mostly copy/pasted from EcoreUtil.Copier#copyContainment(EReference, EObject,
+ * EObject). We're only making sure not to resolve any proxy to another resource.
+ * </p>
+ *
+ * @see org.eclipse.emf.ecore.util.EcoreUtil.Copier#copyReference(org.eclipse.emf.ecore.EReference,
+ * org.eclipse.emf.ecore.EObject, org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject) {
+ if (!eObject.eIsSet(eReference)) {
+ return;
+ }
+
+ if (eReference.isMany()) {
+ final Iterator<EObject> source = new BoundProperContentIterator(eObject, eReference);
+ @SuppressWarnings("unchecked")
+ InternalEList<EObject> target = (InternalEList<EObject>)copyEObject.eGet(
+ getTarget(eReference), false);
+ if (!source.hasNext()) {
+ target.clear();
+ } else {
+ boolean isBidirectional = eReference.getEOpposite() != null;
+ int index = 0;
+ while (source.hasNext()) {
+ final EObject next = source.next();
+ final EObject copyReferencedEObject = get(next);
+
+ if (copyReferencedEObject == null) {
+ if (useOriginalReferences && !isBidirectional) {
+ target.addUnique(index, next);
+ ++index;
+ }
+ } else {
+ if (isBidirectional) {
+ int position = target.indexOf(copyReferencedEObject);
+ if (position == -1) {
+ target.addUnique(index, copyReferencedEObject);
+ } else if (index != position) {
+ target.move(index, copyReferencedEObject);
+ }
+ } else {
+ target.addUnique(index, copyReferencedEObject);
+ }
+ ++index;
+ }
+ }
+ }
+ } else {
+ /*
+ * TODO untested yet as this is a rare case. EMF ignors the "resolve" argument of eGet for
+ * multi-valued containment features. Will it honor it for unique features?
+ */
+ final Object referencedEObject = eObject.eGet(eReference, resolveProxies);
+ if (referencedEObject == null) {
+ copyEObject.eSet(getTarget(eReference), null);
+ } else {
+ final Object copyReferencedEObject = get(referencedEObject);
+ if (copyReferencedEObject == null) {
+ if (useOriginalReferences && eReference.getEOpposite() == null) {
+ copyEObject.eSet(getTarget(eReference), referencedEObject);
+ }
+ } else {
+ copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
+ }
+ }
+ }
+ }
+ }
+
+ private final class BoundProperContentIterator extends EcoreUtil.ProperContentIterator<EObject> {
+ public BoundProperContentIterator(EObject eObject, EReference eReference) {
+ super(eObject, false);
+ // Calling super-constructor since we need to, but we'll override what it just did
+ @SuppressWarnings("unchecked")
+ final List<EObject> contents = (List<EObject>)ReferenceUtil.safeEGet(eObject, eReference);
+ if (contents instanceof InternalEList<?>) {
+ this.iterator = ((InternalEList<EObject>)contents).basicIterator();
+ } else {
+ this.iterator = contents.iterator();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java
new file mode 100644
index 000000000..6835ea022
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ICompareAccessor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import com.google.common.collect.ImmutableList;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public interface ICompareAccessor {
+
+ Comparison getComparison();
+
+ IMergeViewerItem getInitialItem();
+
+ ImmutableList<? extends IMergeViewerItem> getItems();
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/AbstractAccessorFactory.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java
index 260b8c946..0ec996494 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/accessor/AbstractAccessorFactory.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IResourceContentsAccessor.java
@@ -1,16 +1,22 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.contentmergeviewer.accessor;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public interface IResourceContentsAccessor extends ICompareAccessor {
+
+ Resource getResource(MergeViewerSide side);
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
index 8993bc07a..59b6bb582 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/IStructuralFeatureAccessor.java
@@ -1,36 +1,26 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.accessor;
-
-import com.google.common.collect.ImmutableList;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
-import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public interface IStructuralFeatureAccessor {
-
- EStructuralFeature getStructuralFeature();
-
- EObject getEObject(MergeViewerSide side);
-
- Comparison getComparison();
-
- IMergeViewerItem getInitialItem();
-
- ImmutableList<? extends IMergeViewerItem> getItems();
-
-}
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public interface IStructuralFeatureAccessor extends ICompareAccessor {
+
+ EStructuralFeature getStructuralFeature();
+
+ EObject getEObject(MergeViewerSide side);
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java
new file mode 100644
index 000000000..bb1a6addf
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/mergeviewer/accessor/ResourceContentsAccessorImpl.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * 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.mergeviewer.accessor;
+
+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.collect.ImmutableList;
+
+import java.util.Iterator;
+import java.util.List;
+
+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.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.InsertionPoint;
+import org.eclipse.emf.compare.rcp.ui.mergeviewer.MatchedObject;
+import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.compare.utils.IEqualityHelper;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+public class ResourceContentsAccessorImpl extends BasicResourceContentsAccessorImpl {
+
+ /**
+ * @param diff
+ * The difference performed.
+ * @param side
+ * The side on which the difference is located.
+ */
+ public ResourceContentsAccessorImpl(Diff diff, MergeViewerSide side) {
+ super(diff, side);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.mergeviewer.accessor.IResourceContentsAccessor#getItems()
+ */
+ public ImmutableList<? extends IMergeViewerItem> getItems() {
+ List<? extends IMergeViewerItem> ret;
+ List<?> list = getResourceContents(getSide());
+ ret = createMergeViewerItemFrom(list);
+
+ if (getSide() != MergeViewerSide.ANCESTOR) {
+ ret = createInsertionPoints(ret);
+ }
+
+ return ImmutableList.copyOf(ret);
+ }
+
+ private List<? extends IMergeViewerItem> createMergeViewerItemFrom(List<?> values) {
+ List<IMergeViewerItem> ret = newArrayListWithCapacity(values.size());
+ for (Object value : values) {
+ IMergeViewerItem valueToAdd = createMergeViewerItemFrom(value);
+ ret.add(valueToAdd);
+ }
+ return ret;
+ }
+
+ 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);
+ return new MatchedObject(diff, left, right, ancestor);
+ }
+
+ private List<? extends IMergeViewerItem> createInsertionPoints(
+ final List<? extends IMergeViewerItem> values) {
+ List<IMergeViewerItem> ret = newArrayList(values);
+ for (Diff diff : getDifferences().reverse()) {
+ boolean rightToLeft = (getSide() == MergeViewerSide.LEFT);
+ Object left = getValueFromDiff(diff, MergeViewerSide.LEFT);
+ Object right = getValueFromDiff(diff, MergeViewerSide.RIGHT);
+
+ if (left == null && right == null) {
+ // Do not display anything
+ } else {
+ final boolean leftEmptyBox = getSide() == MergeViewerSide.LEFT
+ && (left == null || !getResourceContents(getSide()).contains(left));
+ final boolean rightEmptyBox = getSide() == MergeViewerSide.RIGHT
+ && (right == null || !getResourceContents(getSide()).contains(right));
+ if (leftEmptyBox || rightEmptyBox) {
+ Object ancestor = getValueFromDiff(diff, MergeViewerSide.ANCESTOR);
+
+ InsertionPoint insertionPoint = new InsertionPoint(diff, left, right, ancestor);
+
+ final int insertionIndex = Math.min(findInsertionIndex(diff, rightToLeft), ret.size());
+ List<IMergeViewerItem> subList = ret.subList(0, insertionIndex);
+ final int nbInsertionPointBefore = size(filter(subList, InsertionPoint.class));
+
+ int index = Math.min(insertionIndex + nbInsertionPointBefore, ret.size());
+ ret.add(index, insertionPoint);
+ }
+ }
+ }
+ return ret;
+ }
+
+ protected int findInsertionIndex(Diff diff, boolean rightToLeft) {
+ final Match valueMatch = diff.getMatch();
+ final Comparison comparison = valueMatch.getComparison();
+
+ final EObject expectedValue;
+ if (valueMatch.getLeft() != null) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+
+ final Resource initialResource;
+ final Resource expectedResource;
+ if (rightToLeft) {
+ initialResource = getResource(MergeViewerSide.RIGHT);
+ expectedResource = getResource(MergeViewerSide.LEFT);
+ } else {
+ initialResource = getResource(MergeViewerSide.LEFT);
+ expectedResource = getResource(MergeViewerSide.RIGHT);
+ }
+ final List<EObject> sourceList = initialResource.getContents();
+ final List<EObject> targetList = expectedResource.getContents();
+
+ return DiffUtil.findInsertionIndex(comparison, sourceList, targetList, expectedValue);
+ }
+
+ private Diff getDiffWithValue(Object value) {
+ Diff ret = null;
+ for (Diff diff : getDifferences()) {
+ Object valueOfDiff = getValueFromDiff(diff, getSide());
+ if (valueOfDiff == value) {
+ ret = diff;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ protected Object getValueFromDiff(final Diff diff, MergeViewerSide side) {
+ Object diffValue = getDiffValue(diff, side);
+ Object ret = matchingValue(diffValue, side);
+ return ret;
+ }
+
+ 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, getResourceContents(side));
+ }
+ } else {
+ ret = matchingValue(object, getResourceContents(side));
+ }
+ return ret;
+ }
+
+ 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;
+ }
+
+ protected Object getDiffValue(Diff diff, MergeViewerSide side) {
+ final Object ret;
+ if (diff instanceof ResourceAttachmentChange) {
+ Match match = ((ResourceAttachmentChange)diff).getMatch();
+ switch (side) {
+ case ANCESTOR:
+ switch (diff.getSource()) {
+ case LEFT:
+ ret = match.getRight();
+ break;
+ case RIGHT:
+ ret = match.getLeft();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ break;
+ case LEFT:
+ ret = match.getLeft();
+ break;
+ case RIGHT:
+ ret = match.getRight();
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ } else {
+ ret = null;
+ }
+ return ret;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java
new file mode 100644
index 000000000..4cb6e0f30
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterAction.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+
+/**
+ * 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.
+ * <p>
+ * 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 <b>not</b> meet the
+ * selected filters' criteria in order to be displayed).
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class FilterAction extends Action {
+
+ /** The filter associated with this action. */
+ private IDifferenceFilter filter;
+
+ /** The Filter that will be modified by the action. */
+ private StructureMergeViewerFilter structureMergeViewerFilter;
+
+ /**
+ * 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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ if (isChecked()) {
+ structureMergeViewerFilter.addFilter(filter);
+ } else {
+ structureMergeViewerFilter.removeFilter(filter);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java
new file mode 100644
index 000000000..3e83bfd58
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/FilterActionMenu.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.StructureMergeViewerFilter;
+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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.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 MenuManager menuManager;
+
+ /**
+ * Constructs our filtering menu.
+ *
+ * @param structureMergeViewerFilter
+ * The viewer filter for which we'll create actions.
+ * @param menuManager
+ * The Menu Manager that will contain our menu.
+ */
+ public FilterActionMenu(StructureMergeViewerFilter structureMergeViewerFilter, MenuManager menuManager) {
+ super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
+ this.menuManager = menuManager;
+ this.structureMergeViewerFilter = structureMergeViewerFilter;
+ setMenuCreator(this);
+ setToolTipText("Filters"); //$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 scope
+ * The scope on which the filters will be applied.
+ * @param comparison
+ * The comparison on which the filters will be applied.
+ */
+ public void createActions(IComparisonScope scope, Comparison comparison) {
+ IDifferenceFilter.Registry registry = EMFCompareRCPUIPlugin.getDefault().getFilterActionRegistry();
+ for (IDifferenceFilter filterProvider : registry.getFilters(scope, comparison)) {
+ FilterAction action = new FilterAction(filterProvider.getLabel(), structureMergeViewerFilter,
+ filterProvider);
+ if (filterProvider.defaultSelected()) {
+ action.setChecked(true);
+ action.run();
+ }
+ 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 menuManager.getMenu();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java
index 6cfbdacae..cba4f3899 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/GroupAction.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupAction.java
@@ -1,50 +1,57 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-
-/**
- * This action will allow us to group differences by their kind.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class GroupAction extends Action {
- /** The difference grouper that will be affected by this action. */
- private final DifferenceGrouper differenceGrouper;
-
- /** The actual instance that will provide groups if this action is used. */
- private final DifferenceGroupProvider provider;
-
- /**
- * Instantiates our action given its target grouper.
- *
- * @param differenceGrouper
- * The grouper to which we'll provide our DifferenceGroupProvider.
- */
- public GroupAction(String text, DifferenceGrouper differenceGrouper,
- DifferenceGroupProvider provider) {
- super(text, IAction.AS_RADIO_BUTTON);
- this.differenceGrouper = differenceGrouper;
- this.provider = provider;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.action.Action#run()
- */
- @Override
- public void run() {
- differenceGrouper.setProvider(provider);
- }
-}
+/*******************************************************************************
+ * 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.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+
+/**
+ * This action will allow us to group differences by their kind.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.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;
+
+ /**
+ * Instantiates our action given its target grouper.
+ *
+ * @param text
+ * Will be used as the action's tooltip.
+ * @param structureMergeViewerGrouper
+ * The grouper to which we'll provide our DifferenceGroupProvider.
+ * @param provider
+ * The group provider associated with this action.
+ */
+ public GroupAction(String text, StructureMergeViewerGrouper structureMergeViewerGrouper,
+ IDifferenceGroupProvider provider) {
+ super(text, IAction.AS_RADIO_BUTTON);
+ this.structureMergeViewerGrouper = structureMergeViewerGrouper;
+ this.provider = provider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ structureMergeViewerGrouper.setProvider(provider);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java
new file mode 100644
index 000000000..90dc19827
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/actions/GroupActionMenu.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.actions;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DefaultGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.StructureMergeViewerGrouper;
+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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.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 MenuManager menuManager;
+
+ /** The default group provider. */
+ private DefaultGroupProvider defaultGroupProvider;
+
+ /**
+ * Constructs our grouping menu.
+ *
+ * @param structureMergeViewerGrouper
+ * The viewer grouper that will be affected by this menu's actions.
+ * @param menuManager
+ * The Menu Manager that will contain our menu.
+ * @param defaultGroupProvider
+ * The default group provider.
+ */
+ public GroupActionMenu(StructureMergeViewerGrouper structureMergeViewerGrouper, MenuManager menuManager,
+ DefaultGroupProvider defaultGroupProvider) {
+ super("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
+ this.menuManager = menuManager;
+ this.structureMergeViewerGrouper = structureMergeViewerGrouper;
+ this.defaultGroupProvider = defaultGroupProvider;
+ setToolTipText("Groups"); //$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 createActions(IComparisonScope scope, Comparison comparison) {
+ final IAction defaultAction = new GroupAction(defaultGroupProvider.getLabel(),
+ structureMergeViewerGrouper, defaultGroupProvider);
+ defaultAction.setChecked(true);
+ menuManager.add(defaultAction);
+ IDifferenceGroupProvider.Registry registry = EMFCompareRCPUIPlugin.getDefault()
+ .getDifferenceGroupProviderRegistry();
+ boolean alreadyChecked = false;
+ for (IDifferenceGroupProvider dgp : registry.getGroupProviders(scope, comparison)) {
+ GroupAction action = new GroupAction(dgp.getLabel(), structureMergeViewerGrouper, dgp);
+ menuManager.add(action);
+ if (dgp.defaultSelected() && !alreadyChecked) {
+ defaultAction.setChecked(false);
+ action.setChecked(true);
+ alreadyChecked = true;
+ action.run();
+ }
+
+ }
+ }
+
+ /**
+ * {@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 menuManager.getMenu();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java
new file mode 100644
index 000000000..b8c8995fc
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/AddedElementsFilter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out added elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class AddedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The predicate activate through this filter. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public AddedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@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}
+ *
+ * @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.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.ADD).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java
new file mode 100644
index 000000000..dfa072d6a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/ChangedElementsFilter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out changed elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class ChangedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public ChangedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@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}
+ *
+ * @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.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.CHANGE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/EmptyMatchedResourcesFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/EmptyMatchedResourcesFilter.java
new file mode 100644
index 000000000..355242e52
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/EmptyMatchedResourcesFilter.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out matched elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class EmptyMatchedResourcesFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public EmptyMatchedResourcesFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@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}
+ *
+ * @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.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ if (input instanceof MatchResource) {
+ EList<Diff> differences = ((MatchResource)input).getComparison().getDifferences();
+ Iterable<ResourceAttachmentChange> resourceAttachmentchanges = filter(differences,
+ ResourceAttachmentChange.class);
+ if (!isEmpty(resourceAttachmentchanges)) {
+ for (ResourceAttachmentChange rac : resourceAttachmentchanges) {
+ final String diffResourceURI = rac.getResourceURI();
+ if (!diffResourceURI.equals(((MatchResource)input).getLeftURI())
+ && !diffResourceURI.equals(((MatchResource)input).getRightURI())
+ && !diffResourceURI.equals(((MatchResource)input).getOriginURI())) {
+ return true;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java
new file mode 100644
index 000000000..496e94b7a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilter.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+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 java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+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 <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public interface IDifferenceFilter {
+
+ /**
+ * The predicate that will filter out objects in the structural differences view.
+ *
+ * @return The predicate that will filter out objects in the structural differences view.
+ */
+ Predicate<? super EObject> getPredicate();
+
+ /**
+ * 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);
+
+ /**
+ * 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}.
+ */
+ 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<IDifferenceFilter> 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();
+ }
+
+ /**
+ * The default implementation of the {@link Registry}.
+ */
+ public class RegistryImpl implements Registry {
+
+ /** A map that associates the class name to theirs {@link IDifferenceFilter}s. */
+ private final Map<String, IDifferenceFilter> map;
+
+ /**
+ * Constructs the registry.
+ */
+ public RegistryImpl() {
+ map = new ConcurrentHashMap<String, IDifferenceFilter>();
+ }
+
+ /**
+ * {@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<IDifferenceFilter> getFilters(IComparisonScope scope, Comparison comparison) {
+ Iterable<IDifferenceFilter> filters = filter(map.values(), isFilterActivable(scope, comparison));
+ List<IDifferenceFilter> ret = newArrayList();
+ for (IDifferenceFilter filter : filters) {
+ ret.add(filter);
+ }
+ return ret;
+ }
+
+ /**
+ * 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<IDifferenceFilter> isFilterActivable(final IComparisonScope scope,
+ final Comparison comparison) {
+ return new Predicate<IDifferenceFilter>() {
+ /**
+ * {@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 map.put(filter.getClass().getName(), filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#remove(java.lang.String)
+ */
+ public IDifferenceFilter remove(String className) {
+ return map.remove(className);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter.Registry#clear()
+ */
+ public void clear() {
+ map.clear();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java
new file mode 100644
index 000000000..4565236e8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/IDifferenceFilterSelectionChangeEvent.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+/**
+ * The {@link IDifferenceFilterSelectionChangeEvent} is type of event that will be posted through an event bus. When
+ * clicking on a filter through the EMF Compare UI in order to activate or deactivate it, an event of type
+ * {@link IDifferenceFilterSelectionChangeEvent} will be posted through an event bus.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public interface IDifferenceFilterSelectionChangeEvent {
+
+ /**
+ * The {@link IDifferenceFilter} associated with this event.
+ *
+ * @return The {@link IDifferenceFilter} associated with this event.
+ */
+ IDifferenceFilter getFilter();
+
+ /**
+ * The {@link Action} associated with this event.
+ *
+ * @return The {@link Action} associated with this event.
+ */
+ Action getAction();
+
+ /**
+ * The types of actions which can be associated with the events.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+ enum Action {
+ /** Corresponding to an activation of an {@link IDifferenceFilter}. */
+ ADD,
+ /** Corresponding to a deactivation of an {@link IDifferenceFilter}. */
+ REMOVE,
+ }
+
+ /**
+ * A default implementation of the {@link IDifferenceFilterSelectionChangeEvent}.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ */
+ class DefaultFilterSelectionChangeEvent implements IDifferenceFilterSelectionChangeEvent {
+
+ /** The {@link IDifferenceFilter} associated with this event. */
+ private final IDifferenceFilter filter;
+
+ /** The {@link Action} associated with this event. */
+ private final Action action;
+
+ /**
+ * Constructs the event.
+ *
+ * @param filter
+ * The {@link IDifferenceFilter} that will be associated with this event.
+ * @param action
+ * The {@link Action} that will be associated with this event.
+ */
+ public DefaultFilterSelectionChangeEvent(IDifferenceFilter filter, Action action) {
+ this.filter = filter;
+ this.action = action;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent#getFilter()
+ */
+ public IDifferenceFilter getFilter() {
+ return filter;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent#getAction()
+ */
+ public Action getAction() {
+ return action;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java
new file mode 100644
index 000000000..ad9eed0ae
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/MovedElementsFilter.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out moved elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class MovedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public MovedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@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}
+ *
+ * @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.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.MOVE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java
new file mode 100644
index 000000000..2bf51be43
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/RemovedElementsFilter.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.base.Predicate;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * A filter used by default that filtered out removed elements.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class RemovedElementsFilter implements IDifferenceFilter {
+
+ /** A human-readable label for this filter. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the filter. */
+ private boolean activeByDefault;
+
+ /** The Predicate activate through this action. */
+ private Predicate<? super EObject> predicate;
+
+ /**
+ * Constructs the filter with the appropriate predicate.
+ */
+ public RemovedElementsFilter() {
+ super();
+ setPredicate();
+ }
+
+ /**
+ * {@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}
+ *
+ * @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.IDifferenceFilter#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@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;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter#getPredicate()
+ */
+ public Predicate<? super EObject> getPredicate() {
+ return predicate;
+ }
+
+ /**
+ * Set the predicate that will be activate through this filter.
+ */
+ private void setPredicate() {
+ final Predicate<? super EObject> actualPredicate = new Predicate<EObject>() {
+ public boolean apply(EObject input) {
+ return input instanceof Diff && ofKind(DifferenceKind.DELETE).apply((Diff)input);
+ }
+ };
+ predicate = actualPredicate;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java
index 9e16ba0b3..e9b530f27 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/filter/DifferenceFilter.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/filters/StructureMergeViewerFilter.java
@@ -1,167 +1,214 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.filter;
-
-import static com.google.common.base.Predicates.not;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.DiffNode;
-import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.MatchNode;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-
-/**
- * This will be used by the structure viewer to filter out its list of differences according to a number of
- * provided predicates.
- * <p>
- * <b>Note</b> 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 <i>hidden</i> 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.
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class DifferenceFilter extends ViewerFilter {
- /** The set of predicates known by this filter. */
- private Set<Predicate<? super EObject>> predicates = Sets.newLinkedHashSet();
-
- /** List of all TreeViewers on which this filter is applied. */
- private List<TreeViewer> viewers = Lists.newArrayList();
-
- /**
- * {@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 result = false;
- final Predicate<? super EObject> predicate = Predicates.or(predicates);
-
- if (predicates.isEmpty()) {
- result = true;
- } else if (element instanceof DiffNode) {
- final Diff diff = ((DiffNode)element).getTarget();
- result = !predicate.apply(diff);
- } else if (element instanceof MatchNode) {
- final Iterator<Diff> differences = ((MatchNode)element).getTarget().getAllDifferences()
- .iterator();
- result = Iterators.any(differences, not(predicate));
- } else if (element instanceof DifferenceGroup) {
- final Iterator<? extends Diff> differences = ((DifferenceGroup)element).getDifferences()
- .iterator();
- result = Iterators.any(differences, not(predicate));
- } else if (element instanceof Adapter && ((Adapter)element).getTarget() instanceof EObject) {
- /*
- * Same code as the DiffNode case... extracted here as this is aimed at handling the cases not
- * known at the time of writing (and the case of the "MatchResource" elements).
- */
- final EObject target = (EObject)((Adapter)element).getTarget();
- result = !predicate.apply(target);
- }
-
- return result;
- }
-
- /**
- * Add a predicate to the set known by this filter.
- *
- * @param predicate
- * The new predicate for differences to be accepted by this viewer. No effect if already
- * accepted.
- */
- public void addPredicate(Predicate<? super EObject> predicate) {
- final boolean changed = predicates.add(predicate);
- if (changed) {
- refreshViewers();
- }
- }
-
- /**
- * Removes a predicate from those accepted by this filter.
- *
- * @param predicate
- * The predicate that should no longer by accepted by this filter. No effect if it was not one
- * of the accepted ones.
- */
- public void removePredicate(Predicate<? super EObject> predicate) {
- final boolean changed = predicates.remove(predicate);
- if (changed) {
- refreshViewers();
- }
- }
-
- /**
- * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
- * possible.
- */
- private void refreshViewers() {
- for (TreeViewer viewer : viewers) {
- final TreePath[] paths = viewer.getExpandedTreePaths();
- viewer.refresh();
- viewer.setExpandedTreePaths(paths);
- }
- }
-
- /**
- * Install this filter on the given viewer.
- * <p>
- * Note that this will also install a dispose listener on that viewer in order to remove the filter
- * whenever the viewer is disposed.
- * </p>
- *
- * @param viewer
- * the viewer on which the filter will be installed
- */
- public void install(final TreeViewer viewer) {
- viewer.addFilter(this);
- viewer.getTree().addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- uninstall(viewer);
- }
- });
- viewers.add(viewer);
- }
-
- /**
- * Uninstall this filter from the given viewer.
- *
- * @param viewer
- * The viewer from which the filter should be removed.
- */
- public void uninstall(TreeViewer viewer) {
- viewer.removeFilter(this);
- viewers.remove(viewer);
- }
-}
+/*******************************************************************************
+ * 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.structuremergeviewer.filters;
+
+import static com.google.common.base.Predicates.not;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.eventbus.EventBus;
+
+import java.util.Iterator;
+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.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilterSelectionChangeEvent.Action;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+
+/**
+ * This will be used by the structure viewer to filter out its list of differences according to a number of
+ * provided predicates.
+ * <p>
+ * <b>Note</b> 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 <i>hidden</i> 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.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class StructureMergeViewerFilter extends ViewerFilter {
+ /** The set of predicates known by this filter. */
+ private Set<Predicate<? super EObject>> predicates = Sets.newLinkedHashSet();
+
+ /** List of all TreeViewers on which this filter is applied. */
+ private List<TreeViewer> viewers = Lists.newArrayList();
+
+ /** The {@link EventBus} associated with this filter. */
+ private EventBus eventBus;
+
+ /**
+ * Constructs the difference filter.
+ *
+ * @param eventBus
+ * The {@link EventBus} which will be associated with this filter.
+ */
+ public StructureMergeViewerFilter(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ /**
+ * {@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 result = false;
+ final Predicate<? super EObject> predicate = Predicates.or(predicates);
+
+ if (predicates.isEmpty()) {
+ result = true;
+ } else if (element instanceof Adapter) {
+ Notifier notifier = ((Adapter)element).getTarget();
+ if (notifier instanceof Diff) {
+ final Diff diff = (Diff)notifier;
+ result = !predicate.apply(diff);
+ } else if (notifier instanceof Match) {
+ final Iterator<Diff> differences = ((Match)notifier).getAllDifferences().iterator();
+ result = Iterators.any(differences, not(predicate));
+ } else if (notifier instanceof MatchResource) {
+ final MatchResource matchResource = (MatchResource)notifier;
+ result = !predicate.apply(matchResource);
+ }
+ } else if (element instanceof DifferenceGroup) {
+ final Iterator<? extends Diff> differences = ((DifferenceGroup)element).getDifferences()
+ .iterator();
+ result = Iterators.any(differences, not(predicate));
+ } else if (element instanceof Adapter && ((Adapter)element).getTarget() instanceof EObject) {
+ /*
+ * Same code as the DiffNode case... extracted here as this is aimed at handling the cases not
+ * known at the time of writing (and the case of the "MatchResource" elements).
+ */
+ final EObject target = (EObject)((Adapter)element).getTarget();
+ result = !predicate.apply(target);
+ }
+
+ return result;
+ }
+
+ /**
+ * Add the predicate of the given {@link IDifferenceFilter}.
+ *
+ * @param filter
+ * The given {@link IDifferenceFilter}.
+ */
+ public void addFilter(IDifferenceFilter filter) {
+ addPredicate(filter.getPredicate());
+ eventBus.post(new IDifferenceFilterSelectionChangeEvent.DefaultFilterSelectionChangeEvent(filter,
+ Action.ADD));
+ }
+
+ /**
+ * Remove the predicate of the given {@link IDifferenceFilter}.
+ *
+ * @param filter
+ * The given {@link IDifferenceFilter}.
+ */
+ public void removeFilter(IDifferenceFilter filter) {
+ removePredicate(filter.getPredicate());
+ eventBus.post(new IDifferenceFilterSelectionChangeEvent.DefaultFilterSelectionChangeEvent(filter,
+ Action.REMOVE));
+ }
+
+ /**
+ * Add a predicate to the set known by this filter.
+ *
+ * @param predicate
+ * The new predicate for differences to be accepted by this viewer. No effect if already
+ * accepted.
+ */
+ public void addPredicate(Predicate<? super EObject> predicate) {
+ final boolean changed = predicates.add(predicate);
+ if (changed) {
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Removes a predicate from those accepted by this filter.
+ *
+ * @param predicate
+ * The predicate that should no longer by accepted by this filter. No effect if it was not one
+ * of the accepted ones.
+ */
+ public void removePredicate(Predicate<? super EObject> predicate) {
+ final boolean changed = predicates.remove(predicate);
+ if (changed) {
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
+ * possible.
+ */
+ private void refreshViewers() {
+ for (TreeViewer viewer : viewers) {
+ final TreePath[] paths = viewer.getExpandedTreePaths();
+ viewer.refresh();
+ viewer.setExpandedTreePaths(paths);
+ }
+ }
+
+ /**
+ * Install this filter on the given viewer.
+ * <p>
+ * Note that this will also install a dispose listener on that viewer in order to remove the filter
+ * whenever the viewer is disposed.
+ * </p>
+ *
+ * @param viewer
+ * the viewer on which the filter will be installed
+ */
+ public void install(final TreeViewer viewer) {
+ viewer.addFilter(this);
+ viewer.getTree().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ uninstall(viewer);
+ }
+ });
+ viewers.add(viewer);
+ }
+
+ /**
+ * Uninstall this filter from the given viewer.
+ *
+ * @param viewer
+ * The viewer from which the filter should be removed.
+ */
+ public void uninstall(TreeViewer viewer) {
+ viewer.removeFilter(this);
+ viewers.remove(viewer);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java
index 1ccb44c78..1a98680d4 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DefaultDifferenceGroup.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultDifferenceGroup.java
@@ -1,129 +1,137 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.swt.graphics.Image;
-
-/**
- * This implementation of a {@link DifferenceGroup} uses a predicate to filter the whole list of differences.
- * <p>
- * This can be subclasses or used directly instead of {@link DifferenceGroup}.
- * </p>
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class DefaultDifferenceGroup implements DifferenceGroup {
- /** The whole unfiltered list of differences. */
- protected final Iterable<? extends Diff> candidates;
-
- /** The filter we'll use in order to filter the differences that are part of this group. */
- protected final Predicate<? super Diff> 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 comparison that is the parent of this group. */
- protected final Comparison comparison;
-
- /**
- * Instantiates this group given the comparison and filter that should be used in order to determine its
- * list of differences.
- * <p>
- * This will use the default name and icon for the group.
- * </p>
- *
- * @param unfiltered
- * The whole unfiltered list of differences.
- * @param filter
- * The filter we'll use in order to filter the differences that are part of this group.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter) {
- this(comparison, unfiltered, filter, "Group", null);
- }
-
- /**
- * 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 unfiltered
- * The whole unfiltered list of differences.
- * @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.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter, String name) {
- this(comparison, unfiltered, filter, name, null);
- }
-
- /**
- * 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 unfiltered
- * The whole unfiltered list of differences.
- * @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.
- */
- public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
- Predicate<? super Diff> filter, String name, Image image) {
- this.comparison = comparison;
- this.candidates = unfiltered;
- this.filter = filter;
- this.name = name;
- this.image = image;
- }
-
- public Iterable<? extends Diff> getDifferences() {
- return Iterables.filter(candidates, filter);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getComparison()
- */
- public Comparison getComparison() {
- return comparison;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getName()
- */
- public String getName() {
- return name;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroup#getImage()
- */
- public Image getImage() {
- return image;
- }
-}
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This implementation of a {@link DifferenceGroup} uses a predicate to filter the whole list of differences.
+ * <p>
+ * This can be subclasses or used directly instead of {@link DifferenceGroup}.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class DefaultDifferenceGroup implements DifferenceGroup {
+ /** The whole unfiltered list of differences. */
+ protected final Iterable<? extends Diff> candidates;
+
+ /** The filter we'll use in order to filter the differences that are part of this group. */
+ protected final Predicate<? super Diff> 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 comparison that is the parent of this group. */
+ protected final Comparison comparison;
+
+ /**
+ * Instantiates this group given the comparison and filter that should be used in order to determine its
+ * list of differences.
+ * <p>
+ * This will use the default name and icon for the group.
+ * </p>
+ *
+ * @param comparison
+ * The comparison that is the parent of this group.
+ * @param unfiltered
+ * The whole unfiltered list of differences.
+ * @param filter
+ * The filter we'll use in order to filter the differences that are part of this group.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter) {
+ this(comparison, unfiltered, filter, "Group", null); //$NON-NLS-1$
+ }
+
+ /**
+ * 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 comparison
+ * The comparison that is the parent of this group.*
+ * @param unfiltered
+ * The whole unfiltered list of differences.
+ * @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.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter, String name) {
+ this(comparison, unfiltered, filter, name, null);
+ }
+
+ /**
+ * 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 unfiltered
+ * The whole unfiltered list of differences.
+ * @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.
+ */
+ public DefaultDifferenceGroup(Comparison comparison, Iterable<? extends Diff> unfiltered,
+ Predicate<? super Diff> filter, String name, Image image) {
+ this.comparison = comparison;
+ this.candidates = unfiltered;
+ this.filter = filter;
+ this.name = name;
+ this.image = image;
+ }
+
+ public Iterable<? extends Diff> getDifferences() {
+ return Iterables.filter(candidates, filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getComparison()
+ */
+ public Comparison getComparison() {
+ return comparison;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.DifferenceGroup#getImage()
+ */
+ public Image getImage() {
+ return image;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java
new file mode 100644
index 000000000..17a996008
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DefaultGroupProvider.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import java.util.Collections;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used as the default group provider.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class DefaultGroupProvider implements IDifferenceGroupProvider {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return "Default"; //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean defaultSelected) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java
index 1dbc8bd72..e265e7a53 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGroup.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/DifferenceGroup.java
@@ -1,53 +1,54 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- * @see DefaultDifferenceGroup
- */
-public interface DifferenceGroup {
- /**
- * Returns all differences that should be considered a part of this group.
- *
- * @return All differences that should be considered a part of this group.
- */
- Iterable<? extends Diff> getDifferences();
-
- /**
- * Returns the {@link Comparison} in which this group is defined.
- *
- * @return The {@link Comparison} in which this group is defined.
- */
- Comparison getComparison();
-
- /**
- * A human-readable label for this group. This will be displayed in the EMF Compare UI.
- *
- * @return A human-readable label for this group that can be displayed to the user.
- */
- String getName();
-
- /**
- * 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();
-}
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @see DefaultDifferenceGroup
+ * @since 3.0
+ */
+public interface DifferenceGroup {
+ /**
+ * Returns all differences that should be considered a part of this group.
+ *
+ * @return All differences that should be considered a part of this group.
+ */
+ Iterable<? extends Diff> getDifferences();
+
+ /**
+ * Returns the {@link Comparison} in which this group is defined.
+ *
+ * @return The {@link Comparison} in which this group is defined.
+ */
+ Comparison getComparison();
+
+ /**
+ * A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @return A human-readable label for this group that can be displayed to the user.
+ */
+ String getName();
+
+ /**
+ * 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();
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java
new file mode 100644
index 000000000..29ff8bb15
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/IDifferenceGroupProvider.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+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 java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * Instances of this class will be used by EMF Compare in order to provide difference grouping facilities to
+ * the structural differences view.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public interface IDifferenceGroupProvider {
+
+ /**
+ * 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.
+ */
+ Iterable<? extends DifferenceGroup> getGroups(Comparison comparison);
+
+ /**
+ * A human-readable label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @return The label for this group.
+ */
+ String getLabel();
+
+ /**
+ * Set the label for this group. This will be displayed in the EMF Compare UI.
+ *
+ * @param label
+ * A human-readable label for this group.
+ */
+ void setLabel(String label);
+
+ /**
+ * Returns the initial activation state that the group should have.
+ *
+ * @return The initial activation state that the group should have.
+ */
+ boolean defaultSelected();
+
+ /**
+ * Set the initial activation state that the group should have.
+ *
+ * @param defaultSelected
+ * The initial activation state that the group should have (true if the group 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 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);
+
+ /**
+ * 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<IDifferenceGroupProvider> getGroupProviders(IComparisonScope scope, Comparison comparison);
+
+ /**
+ * Add to the registry the given {@link IDifferenceGroupProvider}.
+ *
+ * @param provider
+ * The given {@link IDifferenceGroupProvider}.
+ * @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 add(IDifferenceGroupProvider provider);
+
+ /**
+ * 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 remove(String className);
+
+ /**
+ * Clear the registry.
+ */
+ void clear();
+ }
+
+ /**
+ * The default implementation of the {@link Registry}.
+ */
+ public class RegistryImpl implements Registry {
+
+ /** A map that associates the class name to theirs {@link IDifferenceGroupProvider}s. */
+ private final Map<String, IDifferenceGroupProvider> map;
+
+ /**
+ * Constructs the registry.
+ */
+ public RegistryImpl() {
+ map = new ConcurrentHashMap<String, IDifferenceGroupProvider>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#getGroupProviders(IComparisonScope,
+ * Comparison)
+ */
+ public List<IDifferenceGroupProvider> getGroupProviders(IComparisonScope scope, Comparison comparison) {
+ Iterable<IDifferenceGroupProvider> providers = filter(map.values(), isGroupProviderActivable(
+ scope, comparison));
+ List<IDifferenceGroupProvider> ret = newArrayList();
+ for (IDifferenceGroupProvider provider : providers) {
+ ret.add(provider);
+ }
+ return ret;
+ }
+
+ /**
+ * 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<IDifferenceGroupProvider> isGroupProviderActivable(
+ final IComparisonScope scope, final Comparison comparison) {
+ return new Predicate<IDifferenceGroupProvider>() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(IDifferenceGroupProvider d) {
+ return d.isEnabled(scope, comparison);
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#add
+ * (org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider)
+ */
+ public IDifferenceGroupProvider add(IDifferenceGroupProvider provider) {
+ Preconditions.checkNotNull(provider);
+ return map.put(provider.getClass().getName(), provider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#remove(java.lang.String)
+ * )
+ */
+ public IDifferenceGroupProvider remove(String className) {
+ return map.remove(className);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Registry#clear()
+ */
+ public void clear() {
+ map.clear();
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java
new file mode 100644
index 000000000..1ad46144f
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/KindGroupProvider.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * {@link DifferenceKind kind} : additions, deletions, changes and moves.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class KindGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final DifferenceGroup additions = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.ADD), "Additions"); //$NON-NLS-1$
+ final DifferenceGroup deletions = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.DELETE), "Deletions"); //$NON-NLS-1$
+ final DifferenceGroup changes = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.CHANGE), "Changes"); //$NON-NLS-1$
+ final DifferenceGroup moves = new DefaultDifferenceGroup(comparison, diffs,
+ ofKind(DifferenceKind.MOVE), "Moves"); //$NON-NLS-1$
+
+ return ImmutableList.of(additions, deletions, changes, moves);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java
index 3ad299a31..3c61cc0a7 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/MetamodelGroupProvider.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/MetamodelGroupProvider.java
@@ -1,97 +1,159 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import static com.google.common.base.Predicates.alwaysTrue;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.emf.compare.AttributeChange;
-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.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * This implementation of a {@link DifferenceGroupProvider} will be used to group the differences by their
- * metamodel element : all diffs that apply to a Class, all diffs that apply on a reference...
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public class MetamodelGroupProvider implements DifferenceGroupProvider {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.actions.group.DifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
- */
- public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
- final List<Diff> diffs = comparison.getDifferences();
-
- final Map<EClass, List<Diff>> diffByEClass = Maps.newLinkedHashMap();
- for (Diff candidate : diffs) {
- final EClass target;
- if (candidate instanceof ReferenceChange) {
- if (((ReferenceChange)candidate).getReference().isContainment()) {
- final EObject parentMatch = candidate.getMatch().eContainer();
- if (parentMatch instanceof Match) {
- target = findEClass((Match)parentMatch);
- } else {
- target = findEClass(candidate.getMatch());
- }
- } else {
- target = findEClass(candidate.getMatch());
- }
- } else if (candidate instanceof AttributeChange) {
- target = findEClass(candidate.getMatch());
- } else {
- // Ignore this possibility for now.
- continue;
- }
-
- List<Diff> diffsForEClass = diffByEClass.get(target);
- if (diffsForEClass == null) {
- diffsForEClass = Lists.newArrayList();
- diffByEClass.put(target, diffsForEClass);
- }
- diffsForEClass.add(candidate);
- }
-
- final List<DifferenceGroup> groups = Lists.newArrayList();
- for (Map.Entry<EClass, List<Diff>> entry : diffByEClass.entrySet()) {
- groups.add(new DefaultDifferenceGroup(comparison, entry.getValue(), alwaysTrue(), entry.getKey()
- .getName()));
- }
-
- return groups;
- }
-
- private EClass findEClass(Match match) {
- final EClass eClass;
- if (match.getOrigin() != null) {
- eClass = match.getOrigin().eClass();
- } else if (match.getRight() != null) {
- eClass = match.getRight().eClass();
- } else {
- /*
- * All three sides null means that something went awry. Might as well throw the exception from
- * here.
- */
- eClass = match.getLeft().eClass();
- }
- return eClass;
- }
-}
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import static com.google.common.base.Predicates.alwaysTrue;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.compare.AttributeChange;
+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.scope.IComparisonScope;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * metamodel element : all diffs that apply to a Class, all diffs that apply on a reference...
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class MetamodelGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final Map<EClass, List<Diff>> diffByEClass = Maps.newLinkedHashMap();
+ for (Diff candidate : diffs) {
+ final EClass target;
+ if (candidate instanceof ReferenceChange) {
+ if (((ReferenceChange)candidate).getReference().isContainment()) {
+ final EObject parentMatch = candidate.getMatch().eContainer();
+ if (parentMatch instanceof Match) {
+ target = findEClass((Match)parentMatch);
+ } else {
+ target = findEClass(candidate.getMatch());
+ }
+ } else {
+ target = findEClass(candidate.getMatch());
+ }
+ } else if (candidate instanceof AttributeChange) {
+ target = findEClass(candidate.getMatch());
+ } else {
+ // Ignore this possibility for now.
+ continue;
+ }
+
+ List<Diff> diffsForEClass = diffByEClass.get(target);
+ if (diffsForEClass == null) {
+ diffsForEClass = Lists.newArrayList();
+ diffByEClass.put(target, diffsForEClass);
+ }
+ diffsForEClass.add(candidate);
+ }
+
+ final List<DifferenceGroup> groups = Lists.newArrayList();
+ for (Map.Entry<EClass, List<Diff>> entry : diffByEClass.entrySet()) {
+ groups.add(new DefaultDifferenceGroup(comparison, entry.getValue(), alwaysTrue(), entry.getKey()
+ .getName()));
+ }
+
+ return groups;
+ }
+
+ /**
+ * Returns the appropriate {@link EClass} associated with the given {@link Match}.
+ *
+ * @param match
+ * The given {@link Match}.
+ * @return the appropriate {@link EClass} associated with the given {@link Match}.
+ */
+ private EClass findEClass(Match match) {
+ final EClass eClass;
+ if (match.getOrigin() != null) {
+ eClass = match.getOrigin().eClass();
+ } else if (match.getRight() != null) {
+ eClass = match.getRight().eClass();
+ } else {
+ /*
+ * All three sides null means that something went awry. Might as well throw the exception from
+ * here.
+ */
+ eClass = match.getLeft().eClass();
+ }
+ return eClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java
index a1c3182b0..0b8564d5c 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/actions/group/DifferenceGrouper.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/StructureMergeViewerGrouper.java
@@ -1,131 +1,147 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.ide.ui.internal.actions.group;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.jface.viewers.TreePath;
-import org.eclipse.jface.viewers.TreeViewer;
-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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
-public final class DifferenceGrouper {
- /**
- * The currently selected group provider. This is what will compute and give us the groups we need to
- * display.
- */
- private DifferenceGroupProvider provider;
-
- /** List of all TreeViewers on which this filter is applied. */
- private List<TreeViewer> viewers = Lists.newArrayList();
-
- /**
- * This will be called internally by the ComparisonNode in order to know how it should group its
- * differences.
- *
- * @param comparison
- * The comparison which differences need to be grouped.
- * @return The collection of groups we could retrieve from the currently selected group provider. Empty
- * {@link Iterable} if we have no group provider set.
- */
- public Iterable<? extends DifferenceGroup> getGroups(final Comparison comparison) {
- if (provider == null) {
- return ImmutableList.of();
- }
-
- final Iterable<? extends DifferenceGroup> groups = provider.getGroups(comparison);
- final Iterable<? extends DifferenceGroup> filteredGroups = Iterables.filter(groups,
- new NonEmptyGroup());
- return filteredGroups;
- }
-
- /**
- * 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(DifferenceGroupProvider provider) {
- if (this.provider != provider) {
- this.provider = provider;
- refreshViewers();
- }
- }
-
- /**
- * Refreshes the viewers registered with this filter. Will try and conserve the expanded tree paths when
- * possible.
- */
- private void refreshViewers() {
- for (TreeViewer viewer : viewers) {
- final TreePath[] paths = viewer.getExpandedTreePaths();
- viewer.refresh();
- viewer.setExpandedTreePaths(paths);
- }
- }
-
- /**
- * Install this filter on the given viewer.
- * <p>
- * Note that this will also install a dispose listener on that viewer in order to remove the filter
- * whenever the viewer is disposed.
- * </p>
- *
- * @param viewer
- * the viewer on which the filter will be installed
- */
- public void install(final TreeViewer viewer) {
- viewer.getTree().addDisposeListener(new DisposeListener() {
- public void widgetDisposed(DisposeEvent e) {
- uninstall(viewer);
- }
- });
- viewers.add(viewer);
- }
-
- /**
- * Uninstall this filter from the given viewer.
- *
- * @param viewer
- * The viewer from which the filter should be removed.
- */
- public void uninstall(TreeViewer viewer) {
- viewers.remove(viewer);
- }
-
- /**
- * This predicate will be used to filter the empty groups out of the displayed list.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
- private static class NonEmptyGroup implements Predicate<DifferenceGroup> {
- /**
- * {@inheritDoc}
- *
- * @see com.google.common.base.Predicate#apply(java.lang.Object)
- */
- public boolean apply(DifferenceGroup input) {
- return input != null && !Iterables.isEmpty(input.getDifferences());
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeViewer;
+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 <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public final class StructureMergeViewerGrouper {
+ /**
+ * 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 List<TreeViewer> viewers = Lists.newArrayList();
+
+ /** The {@link EventBus} associated with this grouper. */
+ private EventBus eventBus;
+
+ /**
+ * Constructs the difference grouper.
+ *
+ * @param eventBus
+ * The {@link EventBus} which will be associated with this difference grouper.
+ */
+ public StructureMergeViewerGrouper(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ /**
+ * This will be called internally by the ComparisonNode in order to know how it should group its
+ * differences.
+ *
+ * @param comparison
+ * The comparison which differences need to be grouped.
+ * @return The collection of groups we could retrieve from the currently selected group provider. Empty
+ * {@link Iterable} if we have no group provider set.
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(final Comparison comparison) {
+ if (provider == null) {
+ return ImmutableList.of();
+ }
+
+ final Iterable<? extends DifferenceGroup> groups = provider.getGroups(comparison);
+ final Iterable<? extends DifferenceGroup> filteredGroups = Iterables.filter(groups,
+ new NonEmptyGroup());
+ return filteredGroups;
+ }
+
+ /**
+ * 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;
+ eventBus.post(provider);
+ refreshViewers();
+ }
+ }
+
+ /**
+ * Refreshes the viewers registered with this grouper. Will try and conserve the expanded tree paths when
+ * possible.
+ */
+ private void refreshViewers() {
+ for (TreeViewer viewer : viewers) {
+ final TreePath[] paths = viewer.getExpandedTreePaths();
+ viewer.refresh();
+ viewer.setExpandedTreePaths(paths);
+ }
+ }
+
+ /**
+ * Install this grouper on the given viewer.
+ * <p>
+ * Note that this will also install a dispose listener on that viewer in order to remove the grouper
+ * whenever the viewer is disposed.
+ * </p>
+ *
+ * @param viewer
+ * The viewer on which the grouper will be installed.
+ */
+ public void install(final TreeViewer viewer) {
+ viewer.getTree().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(TreeViewer viewer) {
+ viewers.remove(viewer);
+ }
+
+ /**
+ * This predicate will be used to filter the empty groups out of the displayed list.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+ private static class NonEmptyGroup implements Predicate<DifferenceGroup> {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(DifferenceGroup input) {
+ return input != null && !Iterables.isEmpty(input.getDifferences());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java
new file mode 100644
index 000000000..6e1f8ec42
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/structuremergeviewer/groups/ThreeWayComparisonGroupProvider.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.structuremergeviewer.groups;
+
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasConflict;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+
+/**
+ * This implementation of a {@link IDifferenceGroupProvider} will be used to group the differences by their
+ * {@link DifferenceSource side} : left, right and conflicts.
+ *
+ * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
+ * @since 3.0
+ */
+public class ThreeWayComparisonGroupProvider implements IDifferenceGroupProvider {
+
+ /** A human-readable label for this group provider. This will be displayed in the EMF Compare UI. */
+ private String label;
+
+ /** The initial activation state of the group provider. */
+ private boolean activeByDefault;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getGroups(org.eclipse.emf.compare.Comparison)
+ */
+ public Iterable<? extends DifferenceGroup> getGroups(Comparison comparison) {
+ final List<Diff> diffs = comparison.getDifferences();
+
+ final DifferenceGroup leftSide = new DefaultDifferenceGroup(comparison, diffs, Predicates.and(
+ fromSide(DifferenceSource.LEFT), Predicates.not(hasConflict(ConflictKind.REAL))), "Left side"); //$NON-NLS-1$
+ final DifferenceGroup rightSide = new DefaultDifferenceGroup(comparison, diffs, Predicates.and(
+ fromSide(DifferenceSource.RIGHT), Predicates.not(hasConflict(ConflictKind.REAL))),
+ "Right side"); //$NON-NLS-1$
+ final DifferenceGroup conflicts = new DefaultDifferenceGroup(comparison, diffs,
+ hasConflict(ConflictKind.REAL), "Conflicts"); //$NON-NLS-1$
+
+ return ImmutableList.of(leftSide, rightSide, conflicts);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#getLabel()
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setLabel(java.lang.String)
+ */
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#defaultSelected()
+ */
+ public boolean defaultSelected() {
+ return activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#setDefaultSelected(boolean)
+ */
+ public void setDefaultSelected(boolean activeByDefault) {
+ this.activeByDefault = activeByDefault;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider#isEnabled(org
+ * .eclipse.emf.compare.scope.IComparisonScope, org.eclipse.emf.compare.Comparison)
+ */
+ public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
+ if (comparison != null && comparison.isThreeWay()) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
index cee9ebe6f..9876c270b 100644
--- a/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
@@ -20,6 +20,7 @@ Require-Bundle: org.eclipse.core.runtime,
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.emf.compare.tests.framework,
+ org.eclipse.emf.compare.tests.merge,
org.eclipse.emf.compare.tests.nodes,
org.eclipse.emf.compare.tests.nodes.impl,
org.eclipse.emf.compare.tests.nodes.util,
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/FuzzyTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/FuzzyTest.java
index cfd3f0b2f..82cec52da 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/FuzzyTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/FuzzyTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -19,12 +19,16 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.match.eobject.URIDistance;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcorePackage;
@@ -47,6 +51,7 @@ import org.junit.runner.RunWith;
*/
@RunWith(FuzzyRunner.class)
@DataProvider(EMFDataProvider.class)
+@SuppressWarnings("nls")
public class FuzzyTest {
@Data
@@ -55,6 +60,8 @@ public class FuzzyTest {
@Util
private MutateUtil util;
+ private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
/**
* Test to check if the {@link FuzzyRunner} is working.
*/
@@ -81,10 +88,8 @@ public class FuzzyTest {
Comparison result = EMFCompare.builder().build().compare(EMFCompare.createDefaultScope(root, backup));
int nbDiffs = result.getDifferences().size();
-
- for (Diff delta : result.getDifferences()) {
- delta.copyRightToLeft();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(result.getDifferences(), new BasicMonitor());
for (Diff delta : result.getDifferences()) {
assertSame(delta.getState(), DifferenceState.MERGED);
@@ -111,7 +116,8 @@ public class FuzzyTest {
if (diff.getMatch().getRight() != null) {
String uri = new URIDistance().apply(diff.getMatch().getRight()).toString();
if (urisToDebug.contains(uri)) {
- diff.copyRightToLeft();
+ final IMerger diffMerger = mergerRegistry.getHighestRankingMerger(diff);
+ diffMerger.copyRightToLeft(diff, new BasicMonitor());
}
}
}
@@ -136,9 +142,8 @@ public class FuzzyTest {
Comparison result = EMFCompare.builder().build().compare(EMFCompare.createDefaultScope(root, backup));
int nbDiffs = result.getDifferences().size();
- for (Diff delta : result.getDifferences()) {
- delta.copyLeftToRight();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(result.getDifferences(), new BasicMonitor());
Comparison valid = EMFCompare.builder().build().compare(EMFCompare.createDefaultScope(root, backup));
List<Diff> differences = valid.getDifferences();
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java
new file mode 100644
index 000000000..588b8c798
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/LCSPerformanceTest.java
@@ -0,0 +1,150 @@
+/**
+ * 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.tests.diff;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceKind;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.tests.nodes.Node;
+import org.eclipse.emf.compare.tests.nodes.NodesFactory;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This will specifically make sure that merging two large lists never takes more than a set amount of time.
+ * <p>
+ * I have a list (S1) on the left side that contains 2000 elements. Its counterpart on the right side (S2) has
+ * 200 elements, only 100 of which are not differences (i.e. : also present in S1). We'll make sure that
+ * merging these two lists is fast enough (through test timeouts).
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+@SuppressWarnings("nls")
+public class LCSPerformanceTest {
+ private XMIResource left;
+
+ private XMIResource right;
+
+ @Before
+ public void setup() {
+ left = new XMIResourceImpl(URI.createURI("left.xmi"));
+ right = new XMIResourceImpl(URI.createURI("right.xmi"));
+
+ createNode(left, 2000, 0, 1);
+ createNode(right, 200, 0, 1901);
+ }
+
+ @Test
+ public void checkTestData() {
+ assertTrue(left.getContents().size() == 1);
+ final Node leftRoot = (Node)left.getContents().get(0);
+ assertTrue(leftRoot.eContents().size() == 2000);
+
+ assertTrue(right.getContents().size() == 1);
+ final Node rightRoot = (Node)right.getContents().get(0);
+ assertTrue(rightRoot.eContents().size() == 200);
+
+ IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
+ Comparison comparison = EMFCompare.builder().build().compare(scope);
+
+ final List<Diff> additions = Lists.newArrayList();
+ final List<Diff> deletions = Lists.newArrayList();
+
+ for (Diff difference : comparison.getDifferences()) {
+ if (difference.getKind() == DifferenceKind.ADD) {
+ additions.add(difference);
+ } else {
+ deletions.add(difference);
+ }
+ }
+
+ assertEquals(Integer.valueOf(1900), Integer.valueOf(additions.size()));
+ assertEquals(Integer.valueOf(100), Integer.valueOf(deletions.size()));
+ }
+
+ /**
+ * Will fail if {@link #checkTestData()} does.
+ * <p>
+ * The real assertion here is that this should never take more than 40 seconds to execute. We have 1900
+ * additions to merge, accounting for as many LCS computations.
+ * </p>
+ * <p>
+ * Note that this test should run in less than 30 seconds... However that is not true on our build
+ * machine, so the timeout has been raised to 60s.
+ * </p>
+ */
+ @Test(timeout = 60000)
+ public void copyLeftToRight() {
+ IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
+ Comparison comparison = EMFCompare.builder().build().compare(scope);
+
+ final IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ final IBatchMerger merger = new BatchMerger(registry);
+ merger.copyAllLeftToRight(comparison.getDifferences(), new BasicMonitor());
+
+ comparison = EMFCompare.builder().build().compare(scope);
+ assertTrue(comparison.getDifferences().isEmpty());
+ }
+
+ /**
+ * Will fail if {@link #checkTestData()} does.
+ * <p>
+ * The real assertion here is that this should never take more than 3 seconds to execute : we're resetting
+ * all differences so there are only 100 "slow" ones : resetting deletions need the LCS computation.
+ * </p>
+ */
+ @Test(timeout = 3000)
+ public void copyRightToLeft() {
+ IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
+ Comparison comparison = EMFCompare.builder().build().compare(scope);
+
+ final IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ final IBatchMerger merger = new BatchMerger(registry);
+ merger.copyAllRightToLeft(comparison.getDifferences(), new BasicMonitor());
+
+ comparison = EMFCompare.builder().build().compare(scope);
+ assertTrue(comparison.getDifferences().isEmpty());
+ }
+
+ private void createNode(XMIResource resource, int childCount, int nodeId, int idGap) {
+ resource.eSetDeliver(false);
+ Node node = NodesFactory.eINSTANCE.createNode();
+ node.setName("node" + nodeId);
+ resource.getContents().add(node);
+ resource.setID(node, Integer.toString(nodeId));
+ int childId = nodeId + Math.max(1, idGap);
+ for (int i = 0; i < childCount; i++) {
+ Node child = NodesFactory.eINSTANCE.createNode();
+ child.setName("node" + childId);
+ node.getContainmentRef1().add(child);
+ resource.setID(child, Integer.toString(childId));
+ childId++;
+ }
+ resource.eSetDeliver(true);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fragmentation/FragmentationTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fragmentation/FragmentationTest.java
index de6495fe8..2773c7a0c 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fragmentation/FragmentationTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fragmentation/FragmentationTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -23,6 +23,7 @@ import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
@@ -31,6 +32,9 @@ import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.fragmentation.data.FragmentationInputData;
import org.eclipse.emf.ecore.EObject;
@@ -45,6 +49,8 @@ import org.junit.Test;
public class FragmentationTest {
private final FragmentationInputData input = new FragmentationInputData();
+ private final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@Test
public void testUncontroledObjectResourceSet() throws IOException {
final Resource left = input.getUncontrolLeft();
@@ -103,7 +109,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(1), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(originSet.getResources().size()));
// Still two resources, though one is empty
@@ -156,7 +162,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(originSet.getResources().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(rightSet.getResources().size()));
@@ -231,9 +237,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyLeftToRight();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -284,9 +289,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyRightToLeft();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -379,7 +383,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(originSet.getResources().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(rightSet.getResources().size()));
@@ -425,7 +429,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// Note : we still have 2 resources there, though one is empty
assertSame(Integer.valueOf(2), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(originSet.getResources().size()));
@@ -507,9 +511,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyLeftToRight();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -560,9 +563,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyRightToLeft();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -655,7 +657,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(originSet.getResources().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(rightSet.getResources().size()));
@@ -701,7 +703,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// Note : we still have 2 resources there, though one is empty
assertSame(Integer.valueOf(2), Integer.valueOf(leftSet.getResources().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(originSet.getResources().size()));
@@ -783,9 +785,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyLeftToRight();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -836,9 +837,8 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
- for (Diff diff : differences) {
- diff.copyRightToLeft();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
final EObject leftFragmentedNode = getNodeNamed(left, "fragmented");
final EObject originFragmentedNode = getNodeNamed(origin, "fragmented");
@@ -931,7 +931,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(1), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(right.getContents().size()));
@@ -969,7 +969,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(right.getContents().size()));
@@ -1012,7 +1012,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(1), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(right.getContents().size()));
@@ -1042,7 +1042,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(right.getContents().size()));
@@ -1113,7 +1113,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(right.getContents().size()));
@@ -1151,7 +1151,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
assertSame(Integer.valueOf(1), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(right.getContents().size()));
@@ -1198,7 +1198,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
assertSame(Integer.valueOf(2), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(2), Integer.valueOf(right.getContents().size()));
@@ -1228,7 +1228,7 @@ public class FragmentationTest {
final List<Diff> differences = comparison.getDifferences();
final Diff diff = differences.get(0);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
assertSame(Integer.valueOf(1), Integer.valueOf(left.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(origin.getContents().size()));
assertSame(Integer.valueOf(1), Integer.valueOf(right.getContents().size()));
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DynamicInstanceComparisonTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DynamicInstanceComparisonTest.java
index 4750ba450..f3c1c20d4 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DynamicInstanceComparisonTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/fullcomparison/DynamicInstanceComparisonTest.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -14,9 +14,12 @@ import static org.junit.Assert.assertEquals;
import java.io.IOException;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.fullcomparison.data.dynamic.DynamicInstancesInputData;
import org.eclipse.emf.compare.tests.suite.AllTests;
@@ -39,6 +42,8 @@ public class DynamicInstanceComparisonTest {
Resource origin;
+ final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@Before
public void setUp() throws Exception {
AllTests.fillEMFRegistries();
@@ -68,9 +73,10 @@ public class DynamicInstanceComparisonTest {
Comparison result = EMFCompare.builder().build().compare(scope);
assertEquals("We are supposed to have one difference (ADD/REMOVE of an instance)", 1, result
.getDifferences().size());
- for (Diff diff : result.getDifferences()) {
- diff.copyLeftToRight();
- }
+
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(result.getDifferences(), new BasicMonitor());
+
assertEquals("We are supposed to have no difference as we merged everything", 0, EMFCompare.builder()
.build().compare(scope).getDifferences().size());
}
@@ -81,9 +87,10 @@ public class DynamicInstanceComparisonTest {
Comparison result = EMFCompare.builder().build().compare(scope);
assertEquals("We are supposed to have one difference (ADD/REMOVE of an instance)", 1, result
.getDifferences().size());
- for (Diff diff : result.getDifferences()) {
- diff.copyRightToLeft();
- }
+
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(result.getDifferences(), new BasicMonitor());
+
assertEquals("We are supposed to have no difference as we merged everything", 0, EMFCompare.builder()
.build().compare(scope).getDifferences().size());
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ExtensionMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ExtensionMergeTest.java
new file mode 100644
index 000000000..bff8becdd
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ExtensionMergeTest.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.tests.merge;
+
+import static com.google.common.base.Predicates.and;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.changedAttribute;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
+
+import com.google.common.collect.Iterators;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.merge.AbstractMerger;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.tests.merge.data.IndividualDiffInputData;
+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.EcoreUtil;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class ExtensionMergeTest {
+ private IndividualDiffInputData input = new IndividualDiffInputData();
+
+ @Test
+ public void testInstantiationMerger() throws IOException {
+ final Resource left = input.getAttributeMonoChangeLeft();
+ final Resource right = input.getAttributeMonoChangeRight();
+
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
+ Comparison comparison = EMFCompare.builder().build().compare(scope);
+
+ final List<Diff> differences = comparison.getDifferences();
+ assertSame(Integer.valueOf(1), Integer.valueOf(differences.size()));
+
+ final String featureName = "singleValuedAttribute";
+ final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
+ changedAttribute("root.origin", featureName, "originValue", "leftValue")));
+
+ IMerger merger = getMerger(IMerger.RegistryImpl.createStandaloneInstance(), diff,
+ AbstractMerger.class);
+ merger.copyLeftToRight(diff, null);
+
+ final EObject originNode = getNodeNamed(right, "origin");
+ assertNotNull(originNode);
+ final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
+ assertNotNull(feature);
+
+ assertEquals("leftValue", originNode.eGet(feature));
+
+ comparison = EMFCompare.builder().build().compare(scope);
+ assertSame(Integer.valueOf(0), Integer.valueOf(comparison.getDifferences().size()));
+ }
+
+ public static IMerger getMerger(final IMerger.Registry registry, final Diff diff,
+ final Class<? extends IMerger> expectedMerger) {
+ IMerger merger = registry.getHighestRankingMerger(diff);
+ assertNotNull("No merger has been found for the diff: " + diff, merger);
+ assertTrue("The found merger is not the expexted Merger", expectedMerger.isInstance(merger));
+ return merger;
+ }
+
+ private EObject getNodeNamed(Resource res, String name) {
+ final Iterator<EObject> iterator = EcoreUtil.getAllProperContents(res, false);
+ while (iterator.hasNext()) {
+ final EObject next = iterator.next();
+ final EStructuralFeature nameFeature = next.eClass().getEStructuralFeature("name");
+ if (nameFeature != null && name.equals(next.eGet(nameFeature))) {
+ return next;
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeOutOfScopeValuesTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeOutOfScopeValuesTest.java
index a9eec8071..09d982711 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeOutOfScopeValuesTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeOutOfScopeValuesTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -21,11 +21,13 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.List;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.merge.data.IndividualDiffInputData;
import org.eclipse.emf.ecore.EObject;
@@ -39,6 +41,8 @@ import org.junit.Test;
public class IndividualMergeOutOfScopeValuesTest {
private IndividualDiffInputData input = new IndividualDiffInputData();
+ private final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@Test
public void testReferenceMonoChange2WayLtR() throws IOException {
final Resource left = input.getReferenceMonoChangeLeftOutOfScope();
@@ -63,7 +67,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -106,7 +110,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -152,7 +156,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -206,7 +210,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -258,7 +262,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -310,7 +314,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -361,7 +365,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -404,7 +408,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -448,7 +452,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -498,7 +502,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -545,7 +549,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -592,7 +596,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -639,7 +643,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -680,7 +684,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -726,7 +730,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -774,7 +778,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -823,7 +827,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -872,7 +876,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -917,7 +921,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -977,7 +981,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1039,7 +1043,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1114,7 +1118,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1187,7 +1191,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1260,7 +1264,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1332,7 +1336,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1391,7 +1395,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(leftDiffContainer, diff.getMatch().getLeft());
assertSame(rightDiffContainer, diff.getMatch().getRight());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1454,7 +1458,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1530,7 +1534,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1606,7 +1610,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1680,7 +1684,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertSame(rightDiffContainer, diff.getMatch().getRight());
assertSame(originDiffContainer, diff.getMatch().getOrigin());
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1768,7 +1772,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertTrue(rightProxyIndex != -1);
assertFalse(leftProxyIndex == rightProxyIndex);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1830,7 +1834,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertTrue(rightProxyIndex != -1);
assertFalse(leftProxyIndex == rightProxyIndex);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1900,7 +1904,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertFalse(leftProxyIndex == rightProxyIndex);
assertEquals(rightProxyIndex, originProxyIndex);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -1977,7 +1981,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertFalse(leftProxyIndex == rightProxyIndex);
assertEquals(rightProxyIndex, originProxyIndex);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -2053,7 +2057,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertFalse(leftProxyIndex == rightProxyIndex);
assertEquals(leftProxyIndex, originProxyIndex);
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
@@ -2129,7 +2133,7 @@ public class IndividualMergeOutOfScopeValuesTest {
assertFalse(leftProxyIndex == rightProxyIndex);
assertEquals(leftProxyIndex, originProxyIndex);
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
// The proxy should not have been resolved by the merge operation
assertTrue(diff.getValue().eIsProxy());
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeTest.java
index 7c8605001..1f8378585 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/IndividualMergeTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -34,11 +34,13 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.merge.data.IndividualDiffInputData;
import org.eclipse.emf.ecore.EObject;
@@ -51,6 +53,8 @@ import org.junit.Test;
public class IndividualMergeTest {
private IndividualDiffInputData input = new IndividualDiffInputData();
+ private final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@Test
public void testAttributeMonoChange2WayLtR() throws IOException {
final Resource left = input.getAttributeMonoChangeLeft();
@@ -66,7 +70,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -93,7 +97,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -121,7 +125,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -151,7 +155,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -180,7 +184,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -209,7 +213,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, "originValue", "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -238,7 +242,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -265,7 +269,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -293,7 +297,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -323,7 +327,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -352,7 +356,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -381,7 +385,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, null, "leftValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -410,7 +414,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -437,7 +441,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -465,7 +469,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -495,7 +499,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -524,7 +528,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -553,7 +557,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedAttribute("root.origin", featureName, "originValue", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -582,7 +586,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -611,7 +615,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -641,7 +645,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -673,7 +677,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -704,7 +708,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -735,7 +739,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
addedToAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -766,7 +770,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -795,7 +799,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -825,7 +829,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -857,7 +861,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -888,7 +892,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -919,7 +923,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
removedFromAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -951,7 +955,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(left, "origin");
@@ -985,7 +989,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(right, "origin");
@@ -1020,7 +1024,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(left, "origin");
@@ -1057,7 +1061,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(origin, "origin");
@@ -1093,7 +1097,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(origin, "origin");
@@ -1129,7 +1133,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
movedInAttribute("root.origin", featureName, "value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(right, "origin");
@@ -1164,7 +1168,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "targetValue");
@@ -1193,7 +1197,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "originValue");
@@ -1223,7 +1227,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "targetValue");
@@ -1255,7 +1259,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "originValue");
@@ -1286,7 +1290,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "originValue");
@@ -1317,7 +1321,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, "root.originValue", "root.targetValue")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "targetValue");
@@ -1348,7 +1352,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "left");
@@ -1377,7 +1381,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1405,7 +1409,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "left");
@@ -1437,7 +1441,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1466,7 +1470,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1495,7 +1499,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, null, "root.left")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "left");
@@ -1526,7 +1530,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1553,7 +1557,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1583,7 +1587,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1613,7 +1617,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1644,7 +1648,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1675,7 +1679,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
changedReference("root.origin", featureName, "root.target", null)));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EStructuralFeature feature = originNode.eClass().getEStructuralFeature(featureName);
@@ -1704,7 +1708,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1735,7 +1739,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1767,7 +1771,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1801,7 +1805,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1834,7 +1838,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1867,7 +1871,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
addedToReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1900,7 +1904,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1931,7 +1935,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -1963,7 +1967,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -1997,7 +2001,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -2030,7 +2034,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(right, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(right, "target");
@@ -2063,7 +2067,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
removedFromReference("root.origin", featureName, "root.target")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject originNode = getNodeNamed(left, "origin");
assertNotNull(originNode);
final EObject targetNode = getNodeNamed(left, "target");
@@ -2097,7 +2101,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(left, "origin");
@@ -2132,7 +2136,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(right, "origin");
@@ -2168,7 +2172,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(left, "origin");
@@ -2206,7 +2210,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.LEFT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(origin, "origin");
@@ -2243,7 +2247,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(right, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(origin, "origin");
@@ -2280,7 +2284,7 @@ public class IndividualMergeTest {
final Diff diff = Iterators.find(differences.iterator(), and(fromSide(DifferenceSource.RIGHT),
movedInReference("root.origin", featureName, "root.value1")));
- diff.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
final EObject targetNode = getNodeNamed(left, "origin");
assertNotNull(targetNode);
final EObject sourceNode = getNodeNamed(right, "origin");
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
index 422b3812f..b47976df8 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -31,6 +31,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.List;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
@@ -38,6 +39,7 @@ import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.conflict.data.ConflictInputData;
import org.eclipse.emf.compare.tests.equi.data.EquiInputData;
@@ -53,6 +55,8 @@ public class MultipleMergeTest {
private EquiInputData equivalenceInput = new EquiInputData();
+ private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@Test
public void testComplexUseCaseLtoR1() throws IOException {
final Resource left = conflictInput.getComplexLeft();
@@ -99,7 +103,7 @@ public class MultipleMergeTest {
final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node8")));
// LCS is currently {2, 3, 4}. Insertion index is right before 2.
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertValueIndexIs(diff1, false, 1);
// merge 2 (add Node9). Since there is a conflict, merge 9 right beforehand
@@ -108,9 +112,9 @@ public class MultipleMergeTest {
final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
// Revert addition of Node9 in right
- diff9.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff9).copyLeftToRight(diff9, new BasicMonitor());
// LCS is now {8, 2, 3, 4}. Insertion should be right after 8
- diff2.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
assertValueIndexIs(diff2, false, 2);
// merge 3 (move Node1). Since there is a conflict, merge 11 beforehand
@@ -119,10 +123,10 @@ public class MultipleMergeTest {
final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// revert move of Node 1 in right. It should be re-positioned right before 2
- diff11.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff11).copyLeftToRight(diff11, new BasicMonitor());
assertValueIndexIs(diff11, false, 3);
// LCS is {8, 9, 2, 3, 4}. 1 should be moved right after 4.
- diff3.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
assertValueIndexIs(diff3, false, 7);
// merge 4 (add Node0). There is a conflict. Merge 10 beforehand.
@@ -131,9 +135,9 @@ public class MultipleMergeTest {
final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
// revert addition of 0 in right
- diff10.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff10).copyLeftToRight(diff10, new BasicMonitor());
// LCS is now {8, 9, 2, 3, 4, 1}. 0 should be added right after 1
- diff4.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff4).copyLeftToRight(diff4, new BasicMonitor());
assertValueIndexIs(diff4, false, 7);
// merge 5 (remove Node5). There is a conflict, but it is a pseudo-conflict.
@@ -142,9 +146,9 @@ public class MultipleMergeTest {
fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
- diff12.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff12).copyLeftToRight(diff12, new BasicMonitor());
assertValueIndexIs(diff12, false, 6);
- diff5.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
assertValueIndexIs(diff5, false, -1);
// merge 6 (remove Node6). There is a conflict. Merge 8 beforehand.
@@ -153,15 +157,15 @@ public class MultipleMergeTest {
final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
// Revert move of 6 in right.
- diff8.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff8).copyLeftToRight(diff8, new BasicMonitor());
assertValueIndexIs(diff8, false, 5);
- diff6.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff6).copyLeftToRight(diff6, new BasicMonitor());
assertValueIndexIs(diff6, false, -1);
// merge 7 (remove Node7)
final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- diff7.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff7).copyLeftToRight(diff7, new BasicMonitor());
assertValueIndexIs(diff7, false, -1);
// Left and Right should now be equal
@@ -192,10 +196,10 @@ public class MultipleMergeTest {
final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// revert move of Node 1 in right. It should be re-positioned right before 2
- diff11.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff11).copyLeftToRight(diff11, new BasicMonitor());
assertValueIndexIs(diff11, false, 1);
// Merge move of 1. Should be moved right after 4.
- diff3.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
assertValueIndexIs(diff3, false, 6);
// merge 6 (add Node6). There is a conflict. Merge 8 beforehand.
@@ -204,15 +208,15 @@ public class MultipleMergeTest {
final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
// Revert move of 6 in right.
- diff8.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff8).copyLeftToRight(diff8, new BasicMonitor());
assertValueIndexIs(diff8, false, 5);
- diff6.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff6).copyLeftToRight(diff6, new BasicMonitor());
assertValueIndexIs(diff6, false, -1);
// merge 7 (remove Node7)
final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- diff7.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff7).copyLeftToRight(diff7, new BasicMonitor());
assertValueIndexIs(diff7, false, -1);
// merge 4 (add Node0). There is a conflict. Merge 10 beforehand.
@@ -221,15 +225,15 @@ public class MultipleMergeTest {
final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
// revert addition of 0 in right
- diff10.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff10).copyLeftToRight(diff10, new BasicMonitor());
assertValueIndexIs(diff10, false, -1);
- diff4.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff4).copyLeftToRight(diff4, new BasicMonitor());
assertValueIndexIs(diff4, false, 5);
// merge 1 (add Node8)
final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertValueIndexIs(diff1, false, 0);
// merge 2 (add Node9). Since there is a conflict, merge 9 right beforehand
@@ -238,9 +242,9 @@ public class MultipleMergeTest {
final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
// Revert addition of Node9 in right
- diff9.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff9).copyLeftToRight(diff9, new BasicMonitor());
assertValueIndexIs(diff9, false, -1);
- diff2.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
assertValueIndexIs(diff2, false, 1);
// merge 5 (remove Node5). There is a conflict, but it is a pseudo-conflict.
@@ -249,10 +253,10 @@ public class MultipleMergeTest {
final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
// revert remove
- diff12.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff12).copyLeftToRight(diff12, new BasicMonitor());
assertValueIndexIs(diff12, false, 5);
// apply remove
- diff5.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
assertValueIndexIs(diff5, false, -1);
// Left and Right should now be equal
@@ -283,10 +287,10 @@ public class MultipleMergeTest {
final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
// Revert remove of 6 in left.
- diff6.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff6).copyRightToLeft(diff6, new BasicMonitor());
assertValueIndexIs(diff6, true, 5);
// apply the move in left
- diff8.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff8).copyRightToLeft(diff8, new BasicMonitor());
assertValueIndexIs(diff8, true, 2);
// merge 9 (add Node9). Since there is a conflict, merge 2 right beforehand
@@ -295,9 +299,9 @@ public class MultipleMergeTest {
final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
// Revert addition in left
- diff2.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff2).copyRightToLeft(diff2, new BasicMonitor());
assertValueIndexIs(diff2, true, -1);
- diff9.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff9).copyRightToLeft(diff9, new BasicMonitor());
assertValueIndexIs(diff9, true, 3);
// merge 10 (add Node0). There is a conflict. Merge 4 beforehand.
@@ -306,9 +310,9 @@ public class MultipleMergeTest {
final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
// Revert addition in left
- diff4.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff4).copyRightToLeft(diff4, new BasicMonitor());
assertValueIndexIs(diff4, true, -1);
- diff10.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff10).copyRightToLeft(diff10, new BasicMonitor());
assertValueIndexIs(diff10, true, 5);
// merge 11 (move Node1). Since there is a conflict, merge 3 beforehand
@@ -317,9 +321,9 @@ public class MultipleMergeTest {
final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// Revert move of 1 in left
- diff3.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
assertValueIndexIs(diff3, true, 2);
- diff11.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff11).copyRightToLeft(diff11, new BasicMonitor());
assertValueIndexIs(diff11, true, 6);
// merge 12 (remove Node5). Merge 5 beforehand.
@@ -328,21 +332,21 @@ public class MultipleMergeTest {
final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
// revert remove in left
- diff5.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
assertValueIndexIs(diff5, true, 8);
- diff12.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff12).copyRightToLeft(diff12, new BasicMonitor());
assertValueIndexIs(diff12, true, -1);
// merge 1 (add Node8). This will remove Node8
final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
assertValueIndexIs(diff1, false, -1);
// merge 7 (remove Node7). This will re-add Node7
final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- diff7.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff7).copyRightToLeft(diff7, new BasicMonitor());
assertValueIndexIs(diff7, false, 7);
// Left and Right should now be equal
@@ -377,9 +381,9 @@ public class MultipleMergeTest {
final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
// revert remove in left
- diff5.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
assertValueIndexIs(diff5, true, 5);
- diff12.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff12).copyRightToLeft(diff12, new BasicMonitor());
assertValueIndexIs(diff12, true, -1);
// merge 10 (add Node0). There is a conflict. Merge 4 beforehand.
@@ -388,15 +392,15 @@ public class MultipleMergeTest {
final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
// Revert addition in left
- diff4.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff4).copyRightToLeft(diff4, new BasicMonitor());
assertValueIndexIs(diff4, true, -1);
- diff10.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff10).copyRightToLeft(diff10, new BasicMonitor());
assertValueIndexIs(diff10, true, 4);
// merge 7 (remove Node7). This will re-add Node7
final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- diff7.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff7).copyRightToLeft(diff7, new BasicMonitor());
assertValueIndexIs(diff7, false, 7);
// merge 9 (add Node9). Since there is a conflict, merge 2 right beforehand
@@ -405,15 +409,15 @@ public class MultipleMergeTest {
final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
// Revert addition in left
- diff2.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff2).copyRightToLeft(diff2, new BasicMonitor());
assertValueIndexIs(diff2, true, -1);
- diff9.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff9).copyRightToLeft(diff9, new BasicMonitor());
assertValueIndexIs(diff9, true, 2);
// merge 1 (add Node8). This will remove Node8
final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
assertValueIndexIs(diff1, false, -1);
// merge 8 (move Node6). There is a conflict. Merge 6 beforehand.
@@ -422,10 +426,10 @@ public class MultipleMergeTest {
final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
// Revert remove of 6 in left.
- diff6.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff6).copyRightToLeft(diff6, new BasicMonitor());
assertValueIndexIs(diff6, true, 5);
// apply the move in left
- diff8.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff8).copyRightToLeft(diff8, new BasicMonitor());
assertValueIndexIs(diff8, true, 0);
// merge 11 (move Node1). Since there is a conflict, merge 3 beforehand
@@ -434,9 +438,9 @@ public class MultipleMergeTest {
final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// Revert move of 1 in left
- diff3.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
assertValueIndexIs(diff3, true, 1);
- diff11.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff11).copyRightToLeft(diff11, new BasicMonitor());
assertValueIndexIs(diff11, true, 5);
// Left and Right should now be equal
@@ -477,19 +481,19 @@ public class MultipleMergeTest {
final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(),
addedToReference("Requirements.F", "source", "Requirements.E"));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
// Check that diff1 got properly merged
assertMerged(comparison, diff1, false, false);
// And validate that diff2 got merged as an equivalent diff
assertMerged(comparison, diff2, false, false);
- diff3.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
// Check that diff3 got properly merged
assertMerged(comparison, diff3, false, false);
// And validate that diff4 got merged as an equivalent diff
assertMerged(comparison, diff4, false, false);
- diff5.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
// Check that diff5 got properly merged
assertMerged(comparison, diff5, false, false);
// And validate that diff6 got merged as an equivalent diff
@@ -529,17 +533,17 @@ public class MultipleMergeTest {
final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(),
addedToReference("Requirements.F", "source", "Requirements.E"));
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
// Check that diff1 got properly merged (we're unsetting values)
assertMerged(comparison, diff1, true, true);
// And validate that diff2 got merged as an equivalent diff
assertMerged(comparison, diff2, true, true);
- diff3.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
assertMerged(comparison, diff3, true, true);
assertMerged(comparison, diff4, true, true);
- diff5.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
assertMerged(comparison, diff5, true, true);
assertMerged(comparison, diff6, true, true);
@@ -572,11 +576,11 @@ public class MultipleMergeTest {
final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(),
addedToReference("Requirements.A", "source", "Requirements.B"));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertMerged(comparison, diff1, false, false);
assertMerged(comparison, diff2, false, false);
- diff3.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
assertMerged(comparison, diff3, false, false);
assertMerged(comparison, diff4, false, false);
@@ -609,11 +613,11 @@ public class MultipleMergeTest {
final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(),
addedToReference("Requirements.A", "source", "Requirements.B"));
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
assertMerged(comparison, diff1, true, true);
assertMerged(comparison, diff2, true, true);
- diff3.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
assertMerged(comparison, diff3, true, true);
assertMerged(comparison, diff4, true, true);
@@ -668,19 +672,19 @@ public class MultipleMergeTest {
final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(),
addedToReference("Requirements", "containmentRef1", "Requirements.F"));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertMerged(comparison, diff1, false, false);
assertMerged(comparison, diff2, false, false);
assertSame(DifferenceState.MERGED, diff7.getState());
assertSame(DifferenceState.MERGED, diff8.getState());
- diff3.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
assertMerged(comparison, diff3, false, false);
assertMerged(comparison, diff4, false, false);
assertSame(DifferenceState.MERGED, diff9.getState());
assertSame(DifferenceState.MERGED, diff10.getState());
- diff5.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
assertMerged(comparison, diff5, false, false);
assertMerged(comparison, diff6, false, false);
assertSame(DifferenceState.MERGED, diff11.getState());
@@ -739,31 +743,31 @@ public class MultipleMergeTest {
// Removing the link between A and B does not necessarily means removing A and B
// The "required" diffs will ne be merged
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
assertMerged(comparison, diff1, true, true);
assertMerged(comparison, diff2, true, true);
assertSame(DifferenceState.UNRESOLVED, diff7.getState());
assertSame(DifferenceState.UNRESOLVED, diff8.getState());
- diff3.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
assertMerged(comparison, diff3, true, true);
assertMerged(comparison, diff4, true, true);
assertSame(DifferenceState.UNRESOLVED, diff9.getState());
assertSame(DifferenceState.UNRESOLVED, diff10.getState());
- diff5.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
assertMerged(comparison, diff5, true, true);
assertMerged(comparison, diff6, true, true);
assertSame(DifferenceState.UNRESOLVED, diff11.getState());
assertSame(DifferenceState.UNRESOLVED, diff12.getState());
// Merge the 6 remaining diffs
- diff7.copyRightToLeft();
- diff8.copyRightToLeft();
- diff9.copyRightToLeft();
- diff10.copyRightToLeft();
- diff11.copyRightToLeft();
- diff12.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff7).copyRightToLeft(diff7, new BasicMonitor());
+ mergerRegistry.getHighestRankingMerger(diff8).copyRightToLeft(diff8, new BasicMonitor());
+ mergerRegistry.getHighestRankingMerger(diff9).copyRightToLeft(diff9, new BasicMonitor());
+ mergerRegistry.getHighestRankingMerger(diff10).copyRightToLeft(diff10, new BasicMonitor());
+ mergerRegistry.getHighestRankingMerger(diff11).copyRightToLeft(diff11, new BasicMonitor());
+ mergerRegistry.getHighestRankingMerger(diff12).copyRightToLeft(diff12, new BasicMonitor());
comparison = EMFCompare.builder().build().compare(scope);
assertSame(Integer.valueOf(0), Integer.valueOf(comparison.getDifferences().size()));
@@ -797,7 +801,7 @@ public class MultipleMergeTest {
final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(),
changedReference("Requirements.C", "source", null, "Requirements.A"));
- diff2.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
assertSame(DifferenceState.MERGED, diff1.getState());
assertMerged(comparison, diff2, false, false);
assertMerged(comparison, diff3, true, false);
@@ -835,13 +839,13 @@ public class MultipleMergeTest {
final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(),
changedReference("Requirements.C", "source", null, "Requirements.A"));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertSame(DifferenceState.MERGED, diff1.getState());
assertSame(DifferenceState.UNRESOLVED, diff2.getState());
assertSame(DifferenceState.UNRESOLVED, diff3.getState());
assertSame(DifferenceState.UNRESOLVED, diff4.getState());
- diff2.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
assertMerged(comparison, diff2, false, false);
assertMerged(comparison, diff3, true, false);
assertMerged(comparison, diff4, false, false);
@@ -878,7 +882,7 @@ public class MultipleMergeTest {
final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(),
changedReference("Requirements.C", "source", null, "Requirements.A"));
- diff2.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff2).copyRightToLeft(diff2, new BasicMonitor());
assertSame(DifferenceState.UNRESOLVED, diff1.getState());
assertMerged(comparison, diff3, false, true);
assertMerged(comparison, diff4, true, true);
@@ -892,7 +896,7 @@ public class MultipleMergeTest {
assertEquals("B", nodeB.eGet(nodeB.eClass().getEStructuralFeature("name")));
assertSame(nodeB, nodeA.eGet(diff2.getReference()));
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
comparison = EMFCompare.builder().build().compare(scope);
assertSame(Integer.valueOf(0), Integer.valueOf(comparison.getDifferences().size()));
@@ -930,14 +934,14 @@ public class MultipleMergeTest {
final ReferenceChange diff5 = (ReferenceChange)Iterators.find(differences.iterator(),
changedReference("Requirements.C", "source", null, "Requirements.A"));
- diff1.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
assertMerged(comparison, diff1, false, false);
assertSame(DifferenceState.UNRESOLVED, diff2.getState());
assertSame(DifferenceState.UNRESOLVED, diff3.getState());
assertSame(DifferenceState.UNRESOLVED, diff4.getState());
assertSame(DifferenceState.UNRESOLVED, diff5.getState());
- diff2.copyLeftToRight();
+ mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
// B has been deleted : unset element in right
assertMerged(comparison, diff2, true, false);
// Change A.destination from "B" to "C"
@@ -987,7 +991,7 @@ public class MultipleMergeTest {
// 1 is required by 3, which is required by 2 and equivalent to 4 and 5.
// Resetting 1 should thus reset all other diffs.
- diff1.copyRightToLeft();
+ mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
assertMerged(comparison, diff1, true, true);
assertMerged(comparison, diff2, false, true);
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
index 971515a06..6722ab275 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
@@ -18,6 +18,7 @@ import org.eclipse.emf.compare.ComparePackage;
import org.eclipse.emf.compare.tests.command.CommandStackTestSuite;
import org.eclipse.emf.compare.tests.conflict.ConflictDetectionTest;
import org.eclipse.emf.compare.tests.diff.DiffUtilTest;
+import org.eclipse.emf.compare.tests.diff.LCSPerformanceTest;
import org.eclipse.emf.compare.tests.diff.URIDistanceTest;
import org.eclipse.emf.compare.tests.edit.AllEditTests;
import org.eclipse.emf.compare.tests.equi.EquiComputingTest;
@@ -26,6 +27,7 @@ import org.eclipse.emf.compare.tests.fullcomparison.DynamicInstanceComparisonTes
import org.eclipse.emf.compare.tests.fullcomparison.ExtLibraryTest;
import org.eclipse.emf.compare.tests.fullcomparison.IdentifierComparisonTest;
import org.eclipse.emf.compare.tests.fullcomparison.ProximityComparisonTest;
+import org.eclipse.emf.compare.tests.merge.ExtensionMergeTest;
import org.eclipse.emf.compare.tests.merge.IndividualMergeOutOfScopeValuesTest;
import org.eclipse.emf.compare.tests.merge.IndividualMergeTest;
import org.eclipse.emf.compare.tests.merge.MultipleMergeTest;
@@ -49,10 +51,10 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({CompareTestSuite.class, DefaultComparisonScopeTest.class, IdentifierComparisonTest.class,
ExtLibraryTest.class, ConflictDetectionTest.class, ReqComputingTest.class, EquiComputingTest.class,
- DiffUtilTest.class, MultipleMergeTest.class, PostProcessorTest.class, IndividualMergeTest.class,
- IndividualMergeOutOfScopeValuesTest.class, ProximityComparisonTest.class,
- DynamicInstanceComparisonTest.class, URIDistanceTest.class, FragmentationTest.class,
- AllEditTests.class, CommandStackTestSuite.class, })
+ DiffUtilTest.class, LCSPerformanceTest.class, MultipleMergeTest.class, PostProcessorTest.class,
+ IndividualMergeTest.class, ExtensionMergeTest.class, IndividualMergeOutOfScopeValuesTest.class,
+ ProximityComparisonTest.class, DynamicInstanceComparisonTest.class, URIDistanceTest.class,
+ FragmentationTest.class, AllEditTests.class, CommandStackTestSuite.class, })
public class AllTests {
/**
* Standalone launcher for all of compare's tests.
diff --git a/plugins/org.eclipse.emf.compare.uml2.edit/plugin.xml b/plugins/org.eclipse.emf.compare.uml2.edit/plugin.xml
index f0ef13fe5..400963291 100644
--- a/plugins/org.eclipse.emf.compare.uml2.edit/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.uml2.edit/plugin.xml
@@ -23,7 +23,8 @@ Contributors:
org.eclipse.emf.edit.provider.IStructuredItemContentProvider
org.eclipse.emf.edit.provider.ITreeItemContentProvider
org.eclipse.emf.edit.provider.IItemLabelProvider
- org.eclipse.emf.edit.provider.IItemPropertySource"/>
+ org.eclipse.emf.edit.provider.IItemPropertySource
+ org.eclipse.emf.compare.provider.IItemStyledLabelProvider"/>
</extension>
diff --git a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/ForwardingUMLDiffItemProvider.java b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/ForwardingUMLDiffItemProvider.java
index 53a774386..1b4b0602e 100644
--- a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/ForwardingUMLDiffItemProvider.java
+++ b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/ForwardingUMLDiffItemProvider.java
@@ -14,22 +14,35 @@ import java.util.Collection;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.DifferenceKind;
-import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
import org.eclipse.emf.compare.provider.ForwardingItemProvider;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
import org.eclipse.emf.compare.provider.spec.Strings;
+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.uml2.UMLDiff;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
/**
+ * Specialized ForwardingItemProvider for UML.
+ *
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public class ForwardingUMLDiffItemProvider extends ForwardingItemProvider {
+public class ForwardingUMLDiffItemProvider extends ForwardingItemProvider implements IItemStyledLabelProvider {
+
+ /**
+ * The maximum length of displayed text.
+ */
+ private static final int MAX_LENGTH = 50;
/**
+ * This constructs an instance from an adapter.
+ *
* @param delegate
+ * the adapter to delegate to.
*/
public ForwardingUMLDiffItemProvider(ItemProviderAdapter delegate) {
super(delegate);
@@ -69,36 +82,7 @@ public class ForwardingUMLDiffItemProvider extends ForwardingItemProvider {
*/
@Override
public String getText(Object object) {
- final UMLDiff umlDiff = (UMLDiff)object;
-
- String remotely = "";
- if (umlDiff.getSource() == DifferenceSource.RIGHT) {
- remotely = "remotely ";
- }
-
- final String valueText = getValueText(umlDiff);
- final String referenceText = getReferenceText(umlDiff);
-
- String ret = "";
- switch (umlDiff.getKind()) {
- case ADD:
- ret = valueText + " has been " + remotely + "added to " + referenceText;
- break;
- case DELETE:
- ret = valueText + " has been " + remotely + "deleted from " + referenceText;
- break;
- case CHANGE:
- ret = valueText + " has been " + remotely + "changed";
- break;
- case MOVE:
- ret = valueText + " has been " + remotely + "moved in " + referenceText;
- break;
- default:
- throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName()
- + " value: " + umlDiff.getKind());
- }
-
- return ret;
+ return getStyledText(object).getString();
}
/**
@@ -133,16 +117,30 @@ public class ForwardingUMLDiffItemProvider extends ForwardingItemProvider {
return image;
}
+ /**
+ * Returns the value text for the given umlDiff.
+ *
+ * @param umlDiff
+ * the given {@link UMLDiff}.
+ * @return the value text.
+ */
private String getValueText(final UMLDiff umlDiff) {
String value = AdapterFactoryUtil.getText(getRootAdapterFactory(), umlDiff.getDiscriminant());
if (value == null) {
value = "<null>";
} else {
- value = Strings.elide(value, 50, "...");
+ value = Strings.elide(value, MAX_LENGTH, "...");
}
return value;
}
+ /**
+ * Returns the reference text for the given umlDiff.
+ *
+ * @param umlDiff
+ * the given {@link UMLDiff}.
+ * @return the reference text.
+ */
private String getReferenceText(final UMLDiff umlDiff) {
String ret = "";
switch (umlDiff.getKind()) {
@@ -177,4 +175,39 @@ public class ForwardingUMLDiffItemProvider extends ForwardingItemProvider {
return super.getForeground(object);
}
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ final UMLDiff umlDiff = (UMLDiff)object;
+
+ final String valueText = getValueText(umlDiff);
+ final String referenceText = getReferenceText(umlDiff);
+
+ ComposedStyledString ret = new ComposedStyledString(valueText);
+ ret.append(" [" + referenceText, Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ switch (umlDiff.getKind()) {
+ case ADD:
+ ret.append(" add", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case DELETE:
+ ret.append(" delete", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case CHANGE:
+ ret.append(" change", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ case MOVE:
+ ret.append(" move", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+ break;
+ default:
+ throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
+ + " value: " + umlDiff.getKind()); //$NON-NLS-1$
+ }
+ ret.append("]", Style.DECORATIONS_STYLER); //$NON-NLS-1$
+
+ return ret;
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/StereotypeApplicationChangeItemProviderSpec.java b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/StereotypeApplicationChangeItemProviderSpec.java
index 03cbcdb98..ca29c82f4 100644
--- a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/StereotypeApplicationChangeItemProviderSpec.java
+++ b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/StereotypeApplicationChangeItemProviderSpec.java
@@ -15,9 +15,12 @@ import java.util.Collection;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.DifferenceKind;
-import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.provider.AdapterFactoryUtil;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
+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.uml2.StereotypeApplicationChange;
import org.eclipse.emf.compare.uml2.UMLDiff;
import org.eclipse.emf.compare.uml2.provider.StereotypeApplicationChangeItemProvider;
@@ -31,7 +34,7 @@ import org.eclipse.uml2.uml.util.UMLUtil;
*
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
*/
-public class StereotypeApplicationChangeItemProviderSpec extends StereotypeApplicationChangeItemProvider {
+public class StereotypeApplicationChangeItemProviderSpec extends StereotypeApplicationChangeItemProvider implements IItemStyledLabelProvider {
/**
* This constructs an instance from a factory and a notifier.
@@ -77,60 +80,7 @@ public class StereotypeApplicationChangeItemProviderSpec extends StereotypeAppli
*/
@Override
public String getText(Object object) {
- final UMLDiff umlDiff = (UMLDiff)object;
-
- String remotely = "";
- if (umlDiff.getSource() == DifferenceSource.RIGHT) {
- remotely = "remotely ";
- }
-
- Stereotype stereotype = ((StereotypeApplicationChange)umlDiff).getStereotype();
- if (stereotype == null) {
- stereotype = UMLUtil.getStereotype(umlDiff.getDiscriminant());
- }
-
- final String stereotypeText;
- if (stereotype != null) {
- stereotypeText = AdapterFactoryUtil.getText(getRootAdapterFactory(), stereotype) + ' ';
- } else if (umlDiff.getDiscriminant() instanceof NamedElement) {
- stereotypeText = "Stereotype " + ((NamedElement)umlDiff.getDiscriminant()).getName() + ' ';
- } else {
- // Can't really do more
- stereotypeText = "Stereotype ";
- }
-
- final Match targetMatch = umlDiff.getMatch();
- final EObject target = findNonNullSide(targetMatch);
- String targetLabel = null;
-
- final String action;
- switch (umlDiff.getKind()) {
- case ADD:
- action = "applied";
- targetLabel = " to ";
- break;
- case DELETE:
- action = "unapplied";
- targetLabel = " from ";
- break;
- case CHANGE:
- action = "changed";
- targetLabel = " on ";
- break;
- case MOVE:
- action = "moved";
- targetLabel = " to ";
- break;
- default:
- throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName()
- + " value: " + umlDiff.getKind());
- }
-
- if (target != null) {
- targetLabel += AdapterFactoryUtil.getText(getRootAdapterFactory(), target);
- }
-
- return stereotypeText + "has been " + remotely + action + targetLabel;
+ return getStyledText(object).getString();
}
/**
@@ -187,4 +137,57 @@ public class StereotypeApplicationChangeItemProviderSpec extends StereotypeAppli
return super.getForeground(object);
}
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.provider.IItemStyledLabelProvider#getStyledText(java.lang.Object)
+ */
+ public IStyledString.IComposedStyledString getStyledText(Object object) {
+ final UMLDiff umlDiff = (UMLDiff)object;
+
+ Stereotype stereotype = ((StereotypeApplicationChange)umlDiff).getStereotype();
+ if (stereotype == null) {
+ stereotype = UMLUtil.getStereotype(umlDiff.getDiscriminant());
+ }
+
+ final ComposedStyledString stereotypeText = new ComposedStyledString();
+ if (stereotype != null) {
+ stereotypeText.append(AdapterFactoryUtil.getText(getRootAdapterFactory(), stereotype) + ' ');
+ } else if (umlDiff.getDiscriminant() instanceof NamedElement) {
+ stereotypeText.append("Stereotype " + ((NamedElement)umlDiff.getDiscriminant()).getName() + ' '); //$NON-NLS-1$
+ } else {
+ // Can't really do more
+ stereotypeText.append("Stereotype "); //$NON-NLS-1$
+ }
+
+ final Match targetMatch = umlDiff.getMatch();
+ final EObject target = findNonNullSide(targetMatch);
+ String targetLabel = null;
+
+ final String action;
+ switch (umlDiff.getKind()) {
+ case ADD:
+ action = "applied"; //$NON-NLS-1$
+ break;
+ case DELETE:
+ action = "unapplied"; //$NON-NLS-1$
+ break;
+ case CHANGE:
+ action = "changed"; //$NON-NLS-1$
+ break;
+ case MOVE:
+ action = "moved"; //$NON-NLS-1$
+ break;
+ default:
+ throw new IllegalStateException("Unsupported " + DifferenceKind.class.getSimpleName() //$NON-NLS-1$
+ + " value: " + umlDiff.getKind()); //$NON-NLS-1$
+ }
+
+ if (target != null) {
+ targetLabel += AdapterFactoryUtil.getText(getRootAdapterFactory(), target);
+ }
+
+ return stereotypeText.append(" [" + targetLabel + " " + action + "]", Style.DECORATIONS_STYLER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
}
diff --git a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/UMLCompareAdapterFactorySpec.java b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/UMLCompareAdapterFactorySpec.java
index 8ee7c9b7c..8a3971744 100644
--- a/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/UMLCompareAdapterFactorySpec.java
+++ b/plugins/org.eclipse.emf.compare.uml2.edit/src/org/eclipse/emf/compare/uml2/provider/spec/UMLCompareAdapterFactorySpec.java
@@ -11,6 +11,7 @@
package org.eclipse.emf.compare.uml2.provider.spec;
import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.compare.provider.IItemStyledLabelProvider;
import org.eclipse.emf.compare.uml2.provider.StereotypeApplicationChangeItemProvider;
import org.eclipse.emf.compare.uml2.provider.UMLCompareItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
@@ -48,6 +49,11 @@ public class UMLCompareAdapterFactorySpec extends UMLCompareItemProviderAdapterF
ForwardingUMLDiffItemProvider fSubstitutionChangeItemProvider;
+ public UMLCompareAdapterFactorySpec() {
+ super();
+ supportedTypes.add(IItemStyledLabelProvider.class);
+ }
+
/**
* {@inheritDoc}
*
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/AbstractTest.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/AbstractTest.java
index d3dec4b8d..a69b5d5cf 100644
--- a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/AbstractTest.java
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/AbstractTest.java
@@ -1,3 +1,13 @@
+/**
+ * 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.uml2.tests;
import static org.junit.Assert.assertTrue;
@@ -9,6 +19,7 @@ import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.AttributeChange;
import org.eclipse.emf.compare.ComparePackage;
@@ -18,9 +29,13 @@ import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.extension.PostProcessorDescriptor;
import org.eclipse.emf.compare.extension.PostProcessorRegistry;
+import org.eclipse.emf.compare.merge.BatchMerger;
+import org.eclipse.emf.compare.merge.IBatchMerger;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.compare.tests.framework.AbstractInputData;
import org.eclipse.emf.compare.uml2.diff.UMLDiffExtensionPostProcessor;
+import org.eclipse.emf.compare.uml2.merge.UMLDiffMerger;
import org.eclipse.emf.compare.utils.ReferenceUtil;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
@@ -35,13 +50,19 @@ public abstract class AbstractTest {
private EMFCompare emfCompare;
+ private static final IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
@BeforeClass
- public static void fillEMFRegistries() {
+ public static void fillRegistries() {
EPackage.Registry.INSTANCE.put(ComparePackage.eNS_URI, ComparePackage.eINSTANCE);
EPackage.Registry.INSTANCE.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("uml", //$NON-NLS-1$
new UMLResourceFactoryImpl());
+
+ final IMerger umlMerger = new UMLDiffMerger();
+ umlMerger.setRanking(11);
+ mergerRegistry.add(umlMerger);
}
@Before
@@ -110,9 +131,8 @@ public abstract class AbstractTest {
final IComparisonScope scope = EMFCompare.createDefaultScope(left, right, origin);
final Comparison comparisonBefore = getCompare().compare(scope);
EList<Diff> differences = comparisonBefore.getDifferences();
- for (Diff diff : differences) {
- diff.copyLeftToRight();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllLeftToRight(differences, new BasicMonitor());
final Comparison comparisonAfter = getCompare().compare(scope);
assertTrue("Comparison#getDifferences() must be empty after copyAllLeftToRight", comparisonAfter
.getDifferences().isEmpty());
@@ -122,9 +142,8 @@ public abstract class AbstractTest {
final IComparisonScope scope = EMFCompare.createDefaultScope(left, right, origin);
final Comparison comparisonBefore = getCompare().compare(scope);
EList<Diff> differences = comparisonBefore.getDifferences();
- for (Diff diff : differences) {
- diff.copyRightToLeft();
- }
+ final IBatchMerger merger = new BatchMerger(mergerRegistry);
+ merger.copyAllRightToLeft(differences, new BasicMonitor());
final Comparison comparisonAfter = getCompare().compare(scope);
assertTrue("Comparison#getDifferences() must be empty after copyAllRightToLeft", comparisonAfter
.getDifferences().isEmpty());
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/association/AddAssociationTest.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/association/AddAssociationTest.java
index 57b3d713d..e23ee5c42 100644
--- a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/association/AddAssociationTest.java
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/association/AddAssociationTest.java
@@ -30,6 +30,7 @@ import org.eclipse.emf.compare.uml2.AssociationChange;
import org.eclipse.emf.compare.uml2.tests.AbstractTest;
import org.eclipse.emf.compare.uml2.tests.association.data.AssociationInputData;
import org.eclipse.emf.ecore.resource.Resource;
+import org.junit.Ignore;
import org.junit.Test;
@SuppressWarnings("nls")
@@ -50,43 +51,45 @@ public class AddAssociationTest extends AbstractTest {
@Test
public void testMergeRtLA10UseCase() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeRightToLeft(left, right, null);
}
@Test
+ @Ignore
public void testMergeLtRA10UseCase() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeLeftToRight(left, right, null);
}
@Test
public void testA11UseCase() throws IOException {
- final Resource left = input.getA1Left();
- final Resource right = input.getA1Right();
+ final Resource left = input.getA1Right();
+ final Resource right = input.getA1Left();
- final IComparisonScope scope = EMFCompare.createDefaultScope(right, left);
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left, right);
final Comparison comparison = getCompare().compare(scope);
testAB1(TestKind.DELETE, comparison);
}
@Test
+ @Ignore
public void testMergeRtLA11UseCase() throws IOException {
- final Resource left = input.getA1Left();
+ final Resource left = input.getA1Right();
final Resource right = input.getA1Left();
- testMergeRightToLeft(right, left, null);
+ testMergeRightToLeft(left, right, null);
}
@Test
public void testMergeLtRA11UseCase() throws IOException {
- final Resource left = input.getA1Left();
+ final Resource left = input.getA1Right();
final Resource right = input.getA1Left();
- testMergeLeftToRight(right, left, null);
+ testMergeLeftToRight(left, right, null);
}
@Test
@@ -102,15 +105,16 @@ public class AddAssociationTest extends AbstractTest {
@Test
public void testMergeRtLA10UseCase3way() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeRightToLeft(left, right, right);
}
@Test
+ @Ignore
public void testMergeLtRA10UseCase3way() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeLeftToRight(left, right, right);
}
@@ -128,15 +132,16 @@ public class AddAssociationTest extends AbstractTest {
@Test
public void testMergeRtLA11UseCase3way() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeRightToLeft(left, right, left);
}
@Test
+ @Ignore
public void testMergeLtRA11UseCase3way() throws IOException {
final Resource left = input.getA1Left();
- final Resource right = input.getA1Left();
+ final Resource right = input.getA1Right();
testMergeLeftToRight(left, right, left);
}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/ExtensionMergeTest.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/ExtensionMergeTest.java
new file mode 100644
index 000000000..712ee1390
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/merge/ExtensionMergeTest.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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.uml2.tests.merge;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.merge.AttributeChangeMerger;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.merge.ReferenceChangeMerger;
+import org.eclipse.emf.compare.merge.ResourceAttachmentChangeMerger;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.tests.framework.AbstractInputData;
+import org.eclipse.emf.compare.uml2.UMLDiff;
+import org.eclipse.emf.compare.uml2.merge.UMLDiffMerger;
+import org.eclipse.emf.compare.uml2.tests.AbstractTest;
+import org.eclipse.emf.compare.uml2.tests.association.data.AssociationInputData;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.junit.Test;
+
+@SuppressWarnings("nls")
+public class ExtensionMergeTest extends AbstractTest {
+ private AssociationInputData input = new AssociationInputData();
+
+ @Test
+ public void testInstantiationMerger() throws IOException {
+ final Resource left = input.getA1Left();
+ final Resource right = input.getA1Right();
+
+ testMergeRightToLeft(left, right, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.uml2.tests.AbstractTest#testMergeRightToLeft(org.eclipse.emf.common.notify.Notifier,
+ * org.eclipse.emf.common.notify.Notifier, org.eclipse.emf.common.notify.Notifier)
+ */
+ @Override
+ protected void testMergeRightToLeft(Notifier left, Notifier right, Notifier origin) {
+ final IComparisonScope scope = EMFCompare.createDefaultScope(left, right, origin);
+ final Comparison comparisonBefore = getCompare().compare(scope);
+ EList<Diff> differences = comparisonBefore.getDifferences();
+ final IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ final IMerger umlMerger = new UMLDiffMerger();
+ umlMerger.setRanking(11);
+ registry.add(umlMerger);
+ for (Diff diff : differences) {
+ final Class<? extends IMerger> expectedMerger;
+ if (diff instanceof UMLDiff) {
+ expectedMerger = UMLDiffMerger.class;
+ } else if (diff instanceof AttributeChange) {
+ expectedMerger = AttributeChangeMerger.class;
+ } else if (diff instanceof ReferenceChange) {
+ expectedMerger = ReferenceChangeMerger.class;
+ } else {
+ expectedMerger = ResourceAttachmentChangeMerger.class;
+ }
+ IMerger merger = org.eclipse.emf.compare.tests.merge.ExtensionMergeTest.getMerger(registry, diff,
+ expectedMerger);
+ merger.copyRightToLeft(diff, null);
+ }
+ final Comparison comparisonAfter = getCompare().compare(scope);
+ assertTrue("Comparison#getDifferences() must be empty after copyAllRightToLeft", comparisonAfter
+ .getDifferences().isEmpty());
+ }
+
+ @Override
+ protected AbstractInputData getInput() {
+ return input;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
index 08d62b853..e2a648b22 100644
--- a/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.uml2.tests/src/org/eclipse/emf/compare/uml2/tests/suite/AllTests.java
@@ -32,6 +32,7 @@ import org.eclipse.emf.compare.uml2.tests.executionSpecification.AddBehaviorExec
import org.eclipse.emf.compare.uml2.tests.extend.AddExtendTest;
import org.eclipse.emf.compare.uml2.tests.generalizationSet.AddGeneralizationSetTest;
import org.eclipse.emf.compare.uml2.tests.include.AddIncludeTest;
+import org.eclipse.emf.compare.uml2.tests.merge.ExtensionMergeTest;
import org.eclipse.emf.compare.uml2.tests.message.AddMessageTest;
import org.eclipse.emf.compare.uml2.tests.profiles.ProfileTest;
import org.eclipse.emf.compare.uml2.tests.stereotypes.DynamicStereotypeTest;
@@ -48,8 +49,8 @@ import org.junit.runners.Suite.SuiteClasses;
*/
@RunWith(Suite.class)
@SuiteClasses({AddDependencyTest.class, AddAbstractionTest.class, AddAssociationTest.class,
- AddAssociation2Test.class, ChangeAssociationTest.class, ChangeDependencyTest.class,
- ChangeUsageTest.class, AddAssociation3Test.class, AddExtendTest.class,
+ ExtensionMergeTest.class, AddAssociation2Test.class, ChangeAssociationTest.class,
+ ChangeDependencyTest.class, ChangeUsageTest.class, AddAssociation3Test.class, AddExtendTest.class,
AddGeneralizationSetTest.class, AddInterfaceRealizationTest.class, AddRealizationTest.class,
AddSubstitutionTest.class, AddUsageTest.class, AddMessageTest.class,
AddActionExecutionSpecificationTest.class, AddBehaviorExecutionSpecificationTest.class,
diff --git a/plugins/org.eclipse.emf.compare.uml2/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.uml2/META-INF/MANIFEST.MF
index 7da16e8e1..88c7c6410 100644
--- a/plugins/org.eclipse.emf.compare.uml2/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.uml2/META-INF/MANIFEST.MF
@@ -22,6 +22,7 @@ Export-Package: org.eclipse.emf.compare.uml2,
org.eclipse.emf.compare.uml2.diff.internal.extension.usecase;x-internal:=true,
org.eclipse.emf.compare.uml2.diff.internal.util;x-friends:="org.eclipse.emf.compare.uml2.edit",
org.eclipse.emf.compare.uml2.impl,
+ org.eclipse.emf.compare.uml2.merge,
org.eclipse.emf.compare.uml2.util
Bundle-Activator: org.eclipse.emf.compare.uml2.UMLDiffEnginePlugin
Import-Package: com.google.common.base;version="[10.0.0,11.0.0)",
diff --git a/plugins/org.eclipse.emf.compare.uml2/plugin.xml b/plugins/org.eclipse.emf.compare.uml2/plugin.xml
index 5ff654e2f..9b47b4a89 100644
--- a/plugins/org.eclipse.emf.compare.uml2/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.uml2/plugin.xml
@@ -29,5 +29,12 @@ Contributors:
</nsURI>
</postProcessor>
</extension>
+ <extension
+ point="org.eclipse.emf.compare.ide.mergerExtension">
+ <merger
+ class="org.eclipse.emf.compare.uml2.merge.UMLDiffMerger"
+ ranking="11">
+ </merger>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.compare.uml2/src-gen/org/eclipse/emf/compare/uml2/impl/UMLDiffImpl.java b/plugins/org.eclipse.emf.compare.uml2/src-gen/org/eclipse/emf/compare/uml2/impl/UMLDiffImpl.java
index a56e2b720..2a1b3d09a 100644
--- a/plugins/org.eclipse.emf.compare.uml2/src-gen/org/eclipse/emf/compare/uml2/impl/UMLDiffImpl.java
+++ b/plugins/org.eclipse.emf.compare.uml2/src-gen/org/eclipse/emf/compare/uml2/impl/UMLDiffImpl.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -11,10 +11,9 @@
package org.eclipse.emf.compare.uml2.impl;
import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceSource;
-import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.impl.DiffImpl;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.uml2.UMLComparePackage;
import org.eclipse.emf.compare.uml2.UMLDiff;
import org.eclipse.emf.ecore.EClass;
@@ -234,96 +233,17 @@ public abstract class UMLDiffImpl extends DiffImpl implements UMLDiff {
return super.eIsSet(featureID);
}
+ @Deprecated
@Override
public void copyLeftToRight() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- setEquivalentDiffAsMerged();
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- for (Diff diff : getRefinedBy()) {
- diff.copyLeftToRight();
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "requires" diffs
- mergeRequires(false);
- } else {
- // merge all "required by" diffs
- mergeRequiredBy(false);
- }
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyLeftToRight(this, new BasicMonitor());
}
+ @Deprecated
@Override
public void copyRightToLeft() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- setEquivalentDiffAsMerged();
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- for (Diff diff : getRefinedBy()) {
- diff.copyRightToLeft();
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "required by" diffs
- mergeRequiredBy(true);
- } else {
- mergeRequires(true);
- }
- }
-
- private void setEquivalentDiffAsMerged() {
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequiredBy() differences that require us} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequiredBy() differences
- * that require us}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequiredBy(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequiredBy()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequires() required differences} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequires() required
- * differences}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequires(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequires()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyRightToLeft(this, new BasicMonitor());
}
} // UMLDiffImpl
diff --git a/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/merge/UMLDiffMerger.java b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/merge/UMLDiffMerger.java
new file mode 100644
index 000000000..e0f50f050
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.uml2/src/org/eclipse/emf/compare/uml2/merge/UMLDiffMerger.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.uml2.merge;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.merge.AbstractMerger;
+import org.eclipse.emf.compare.uml2.UMLDiff;
+
+/**
+ * Specific implementation of {@link AbstractMerger} for UML differences.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public class UMLDiffMerger extends AbstractMerger {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
+ */
+ public boolean isMergerFor(Diff target) {
+ return target instanceof UMLDiff;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyLeftToRight(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final UMLDiff diff = (UMLDiff)target;
+
+ setEquivalentDiffAsMerged(diff);
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ for (Diff refining : diff.getRefinedBy()) {
+ mergeDiff(refining, false, monitor);
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "requires" diffs
+ mergeRequires(diff, false, monitor);
+ } else {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, false, monitor);
+ }
+ }
+
+ public void copyRightToLeft(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final UMLDiff diff = (UMLDiff)target;
+
+ setEquivalentDiffAsMerged(diff);
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ for (Diff refining : diff.getRefinedBy()) {
+ mergeDiff(refining, true, monitor);
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, true, monitor);
+ } else {
+ mergeRequires(diff, true, monitor);
+ }
+ }
+
+ /**
+ * Iterates over the differences equivalent to {@code diff} and sets them as
+ * {@link DifferenceState#MERGED}.
+ *
+ * @param diff
+ * Diff which equivalences are to be considered merged.
+ */
+ private void setEquivalentDiffAsMerged(UMLDiff diff) {
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare/META-INF/MANIFEST.MF
index e885b7bb4..7ec5cba29 100644
--- a/plugins/org.eclipse.emf.compare/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare/META-INF/MANIFEST.MF
@@ -18,6 +18,7 @@ Export-Package: org.eclipse.emf.compare,
org.eclipse.emf.compare.match,
org.eclipse.emf.compare.match.eobject,
org.eclipse.emf.compare.match.resource,
+ org.eclipse.emf.compare.merge,
org.eclipse.emf.compare.req,
org.eclipse.emf.compare.scope,
org.eclipse.emf.compare.util,
diff --git a/plugins/org.eclipse.emf.compare/build.properties b/plugins/org.eclipse.emf.compare/build.properties
index bf60a2f99..4708577f6 100644
--- a/plugins/org.eclipse.emf.compare/build.properties
+++ b/plugins/org.eclipse.emf.compare/build.properties
@@ -10,7 +10,6 @@
bin.includes = .,\
model/,\
META-INF/,\
- plugin.xml,\
plugin.properties,\
about.html,\
about.ini,\
diff --git a/plugins/org.eclipse.emf.compare/model/compare.ecore b/plugins/org.eclipse.emf.compare/model/compare.ecore
index a5af333a3..bcfbf848b 100644
--- a/plugins/org.eclipse.emf.compare/model/compare.ecore
+++ b/plugins/org.eclipse.emf.compare/model/compare.ecore
@@ -32,7 +32,7 @@
</eOperations>
<eOperations name="getEqualityHelper" eType="#//IEqualityHelper"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="matchedResources" upperBound="-1"
- eType="#//MatchResource" containment="true">
+ eType="#//MatchResource" containment="true" eOpposite="#//MatchResource/comparison">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="documentation" value="This contains the mappings for each compared Resource."/>
</eAnnotations>
@@ -96,6 +96,8 @@
<details key="documentation" value="Keeps a reference towards the origin Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the origin EResource could not be loaded."/>
</eAnnotations>
</eStructuralFeatures>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="comparison" eType="#//Comparison"
+ eOpposite="#//Comparison/matchedResources"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Match">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
diff --git a/plugins/org.eclipse.emf.compare/model/compare.genmodel b/plugins/org.eclipse.emf.compare/model/compare.genmodel
index 03c388f04..b8b596f66 100644
--- a/plugins/org.eclipse.emf.compare/model/compare.genmodel
+++ b/plugins/org.eclipse.emf.compare/model/compare.genmodel
@@ -35,7 +35,7 @@
<genDataTypes ecoreDataType="compare.ecore#//EIterable">
<genTypeParameters ecoreTypeParameter="compare.ecore#//EIterable/T"/>
</genDataTypes>
- <genDataTypes ecoreDataType="compare.ecore#//CompareConfiguration"/>
+ <genDataTypes ecoreDataType="compare.ecore#//IEqualityHelper"/>
<genClasses ecoreClass="compare.ecore#//Comparison">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference compare.ecore#//Comparison/matchedResources"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference compare.ecore#//Comparison/matches"/>
@@ -49,7 +49,7 @@
<genOperations ecoreOperation="compare.ecore#//Comparison/getMatch">
<genParameters ecoreParameter="compare.ecore#//Comparison/getMatch/element"/>
</genOperations>
- <genOperations ecoreOperation="compare.ecore#//Comparison/getConfiguration"/>
+ <genOperations ecoreOperation="compare.ecore#//Comparison/getEqualityHelper"/>
</genClasses>
<genClasses ecoreClass="compare.ecore#//MatchResource">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute compare.ecore#//MatchResource/leftURI"/>
@@ -58,6 +58,7 @@
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute compare.ecore#//MatchResource/left"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute compare.ecore#//MatchResource/right"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute compare.ecore#//MatchResource/origin"/>
+ <genFeatures property="None" notify="false" createChild="false" ecoreFeature="ecore:EReference compare.ecore#//MatchResource/comparison"/>
</genClasses>
<genClasses ecoreClass="compare.ecore#//Match">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference compare.ecore#//Match/submatches"/>
diff --git a/plugins/org.eclipse.emf.compare/plugin.xml b/plugins/org.eclipse.emf.compare/plugin.xml
deleted file mode 100644
index d2ea40aa0..000000000
--- a/plugins/org.eclipse.emf.compare/plugin.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.0"?>
-
-<!--
- Copyright (c) 2012 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
--->
-
-<plugin>
-
- <extension point="org.eclipse.emf.ecore.generated_package">
- <package
- uri="http://www.eclipse.org/emf/compare"
- class="org.eclipse.emf.compare.ComparePackage"
- genModel="model/compare.genmodel"/>
- </extension>
-
-</plugin>
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/ComparePackage.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/ComparePackage.java
index eb336b2ce..eb5602bbe 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/ComparePackage.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/ComparePackage.java
@@ -1,1857 +1,1885 @@
-/**
- * Copyright (c) 2012 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;
-
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EReference;
-
-/**
- * <!-- begin-user-doc -->
- * The <b>Package</b> for the model.
- * It contains accessors for the meta objects to represent
- * <ul>
- * <li>each class,</li>
- * <li>each feature of each class,</li>
- * <li>each enum,</li>
- * <li>and each data type</li>
- * </ul>
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.CompareFactory
- * @model kind="package"
- * @generated
- */
-public interface ComparePackage extends EPackage {
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * The package name.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- String eNAME = "compare"; //$NON-NLS-1$
-
- /**
- * The package namespace URI.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- String eNS_URI = "http://www.eclipse.org/emf/compare"; //$NON-NLS-1$
-
- /**
- * The package namespace name.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- String eNS_PREFIX = "compare"; //$NON-NLS-1$
-
- /**
- * The singleton instance of the package.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- ComparePackage eINSTANCE = org.eclipse.emf.compare.impl.ComparePackageImpl.init();
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.ComparisonImpl <em>Comparison</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ComparisonImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getComparison()
- * @generated
- */
- int COMPARISON = 0;
-
- /**
- * The feature id for the '<em><b>Matched Resources</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON__MATCHED_RESOURCES = 0;
-
- /**
- * The feature id for the '<em><b>Matches</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON__MATCHES = 1;
-
- /**
- * The feature id for the '<em><b>Conflicts</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON__CONFLICTS = 2;
-
- /**
- * The feature id for the '<em><b>Equivalences</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON__EQUIVALENCES = 3;
-
- /**
- * The feature id for the '<em><b>Three Way</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON__THREE_WAY = 4;
-
- /**
- * The number of structural features of the '<em>Comparison</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int COMPARISON_FEATURE_COUNT = 5;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.MatchResourceImpl <em>Match Resource</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.MatchResourceImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatchResource()
- * @generated
- */
- int MATCH_RESOURCE = 1;
-
- /**
- * The feature id for the '<em><b>Left URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__LEFT_URI = 0;
-
- /**
- * The feature id for the '<em><b>Right URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__RIGHT_URI = 1;
-
- /**
- * The feature id for the '<em><b>Origin URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__ORIGIN_URI = 2;
-
- /**
- * The feature id for the '<em><b>Left</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__LEFT = 3;
-
- /**
- * The feature id for the '<em><b>Right</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__RIGHT = 4;
-
- /**
- * The feature id for the '<em><b>Origin</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE__ORIGIN = 5;
-
- /**
- * The number of structural features of the '<em>Match Resource</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_RESOURCE_FEATURE_COUNT = 6;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.MatchImpl <em>Match</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.MatchImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatch()
- * @generated
- */
- int MATCH = 2;
-
- /**
- * The feature id for the '<em><b>Submatches</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH__SUBMATCHES = 0;
-
- /**
- * The feature id for the '<em><b>Differences</b></em>' containment reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH__DIFFERENCES = 1;
-
- /**
- * The feature id for the '<em><b>Left</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH__LEFT = 2;
-
- /**
- * The feature id for the '<em><b>Right</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH__RIGHT = 3;
-
- /**
- * The feature id for the '<em><b>Origin</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH__ORIGIN = 4;
-
- /**
- * The number of structural features of the '<em>Match</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int MATCH_FEATURE_COUNT = 5;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.DiffImpl <em>Diff</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.DiffImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDiff()
- * @generated
- */
- int DIFF = 3;
-
- /**
- * The feature id for the '<em><b>Match</b></em>' container reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__MATCH = 0;
-
- /**
- * The feature id for the '<em><b>Requires</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__REQUIRES = 1;
-
- /**
- * The feature id for the '<em><b>Required By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__REQUIRED_BY = 2;
-
- /**
- * The feature id for the '<em><b>Refines</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__REFINES = 3;
-
- /**
- * The feature id for the '<em><b>Refined By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__REFINED_BY = 4;
-
- /**
- * The feature id for the '<em><b>Kind</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__KIND = 5;
-
- /**
- * The feature id for the '<em><b>Source</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__SOURCE = 6;
-
- /**
- * The feature id for the '<em><b>State</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__STATE = 7;
-
- /**
- * The feature id for the '<em><b>Equivalence</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__EQUIVALENCE = 8;
-
- /**
- * The feature id for the '<em><b>Conflict</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF__CONFLICT = 9;
-
- /**
- * The number of structural features of the '<em>Diff</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int DIFF_FEATURE_COUNT = 10;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl <em>Resource Attachment Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getResourceAttachmentChange()
- * @generated
- */
- int RESOURCE_ATTACHMENT_CHANGE = 4;
-
- /**
- * The feature id for the '<em><b>Match</b></em>' container reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__MATCH = DIFF__MATCH;
-
- /**
- * The feature id for the '<em><b>Requires</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__REQUIRES = DIFF__REQUIRES;
-
- /**
- * The feature id for the '<em><b>Required By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
-
- /**
- * The feature id for the '<em><b>Refines</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__REFINES = DIFF__REFINES;
-
- /**
- * The feature id for the '<em><b>Refined By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__REFINED_BY = DIFF__REFINED_BY;
-
- /**
- * The feature id for the '<em><b>Kind</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__KIND = DIFF__KIND;
-
- /**
- * The feature id for the '<em><b>Source</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__SOURCE = DIFF__SOURCE;
-
- /**
- * The feature id for the '<em><b>State</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__STATE = DIFF__STATE;
-
- /**
- * The feature id for the '<em><b>Equivalence</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
-
- /**
- * The feature id for the '<em><b>Conflict</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__CONFLICT = DIFF__CONFLICT;
-
- /**
- * The feature id for the '<em><b>Resource URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI = DIFF_FEATURE_COUNT + 0;
-
- /**
- * The number of structural features of the '<em>Resource Attachment Change</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int RESOURCE_ATTACHMENT_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 1;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.ReferenceChangeImpl <em>Reference Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ReferenceChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getReferenceChange()
- * @generated
- */
- int REFERENCE_CHANGE = 5;
-
- /**
- * The feature id for the '<em><b>Match</b></em>' container reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__MATCH = DIFF__MATCH;
-
- /**
- * The feature id for the '<em><b>Requires</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__REQUIRES = DIFF__REQUIRES;
-
- /**
- * The feature id for the '<em><b>Required By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
-
- /**
- * The feature id for the '<em><b>Refines</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__REFINES = DIFF__REFINES;
-
- /**
- * The feature id for the '<em><b>Refined By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__REFINED_BY = DIFF__REFINED_BY;
-
- /**
- * The feature id for the '<em><b>Kind</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__KIND = DIFF__KIND;
-
- /**
- * The feature id for the '<em><b>Source</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__SOURCE = DIFF__SOURCE;
-
- /**
- * The feature id for the '<em><b>State</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__STATE = DIFF__STATE;
-
- /**
- * The feature id for the '<em><b>Equivalence</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
-
- /**
- * The feature id for the '<em><b>Conflict</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__CONFLICT = DIFF__CONFLICT;
-
- /**
- * The feature id for the '<em><b>Reference</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__REFERENCE = DIFF_FEATURE_COUNT + 0;
-
- /**
- * The feature id for the '<em><b>Value</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE__VALUE = DIFF_FEATURE_COUNT + 1;
-
- /**
- * The number of structural features of the '<em>Reference Change</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int REFERENCE_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 2;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.AttributeChangeImpl <em>Attribute Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.AttributeChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getAttributeChange()
- * @generated
- */
- int ATTRIBUTE_CHANGE = 6;
-
- /**
- * The feature id for the '<em><b>Match</b></em>' container reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__MATCH = DIFF__MATCH;
-
- /**
- * The feature id for the '<em><b>Requires</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__REQUIRES = DIFF__REQUIRES;
-
- /**
- * The feature id for the '<em><b>Required By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
-
- /**
- * The feature id for the '<em><b>Refines</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__REFINES = DIFF__REFINES;
-
- /**
- * The feature id for the '<em><b>Refined By</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__REFINED_BY = DIFF__REFINED_BY;
-
- /**
- * The feature id for the '<em><b>Kind</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__KIND = DIFF__KIND;
-
- /**
- * The feature id for the '<em><b>Source</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__SOURCE = DIFF__SOURCE;
-
- /**
- * The feature id for the '<em><b>State</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__STATE = DIFF__STATE;
-
- /**
- * The feature id for the '<em><b>Equivalence</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
-
- /**
- * The feature id for the '<em><b>Conflict</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__CONFLICT = DIFF__CONFLICT;
-
- /**
- * The feature id for the '<em><b>Attribute</b></em>' reference.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__ATTRIBUTE = DIFF_FEATURE_COUNT + 0;
-
- /**
- * The feature id for the '<em><b>Value</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE__VALUE = DIFF_FEATURE_COUNT + 1;
-
- /**
- * The number of structural features of the '<em>Attribute Change</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int ATTRIBUTE_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 2;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.ConflictImpl <em>Conflict</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ConflictImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflict()
- * @generated
- */
- int CONFLICT = 7;
-
- /**
- * The feature id for the '<em><b>Kind</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int CONFLICT__KIND = 0;
-
- /**
- * The feature id for the '<em><b>Differences</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int CONFLICT__DIFFERENCES = 1;
-
- /**
- * The number of structural features of the '<em>Conflict</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int CONFLICT_FEATURE_COUNT = 2;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.impl.EquivalenceImpl <em>Equivalence</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.EquivalenceImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEquivalence()
- * @generated
- */
- int EQUIVALENCE = 8;
-
- /**
- * The feature id for the '<em><b>Differences</b></em>' reference list.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int EQUIVALENCE__DIFFERENCES = 0;
-
- /**
- * The number of structural features of the '<em>Equivalence</em>' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- * @ordered
- */
- int EQUIVALENCE_FEATURE_COUNT = 1;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceKind
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceKind()
- * @generated
- */
- int DIFFERENCE_KIND = 9;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceSource
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceSource()
- * @generated
- */
- int DIFFERENCE_SOURCE = 10;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceState
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceState()
- * @generated
- */
- int DIFFERENCE_STATE = 11;
-
- /**
- * The meta object id for the '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.ConflictKind
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflictKind()
- * @generated
- */
- int CONFLICT_KIND = 12;
-
- /**
- * The meta object id for the '<em>EIterable</em>' data type.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see java.lang.Iterable
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEIterable()
- * @generated
- */
- int EITERABLE = 13;
-
- /**
- * The meta object id for the '<em>IEquality Helper</em>' data type.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.utils.IEqualityHelper
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getIEqualityHelper()
- * @generated
- */
- int IEQUALITY_HELPER = 14;
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.Comparison <em>Comparison</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Comparison</em>'.
- * @see org.eclipse.emf.compare.Comparison
- * @generated
- */
- EClass getComparison();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getMatchedResources <em>Matched Resources</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Matched Resources</em>'.
- * @see org.eclipse.emf.compare.Comparison#getMatchedResources()
- * @see #getComparison()
- * @generated
- */
- EReference getComparison_MatchedResources();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getMatches <em>Matches</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Matches</em>'.
- * @see org.eclipse.emf.compare.Comparison#getMatches()
- * @see #getComparison()
- * @generated
- */
- EReference getComparison_Matches();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getConflicts <em>Conflicts</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Conflicts</em>'.
- * @see org.eclipse.emf.compare.Comparison#getConflicts()
- * @see #getComparison()
- * @generated
- */
- EReference getComparison_Conflicts();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getEquivalences <em>Equivalences</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Equivalences</em>'.
- * @see org.eclipse.emf.compare.Comparison#getEquivalences()
- * @see #getComparison()
- * @generated
- */
- EReference getComparison_Equivalences();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Three Way</em>'.
- * @see org.eclipse.emf.compare.Comparison#isThreeWay()
- * @see #getComparison()
- * @generated
- */
- EAttribute getComparison_ThreeWay();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.MatchResource <em>Match Resource</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Match Resource</em>'.
- * @see org.eclipse.emf.compare.MatchResource
- * @generated
- */
- EClass getMatchResource();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Left URI</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getLeftURI()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_LeftURI();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Right URI</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getRightURI()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_RightURI();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Origin URI</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getOriginURI()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_OriginURI();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Left</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getLeft()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_Left();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Right</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getRight()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_Right();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Origin</em>'.
- * @see org.eclipse.emf.compare.MatchResource#getOrigin()
- * @see #getMatchResource()
- * @generated
- */
- EAttribute getMatchResource_Origin();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.Match <em>Match</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Match</em>'.
- * @see org.eclipse.emf.compare.Match
- * @generated
- */
- EClass getMatch();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Match#getSubmatches <em>Submatches</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Submatches</em>'.
- * @see org.eclipse.emf.compare.Match#getSubmatches()
- * @see #getMatch()
- * @generated
- */
- EReference getMatch_Submatches();
-
- /**
- * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Match#getDifferences <em>Differences</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the containment reference list '<em>Differences</em>'.
- * @see org.eclipse.emf.compare.Match#getDifferences()
- * @see #getMatch()
- * @generated
- */
- EReference getMatch_Differences();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getLeft <em>Left</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Left</em>'.
- * @see org.eclipse.emf.compare.Match#getLeft()
- * @see #getMatch()
- * @generated
- */
- EReference getMatch_Left();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getRight <em>Right</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Right</em>'.
- * @see org.eclipse.emf.compare.Match#getRight()
- * @see #getMatch()
- * @generated
- */
- EReference getMatch_Right();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getOrigin <em>Origin</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Origin</em>'.
- * @see org.eclipse.emf.compare.Match#getOrigin()
- * @see #getMatch()
- * @generated
- */
- EReference getMatch_Origin();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.Diff <em>Diff</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Diff</em>'.
- * @see org.eclipse.emf.compare.Diff
- * @generated
- */
- EClass getDiff();
-
- /**
- * Returns the meta object for the container reference '{@link org.eclipse.emf.compare.Diff#getMatch <em>Match</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the container reference '<em>Match</em>'.
- * @see org.eclipse.emf.compare.Diff#getMatch()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_Match();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRequires <em>Requires</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Requires</em>'.
- * @see org.eclipse.emf.compare.Diff#getRequires()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_Requires();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRequiredBy <em>Required By</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Required By</em>'.
- * @see org.eclipse.emf.compare.Diff#getRequiredBy()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_RequiredBy();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRefines <em>Refines</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Refines</em>'.
- * @see org.eclipse.emf.compare.Diff#getRefines()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_Refines();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRefinedBy <em>Refined By</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Refined By</em>'.
- * @see org.eclipse.emf.compare.Diff#getRefinedBy()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_RefinedBy();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getKind <em>Kind</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Kind</em>'.
- * @see org.eclipse.emf.compare.Diff#getKind()
- * @see #getDiff()
- * @generated
- */
- EAttribute getDiff_Kind();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getSource <em>Source</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Source</em>'.
- * @see org.eclipse.emf.compare.Diff#getSource()
- * @see #getDiff()
- * @generated
- */
- EAttribute getDiff_Source();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getState <em>State</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>State</em>'.
- * @see org.eclipse.emf.compare.Diff#getState()
- * @see #getDiff()
- * @generated
- */
- EAttribute getDiff_State();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Diff#getEquivalence <em>Equivalence</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Equivalence</em>'.
- * @see org.eclipse.emf.compare.Diff#getEquivalence()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_Equivalence();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Diff#getConflict <em>Conflict</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Conflict</em>'.
- * @see org.eclipse.emf.compare.Diff#getConflict()
- * @see #getDiff()
- * @generated
- */
- EReference getDiff_Conflict();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.ResourceAttachmentChange <em>Resource Attachment Change</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Resource Attachment Change</em>'.
- * @see org.eclipse.emf.compare.ResourceAttachmentChange
- * @generated
- */
- EClass getResourceAttachmentChange();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.ResourceAttachmentChange#getResourceURI <em>Resource URI</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Resource URI</em>'.
- * @see org.eclipse.emf.compare.ResourceAttachmentChange#getResourceURI()
- * @see #getResourceAttachmentChange()
- * @generated
- */
- EAttribute getResourceAttachmentChange_ResourceURI();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.ReferenceChange <em>Reference Change</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Reference Change</em>'.
- * @see org.eclipse.emf.compare.ReferenceChange
- * @generated
- */
- EClass getReferenceChange();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.ReferenceChange#getReference <em>Reference</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Reference</em>'.
- * @see org.eclipse.emf.compare.ReferenceChange#getReference()
- * @see #getReferenceChange()
- * @generated
- */
- EReference getReferenceChange_Reference();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.ReferenceChange#getValue <em>Value</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Value</em>'.
- * @see org.eclipse.emf.compare.ReferenceChange#getValue()
- * @see #getReferenceChange()
- * @generated
- */
- EReference getReferenceChange_Value();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.AttributeChange <em>Attribute Change</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Attribute Change</em>'.
- * @see org.eclipse.emf.compare.AttributeChange
- * @generated
- */
- EClass getAttributeChange();
-
- /**
- * Returns the meta object for the reference '{@link org.eclipse.emf.compare.AttributeChange#getAttribute <em>Attribute</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference '<em>Attribute</em>'.
- * @see org.eclipse.emf.compare.AttributeChange#getAttribute()
- * @see #getAttributeChange()
- * @generated
- */
- EReference getAttributeChange_Attribute();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.AttributeChange#getValue <em>Value</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Value</em>'.
- * @see org.eclipse.emf.compare.AttributeChange#getValue()
- * @see #getAttributeChange()
- * @generated
- */
- EAttribute getAttributeChange_Value();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.Conflict <em>Conflict</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Conflict</em>'.
- * @see org.eclipse.emf.compare.Conflict
- * @generated
- */
- EClass getConflict();
-
- /**
- * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Conflict#getKind <em>Kind</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the attribute '<em>Kind</em>'.
- * @see org.eclipse.emf.compare.Conflict#getKind()
- * @see #getConflict()
- * @generated
- */
- EAttribute getConflict_Kind();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Conflict#getDifferences <em>Differences</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Differences</em>'.
- * @see org.eclipse.emf.compare.Conflict#getDifferences()
- * @see #getConflict()
- * @generated
- */
- EReference getConflict_Differences();
-
- /**
- * Returns the meta object for class '{@link org.eclipse.emf.compare.Equivalence <em>Equivalence</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for class '<em>Equivalence</em>'.
- * @see org.eclipse.emf.compare.Equivalence
- * @generated
- */
- EClass getEquivalence();
-
- /**
- * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Equivalence#getDifferences <em>Differences</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for the reference list '<em>Differences</em>'.
- * @see org.eclipse.emf.compare.Equivalence#getDifferences()
- * @see #getEquivalence()
- * @generated
- */
- EReference getEquivalence_Differences();
-
- /**
- * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for enum '<em>Difference Kind</em>'.
- * @see org.eclipse.emf.compare.DifferenceKind
- * @generated
- */
- EEnum getDifferenceKind();
-
- /**
- * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for enum '<em>Difference Source</em>'.
- * @see org.eclipse.emf.compare.DifferenceSource
- * @generated
- */
- EEnum getDifferenceSource();
-
- /**
- * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for enum '<em>Difference State</em>'.
- * @see org.eclipse.emf.compare.DifferenceState
- * @generated
- */
- EEnum getDifferenceState();
-
- /**
- * Returns the meta object for enum '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for enum '<em>Conflict Kind</em>'.
- * @see org.eclipse.emf.compare.ConflictKind
- * @generated
- */
- EEnum getConflictKind();
-
- /**
- * Returns the meta object for data type '{@link java.lang.Iterable <em>EIterable</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for data type '<em>EIterable</em>'.
- * @see java.lang.Iterable
- * @model instanceClass="java.lang.Iterable" typeParameters="T"
- * @generated
- */
- EDataType getEIterable();
-
- /**
- * Returns the meta object for data type '{@link org.eclipse.emf.compare.utils.IEqualityHelper <em>IEquality Helper</em>}'.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the meta object for data type '<em>IEquality Helper</em>'.
- * @see org.eclipse.emf.compare.utils.IEqualityHelper
- * @model instanceClass="org.eclipse.emf.compare.utils.IEqualityHelper" serializeable="false"
- * @generated
- */
- EDataType getIEqualityHelper();
-
- /**
- * Returns the factory that creates the instances of the model.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @return the factory that creates the instances of the model.
- * @generated
- */
- CompareFactory getCompareFactory();
-
- /**
- * <!-- begin-user-doc -->
- * Defines literals for the meta objects that represent
- * <ul>
- * <li>each class,</li>
- * <li>each feature of each class,</li>
- * <li>each enum,</li>
- * <li>and each data type</li>
- * </ul>
- * <!-- end-user-doc -->
- * @generated
- */
- @SuppressWarnings("hiding")
- // generated code, removing warnings
- interface Literals {
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ComparisonImpl <em>Comparison</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ComparisonImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getComparison()
- * @generated
- */
- EClass COMPARISON = eINSTANCE.getComparison();
-
- /**
- * The meta object literal for the '<em><b>Matched Resources</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference COMPARISON__MATCHED_RESOURCES = eINSTANCE.getComparison_MatchedResources();
-
- /**
- * The meta object literal for the '<em><b>Matches</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference COMPARISON__MATCHES = eINSTANCE.getComparison_Matches();
-
- /**
- * The meta object literal for the '<em><b>Conflicts</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference COMPARISON__CONFLICTS = eINSTANCE.getComparison_Conflicts();
-
- /**
- * The meta object literal for the '<em><b>Equivalences</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference COMPARISON__EQUIVALENCES = eINSTANCE.getComparison_Equivalences();
-
- /**
- * The meta object literal for the '<em><b>Three Way</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute COMPARISON__THREE_WAY = eINSTANCE.getComparison_ThreeWay();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.MatchResourceImpl <em>Match Resource</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.MatchResourceImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatchResource()
- * @generated
- */
- EClass MATCH_RESOURCE = eINSTANCE.getMatchResource();
-
- /**
- * The meta object literal for the '<em><b>Left URI</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__LEFT_URI = eINSTANCE.getMatchResource_LeftURI();
-
- /**
- * The meta object literal for the '<em><b>Right URI</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__RIGHT_URI = eINSTANCE.getMatchResource_RightURI();
-
- /**
- * The meta object literal for the '<em><b>Origin URI</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__ORIGIN_URI = eINSTANCE.getMatchResource_OriginURI();
-
- /**
- * The meta object literal for the '<em><b>Left</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__LEFT = eINSTANCE.getMatchResource_Left();
-
- /**
- * The meta object literal for the '<em><b>Right</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__RIGHT = eINSTANCE.getMatchResource_Right();
-
- /**
- * The meta object literal for the '<em><b>Origin</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute MATCH_RESOURCE__ORIGIN = eINSTANCE.getMatchResource_Origin();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.MatchImpl <em>Match</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.MatchImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatch()
- * @generated
- */
- EClass MATCH = eINSTANCE.getMatch();
-
- /**
- * The meta object literal for the '<em><b>Submatches</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference MATCH__SUBMATCHES = eINSTANCE.getMatch_Submatches();
-
- /**
- * The meta object literal for the '<em><b>Differences</b></em>' containment reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference MATCH__DIFFERENCES = eINSTANCE.getMatch_Differences();
-
- /**
- * The meta object literal for the '<em><b>Left</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference MATCH__LEFT = eINSTANCE.getMatch_Left();
-
- /**
- * The meta object literal for the '<em><b>Right</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference MATCH__RIGHT = eINSTANCE.getMatch_Right();
-
- /**
- * The meta object literal for the '<em><b>Origin</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference MATCH__ORIGIN = eINSTANCE.getMatch_Origin();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.DiffImpl <em>Diff</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.DiffImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDiff()
- * @generated
- */
- EClass DIFF = eINSTANCE.getDiff();
-
- /**
- * The meta object literal for the '<em><b>Match</b></em>' container reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__MATCH = eINSTANCE.getDiff_Match();
-
- /**
- * The meta object literal for the '<em><b>Requires</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__REQUIRES = eINSTANCE.getDiff_Requires();
-
- /**
- * The meta object literal for the '<em><b>Required By</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__REQUIRED_BY = eINSTANCE.getDiff_RequiredBy();
-
- /**
- * The meta object literal for the '<em><b>Refines</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__REFINES = eINSTANCE.getDiff_Refines();
-
- /**
- * The meta object literal for the '<em><b>Refined By</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__REFINED_BY = eINSTANCE.getDiff_RefinedBy();
-
- /**
- * The meta object literal for the '<em><b>Kind</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute DIFF__KIND = eINSTANCE.getDiff_Kind();
-
- /**
- * The meta object literal for the '<em><b>Source</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute DIFF__SOURCE = eINSTANCE.getDiff_Source();
-
- /**
- * The meta object literal for the '<em><b>State</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute DIFF__STATE = eINSTANCE.getDiff_State();
-
- /**
- * The meta object literal for the '<em><b>Equivalence</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__EQUIVALENCE = eINSTANCE.getDiff_Equivalence();
-
- /**
- * The meta object literal for the '<em><b>Conflict</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference DIFF__CONFLICT = eINSTANCE.getDiff_Conflict();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl <em>Resource Attachment Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getResourceAttachmentChange()
- * @generated
- */
- EClass RESOURCE_ATTACHMENT_CHANGE = eINSTANCE.getResourceAttachmentChange();
-
- /**
- * The meta object literal for the '<em><b>Resource URI</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI = eINSTANCE
- .getResourceAttachmentChange_ResourceURI();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ReferenceChangeImpl <em>Reference Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ReferenceChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getReferenceChange()
- * @generated
- */
- EClass REFERENCE_CHANGE = eINSTANCE.getReferenceChange();
-
- /**
- * The meta object literal for the '<em><b>Reference</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference REFERENCE_CHANGE__REFERENCE = eINSTANCE.getReferenceChange_Reference();
-
- /**
- * The meta object literal for the '<em><b>Value</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference REFERENCE_CHANGE__VALUE = eINSTANCE.getReferenceChange_Value();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.AttributeChangeImpl <em>Attribute Change</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.AttributeChangeImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getAttributeChange()
- * @generated
- */
- EClass ATTRIBUTE_CHANGE = eINSTANCE.getAttributeChange();
-
- /**
- * The meta object literal for the '<em><b>Attribute</b></em>' reference feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference ATTRIBUTE_CHANGE__ATTRIBUTE = eINSTANCE.getAttributeChange_Attribute();
-
- /**
- * The meta object literal for the '<em><b>Value</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute ATTRIBUTE_CHANGE__VALUE = eINSTANCE.getAttributeChange_Value();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ConflictImpl <em>Conflict</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.ConflictImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflict()
- * @generated
- */
- EClass CONFLICT = eINSTANCE.getConflict();
-
- /**
- * The meta object literal for the '<em><b>Kind</b></em>' attribute feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EAttribute CONFLICT__KIND = eINSTANCE.getConflict_Kind();
-
- /**
- * The meta object literal for the '<em><b>Differences</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference CONFLICT__DIFFERENCES = eINSTANCE.getConflict_Differences();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.impl.EquivalenceImpl <em>Equivalence</em>}' class.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.impl.EquivalenceImpl
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEquivalence()
- * @generated
- */
- EClass EQUIVALENCE = eINSTANCE.getEquivalence();
-
- /**
- * The meta object literal for the '<em><b>Differences</b></em>' reference list feature.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- EReference EQUIVALENCE__DIFFERENCES = eINSTANCE.getEquivalence_Differences();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceKind
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceKind()
- * @generated
- */
- EEnum DIFFERENCE_KIND = eINSTANCE.getDifferenceKind();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceSource
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceSource()
- * @generated
- */
- EEnum DIFFERENCE_SOURCE = eINSTANCE.getDifferenceSource();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.DifferenceState
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceState()
- * @generated
- */
- EEnum DIFFERENCE_STATE = eINSTANCE.getDifferenceState();
-
- /**
- * The meta object literal for the '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}' enum.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.ConflictKind
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflictKind()
- * @generated
- */
- EEnum CONFLICT_KIND = eINSTANCE.getConflictKind();
-
- /**
- * The meta object literal for the '<em>EIterable</em>' data type.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see java.lang.Iterable
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEIterable()
- * @generated
- */
- EDataType EITERABLE = eINSTANCE.getEIterable();
-
- /**
- * The meta object literal for the '<em>IEquality Helper</em>' data type.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see org.eclipse.emf.compare.utils.IEqualityHelper
- * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getIEqualityHelper()
- * @generated
- */
- EDataType IEQUALITY_HELPER = eINSTANCE.getIEqualityHelper();
-
- }
-
-} //ComparePackage
+/**
+ * Copyright (c) 2012 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;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.CompareFactory
+ * @model kind="package"
+ * @generated
+ */
+public interface ComparePackage extends EPackage {
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * The package name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ String eNAME = "compare"; //$NON-NLS-1$
+
+ /**
+ * The package namespace URI.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ String eNS_URI = "http://www.eclipse.org/emf/compare"; //$NON-NLS-1$
+
+ /**
+ * The package namespace name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ String eNS_PREFIX = "compare"; //$NON-NLS-1$
+
+ /**
+ * The singleton instance of the package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ ComparePackage eINSTANCE = org.eclipse.emf.compare.impl.ComparePackageImpl.init();
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.ComparisonImpl <em>Comparison</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ComparisonImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getComparison()
+ * @generated
+ */
+ int COMPARISON = 0;
+
+ /**
+ * The feature id for the '<em><b>Matched Resources</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON__MATCHED_RESOURCES = 0;
+
+ /**
+ * The feature id for the '<em><b>Matches</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON__MATCHES = 1;
+
+ /**
+ * The feature id for the '<em><b>Conflicts</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON__CONFLICTS = 2;
+
+ /**
+ * The feature id for the '<em><b>Equivalences</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON__EQUIVALENCES = 3;
+
+ /**
+ * The feature id for the '<em><b>Three Way</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON__THREE_WAY = 4;
+
+ /**
+ * The number of structural features of the '<em>Comparison</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int COMPARISON_FEATURE_COUNT = 5;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.MatchResourceImpl <em>Match Resource</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.MatchResourceImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatchResource()
+ * @generated
+ */
+ int MATCH_RESOURCE = 1;
+
+ /**
+ * The feature id for the '<em><b>Left URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__LEFT_URI = 0;
+
+ /**
+ * The feature id for the '<em><b>Right URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__RIGHT_URI = 1;
+
+ /**
+ * The feature id for the '<em><b>Origin URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__ORIGIN_URI = 2;
+
+ /**
+ * The feature id for the '<em><b>Left</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__LEFT = 3;
+
+ /**
+ * The feature id for the '<em><b>Right</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__RIGHT = 4;
+
+ /**
+ * The feature id for the '<em><b>Origin</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__ORIGIN = 5;
+
+ /**
+ * The feature id for the '<em><b>Comparison</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE__COMPARISON = 6;
+
+ /**
+ * The number of structural features of the '<em>Match Resource</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_RESOURCE_FEATURE_COUNT = 7;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.MatchImpl <em>Match</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.MatchImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatch()
+ * @generated
+ */
+ int MATCH = 2;
+
+ /**
+ * The feature id for the '<em><b>Submatches</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH__SUBMATCHES = 0;
+
+ /**
+ * The feature id for the '<em><b>Differences</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH__DIFFERENCES = 1;
+
+ /**
+ * The feature id for the '<em><b>Left</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH__LEFT = 2;
+
+ /**
+ * The feature id for the '<em><b>Right</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH__RIGHT = 3;
+
+ /**
+ * The feature id for the '<em><b>Origin</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH__ORIGIN = 4;
+
+ /**
+ * The number of structural features of the '<em>Match</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int MATCH_FEATURE_COUNT = 5;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.DiffImpl <em>Diff</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.DiffImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDiff()
+ * @generated
+ */
+ int DIFF = 3;
+
+ /**
+ * The feature id for the '<em><b>Match</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__MATCH = 0;
+
+ /**
+ * The feature id for the '<em><b>Requires</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__REQUIRES = 1;
+
+ /**
+ * The feature id for the '<em><b>Required By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__REQUIRED_BY = 2;
+
+ /**
+ * The feature id for the '<em><b>Refines</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__REFINES = 3;
+
+ /**
+ * The feature id for the '<em><b>Refined By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__REFINED_BY = 4;
+
+ /**
+ * The feature id for the '<em><b>Kind</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__KIND = 5;
+
+ /**
+ * The feature id for the '<em><b>Source</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__SOURCE = 6;
+
+ /**
+ * The feature id for the '<em><b>State</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__STATE = 7;
+
+ /**
+ * The feature id for the '<em><b>Equivalence</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__EQUIVALENCE = 8;
+
+ /**
+ * The feature id for the '<em><b>Conflict</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF__CONFLICT = 9;
+
+ /**
+ * The number of structural features of the '<em>Diff</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int DIFF_FEATURE_COUNT = 10;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl <em>Resource Attachment Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getResourceAttachmentChange()
+ * @generated
+ */
+ int RESOURCE_ATTACHMENT_CHANGE = 4;
+
+ /**
+ * The feature id for the '<em><b>Match</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__MATCH = DIFF__MATCH;
+
+ /**
+ * The feature id for the '<em><b>Requires</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__REQUIRES = DIFF__REQUIRES;
+
+ /**
+ * The feature id for the '<em><b>Required By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
+
+ /**
+ * The feature id for the '<em><b>Refines</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__REFINES = DIFF__REFINES;
+
+ /**
+ * The feature id for the '<em><b>Refined By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__REFINED_BY = DIFF__REFINED_BY;
+
+ /**
+ * The feature id for the '<em><b>Kind</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__KIND = DIFF__KIND;
+
+ /**
+ * The feature id for the '<em><b>Source</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__SOURCE = DIFF__SOURCE;
+
+ /**
+ * The feature id for the '<em><b>State</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__STATE = DIFF__STATE;
+
+ /**
+ * The feature id for the '<em><b>Equivalence</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
+
+ /**
+ * The feature id for the '<em><b>Conflict</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__CONFLICT = DIFF__CONFLICT;
+
+ /**
+ * The feature id for the '<em><b>Resource URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI = DIFF_FEATURE_COUNT + 0;
+
+ /**
+ * The number of structural features of the '<em>Resource Attachment Change</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int RESOURCE_ATTACHMENT_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 1;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.ReferenceChangeImpl <em>Reference Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ReferenceChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getReferenceChange()
+ * @generated
+ */
+ int REFERENCE_CHANGE = 5;
+
+ /**
+ * The feature id for the '<em><b>Match</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__MATCH = DIFF__MATCH;
+
+ /**
+ * The feature id for the '<em><b>Requires</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__REQUIRES = DIFF__REQUIRES;
+
+ /**
+ * The feature id for the '<em><b>Required By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
+
+ /**
+ * The feature id for the '<em><b>Refines</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__REFINES = DIFF__REFINES;
+
+ /**
+ * The feature id for the '<em><b>Refined By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__REFINED_BY = DIFF__REFINED_BY;
+
+ /**
+ * The feature id for the '<em><b>Kind</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__KIND = DIFF__KIND;
+
+ /**
+ * The feature id for the '<em><b>Source</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__SOURCE = DIFF__SOURCE;
+
+ /**
+ * The feature id for the '<em><b>State</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__STATE = DIFF__STATE;
+
+ /**
+ * The feature id for the '<em><b>Equivalence</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
+
+ /**
+ * The feature id for the '<em><b>Conflict</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__CONFLICT = DIFF__CONFLICT;
+
+ /**
+ * The feature id for the '<em><b>Reference</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__REFERENCE = DIFF_FEATURE_COUNT + 0;
+
+ /**
+ * The feature id for the '<em><b>Value</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE__VALUE = DIFF_FEATURE_COUNT + 1;
+
+ /**
+ * The number of structural features of the '<em>Reference Change</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int REFERENCE_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 2;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.AttributeChangeImpl <em>Attribute Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.AttributeChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getAttributeChange()
+ * @generated
+ */
+ int ATTRIBUTE_CHANGE = 6;
+
+ /**
+ * The feature id for the '<em><b>Match</b></em>' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__MATCH = DIFF__MATCH;
+
+ /**
+ * The feature id for the '<em><b>Requires</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__REQUIRES = DIFF__REQUIRES;
+
+ /**
+ * The feature id for the '<em><b>Required By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__REQUIRED_BY = DIFF__REQUIRED_BY;
+
+ /**
+ * The feature id for the '<em><b>Refines</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__REFINES = DIFF__REFINES;
+
+ /**
+ * The feature id for the '<em><b>Refined By</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__REFINED_BY = DIFF__REFINED_BY;
+
+ /**
+ * The feature id for the '<em><b>Kind</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__KIND = DIFF__KIND;
+
+ /**
+ * The feature id for the '<em><b>Source</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__SOURCE = DIFF__SOURCE;
+
+ /**
+ * The feature id for the '<em><b>State</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__STATE = DIFF__STATE;
+
+ /**
+ * The feature id for the '<em><b>Equivalence</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__EQUIVALENCE = DIFF__EQUIVALENCE;
+
+ /**
+ * The feature id for the '<em><b>Conflict</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__CONFLICT = DIFF__CONFLICT;
+
+ /**
+ * The feature id for the '<em><b>Attribute</b></em>' reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__ATTRIBUTE = DIFF_FEATURE_COUNT + 0;
+
+ /**
+ * The feature id for the '<em><b>Value</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE__VALUE = DIFF_FEATURE_COUNT + 1;
+
+ /**
+ * The number of structural features of the '<em>Attribute Change</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int ATTRIBUTE_CHANGE_FEATURE_COUNT = DIFF_FEATURE_COUNT + 2;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.ConflictImpl <em>Conflict</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ConflictImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflict()
+ * @generated
+ */
+ int CONFLICT = 7;
+
+ /**
+ * The feature id for the '<em><b>Kind</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int CONFLICT__KIND = 0;
+
+ /**
+ * The feature id for the '<em><b>Differences</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int CONFLICT__DIFFERENCES = 1;
+
+ /**
+ * The number of structural features of the '<em>Conflict</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int CONFLICT_FEATURE_COUNT = 2;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.impl.EquivalenceImpl <em>Equivalence</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.EquivalenceImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEquivalence()
+ * @generated
+ */
+ int EQUIVALENCE = 8;
+
+ /**
+ * The feature id for the '<em><b>Differences</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int EQUIVALENCE__DIFFERENCES = 0;
+
+ /**
+ * The number of structural features of the '<em>Equivalence</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ * @ordered
+ */
+ int EQUIVALENCE_FEATURE_COUNT = 1;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceKind
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceKind()
+ * @generated
+ */
+ int DIFFERENCE_KIND = 9;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceSource
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceSource()
+ * @generated
+ */
+ int DIFFERENCE_SOURCE = 10;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceState
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceState()
+ * @generated
+ */
+ int DIFFERENCE_STATE = 11;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.ConflictKind
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflictKind()
+ * @generated
+ */
+ int CONFLICT_KIND = 12;
+
+ /**
+ * The meta object id for the '<em>EIterable</em>' data type.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see java.lang.Iterable
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEIterable()
+ * @generated
+ */
+ int EITERABLE = 13;
+
+ /**
+ * The meta object id for the '<em>IEquality Helper</em>' data type.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.utils.IEqualityHelper
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getIEqualityHelper()
+ * @generated
+ */
+ int IEQUALITY_HELPER = 14;
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.Comparison <em>Comparison</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Comparison</em>'.
+ * @see org.eclipse.emf.compare.Comparison
+ * @generated
+ */
+ EClass getComparison();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getMatchedResources <em>Matched Resources</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Matched Resources</em>'.
+ * @see org.eclipse.emf.compare.Comparison#getMatchedResources()
+ * @see #getComparison()
+ * @generated
+ */
+ EReference getComparison_MatchedResources();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getMatches <em>Matches</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Matches</em>'.
+ * @see org.eclipse.emf.compare.Comparison#getMatches()
+ * @see #getComparison()
+ * @generated
+ */
+ EReference getComparison_Matches();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getConflicts <em>Conflicts</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Conflicts</em>'.
+ * @see org.eclipse.emf.compare.Comparison#getConflicts()
+ * @see #getComparison()
+ * @generated
+ */
+ EReference getComparison_Conflicts();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Comparison#getEquivalences <em>Equivalences</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Equivalences</em>'.
+ * @see org.eclipse.emf.compare.Comparison#getEquivalences()
+ * @see #getComparison()
+ * @generated
+ */
+ EReference getComparison_Equivalences();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Three Way</em>'.
+ * @see org.eclipse.emf.compare.Comparison#isThreeWay()
+ * @see #getComparison()
+ * @generated
+ */
+ EAttribute getComparison_ThreeWay();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.MatchResource <em>Match Resource</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Match Resource</em>'.
+ * @see org.eclipse.emf.compare.MatchResource
+ * @generated
+ */
+ EClass getMatchResource();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Left URI</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getLeftURI()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_LeftURI();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Right URI</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getRightURI()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_RightURI();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Origin URI</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getOriginURI()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_OriginURI();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Left</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getLeft()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_Left();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Right</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getRight()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_Right();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Origin</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getOrigin()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EAttribute getMatchResource_Origin();
+
+ /**
+ * Returns the meta object for the container reference '{@link org.eclipse.emf.compare.MatchResource#getComparison <em>Comparison</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the container reference '<em>Comparison</em>'.
+ * @see org.eclipse.emf.compare.MatchResource#getComparison()
+ * @see #getMatchResource()
+ * @generated
+ */
+ EReference getMatchResource_Comparison();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.Match <em>Match</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Match</em>'.
+ * @see org.eclipse.emf.compare.Match
+ * @generated
+ */
+ EClass getMatch();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Match#getSubmatches <em>Submatches</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Submatches</em>'.
+ * @see org.eclipse.emf.compare.Match#getSubmatches()
+ * @see #getMatch()
+ * @generated
+ */
+ EReference getMatch_Submatches();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.emf.compare.Match#getDifferences <em>Differences</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the containment reference list '<em>Differences</em>'.
+ * @see org.eclipse.emf.compare.Match#getDifferences()
+ * @see #getMatch()
+ * @generated
+ */
+ EReference getMatch_Differences();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getLeft <em>Left</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Left</em>'.
+ * @see org.eclipse.emf.compare.Match#getLeft()
+ * @see #getMatch()
+ * @generated
+ */
+ EReference getMatch_Left();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getRight <em>Right</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Right</em>'.
+ * @see org.eclipse.emf.compare.Match#getRight()
+ * @see #getMatch()
+ * @generated
+ */
+ EReference getMatch_Right();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Match#getOrigin <em>Origin</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Origin</em>'.
+ * @see org.eclipse.emf.compare.Match#getOrigin()
+ * @see #getMatch()
+ * @generated
+ */
+ EReference getMatch_Origin();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.Diff <em>Diff</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Diff</em>'.
+ * @see org.eclipse.emf.compare.Diff
+ * @generated
+ */
+ EClass getDiff();
+
+ /**
+ * Returns the meta object for the container reference '{@link org.eclipse.emf.compare.Diff#getMatch <em>Match</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the container reference '<em>Match</em>'.
+ * @see org.eclipse.emf.compare.Diff#getMatch()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_Match();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRequires <em>Requires</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Requires</em>'.
+ * @see org.eclipse.emf.compare.Diff#getRequires()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_Requires();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRequiredBy <em>Required By</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Required By</em>'.
+ * @see org.eclipse.emf.compare.Diff#getRequiredBy()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_RequiredBy();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRefines <em>Refines</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Refines</em>'.
+ * @see org.eclipse.emf.compare.Diff#getRefines()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_Refines();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Diff#getRefinedBy <em>Refined By</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Refined By</em>'.
+ * @see org.eclipse.emf.compare.Diff#getRefinedBy()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_RefinedBy();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getKind <em>Kind</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Kind</em>'.
+ * @see org.eclipse.emf.compare.Diff#getKind()
+ * @see #getDiff()
+ * @generated
+ */
+ EAttribute getDiff_Kind();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getSource <em>Source</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Source</em>'.
+ * @see org.eclipse.emf.compare.Diff#getSource()
+ * @see #getDiff()
+ * @generated
+ */
+ EAttribute getDiff_Source();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Diff#getState <em>State</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>State</em>'.
+ * @see org.eclipse.emf.compare.Diff#getState()
+ * @see #getDiff()
+ * @generated
+ */
+ EAttribute getDiff_State();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Diff#getEquivalence <em>Equivalence</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Equivalence</em>'.
+ * @see org.eclipse.emf.compare.Diff#getEquivalence()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_Equivalence();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.Diff#getConflict <em>Conflict</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Conflict</em>'.
+ * @see org.eclipse.emf.compare.Diff#getConflict()
+ * @see #getDiff()
+ * @generated
+ */
+ EReference getDiff_Conflict();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.ResourceAttachmentChange <em>Resource Attachment Change</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Resource Attachment Change</em>'.
+ * @see org.eclipse.emf.compare.ResourceAttachmentChange
+ * @generated
+ */
+ EClass getResourceAttachmentChange();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.ResourceAttachmentChange#getResourceURI <em>Resource URI</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Resource URI</em>'.
+ * @see org.eclipse.emf.compare.ResourceAttachmentChange#getResourceURI()
+ * @see #getResourceAttachmentChange()
+ * @generated
+ */
+ EAttribute getResourceAttachmentChange_ResourceURI();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.ReferenceChange <em>Reference Change</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Reference Change</em>'.
+ * @see org.eclipse.emf.compare.ReferenceChange
+ * @generated
+ */
+ EClass getReferenceChange();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.ReferenceChange#getReference <em>Reference</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Reference</em>'.
+ * @see org.eclipse.emf.compare.ReferenceChange#getReference()
+ * @see #getReferenceChange()
+ * @generated
+ */
+ EReference getReferenceChange_Reference();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.ReferenceChange#getValue <em>Value</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Value</em>'.
+ * @see org.eclipse.emf.compare.ReferenceChange#getValue()
+ * @see #getReferenceChange()
+ * @generated
+ */
+ EReference getReferenceChange_Value();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.AttributeChange <em>Attribute Change</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Attribute Change</em>'.
+ * @see org.eclipse.emf.compare.AttributeChange
+ * @generated
+ */
+ EClass getAttributeChange();
+
+ /**
+ * Returns the meta object for the reference '{@link org.eclipse.emf.compare.AttributeChange#getAttribute <em>Attribute</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference '<em>Attribute</em>'.
+ * @see org.eclipse.emf.compare.AttributeChange#getAttribute()
+ * @see #getAttributeChange()
+ * @generated
+ */
+ EReference getAttributeChange_Attribute();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.AttributeChange#getValue <em>Value</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Value</em>'.
+ * @see org.eclipse.emf.compare.AttributeChange#getValue()
+ * @see #getAttributeChange()
+ * @generated
+ */
+ EAttribute getAttributeChange_Value();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.Conflict <em>Conflict</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Conflict</em>'.
+ * @see org.eclipse.emf.compare.Conflict
+ * @generated
+ */
+ EClass getConflict();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.emf.compare.Conflict#getKind <em>Kind</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the attribute '<em>Kind</em>'.
+ * @see org.eclipse.emf.compare.Conflict#getKind()
+ * @see #getConflict()
+ * @generated
+ */
+ EAttribute getConflict_Kind();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Conflict#getDifferences <em>Differences</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Differences</em>'.
+ * @see org.eclipse.emf.compare.Conflict#getDifferences()
+ * @see #getConflict()
+ * @generated
+ */
+ EReference getConflict_Differences();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.emf.compare.Equivalence <em>Equivalence</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for class '<em>Equivalence</em>'.
+ * @see org.eclipse.emf.compare.Equivalence
+ * @generated
+ */
+ EClass getEquivalence();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.emf.compare.Equivalence#getDifferences <em>Differences</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for the reference list '<em>Differences</em>'.
+ * @see org.eclipse.emf.compare.Equivalence#getDifferences()
+ * @see #getEquivalence()
+ * @generated
+ */
+ EReference getEquivalence_Differences();
+
+ /**
+ * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for enum '<em>Difference Kind</em>'.
+ * @see org.eclipse.emf.compare.DifferenceKind
+ * @generated
+ */
+ EEnum getDifferenceKind();
+
+ /**
+ * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for enum '<em>Difference Source</em>'.
+ * @see org.eclipse.emf.compare.DifferenceSource
+ * @generated
+ */
+ EEnum getDifferenceSource();
+
+ /**
+ * Returns the meta object for enum '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for enum '<em>Difference State</em>'.
+ * @see org.eclipse.emf.compare.DifferenceState
+ * @generated
+ */
+ EEnum getDifferenceState();
+
+ /**
+ * Returns the meta object for enum '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for enum '<em>Conflict Kind</em>'.
+ * @see org.eclipse.emf.compare.ConflictKind
+ * @generated
+ */
+ EEnum getConflictKind();
+
+ /**
+ * Returns the meta object for data type '{@link java.lang.Iterable <em>EIterable</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for data type '<em>EIterable</em>'.
+ * @see java.lang.Iterable
+ * @model instanceClass="java.lang.Iterable" typeParameters="T"
+ * @generated
+ */
+ EDataType getEIterable();
+
+ /**
+ * Returns the meta object for data type '{@link org.eclipse.emf.compare.utils.IEqualityHelper <em>IEquality Helper</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the meta object for data type '<em>IEquality Helper</em>'.
+ * @see org.eclipse.emf.compare.utils.IEqualityHelper
+ * @model instanceClass="org.eclipse.emf.compare.utils.IEqualityHelper" serializeable="false"
+ * @generated
+ */
+ EDataType getIEqualityHelper();
+
+ /**
+ * Returns the factory that creates the instances of the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the factory that creates the instances of the model.
+ * @generated
+ */
+ CompareFactory getCompareFactory();
+
+ /**
+ * <!-- begin-user-doc -->
+ * Defines literals for the meta objects that represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @SuppressWarnings("hiding")
+ // generated code, removing warnings
+ interface Literals {
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ComparisonImpl <em>Comparison</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ComparisonImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getComparison()
+ * @generated
+ */
+ EClass COMPARISON = eINSTANCE.getComparison();
+
+ /**
+ * The meta object literal for the '<em><b>Matched Resources</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference COMPARISON__MATCHED_RESOURCES = eINSTANCE.getComparison_MatchedResources();
+
+ /**
+ * The meta object literal for the '<em><b>Matches</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference COMPARISON__MATCHES = eINSTANCE.getComparison_Matches();
+
+ /**
+ * The meta object literal for the '<em><b>Conflicts</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference COMPARISON__CONFLICTS = eINSTANCE.getComparison_Conflicts();
+
+ /**
+ * The meta object literal for the '<em><b>Equivalences</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference COMPARISON__EQUIVALENCES = eINSTANCE.getComparison_Equivalences();
+
+ /**
+ * The meta object literal for the '<em><b>Three Way</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute COMPARISON__THREE_WAY = eINSTANCE.getComparison_ThreeWay();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.MatchResourceImpl <em>Match Resource</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.MatchResourceImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatchResource()
+ * @generated
+ */
+ EClass MATCH_RESOURCE = eINSTANCE.getMatchResource();
+
+ /**
+ * The meta object literal for the '<em><b>Left URI</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__LEFT_URI = eINSTANCE.getMatchResource_LeftURI();
+
+ /**
+ * The meta object literal for the '<em><b>Right URI</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__RIGHT_URI = eINSTANCE.getMatchResource_RightURI();
+
+ /**
+ * The meta object literal for the '<em><b>Origin URI</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__ORIGIN_URI = eINSTANCE.getMatchResource_OriginURI();
+
+ /**
+ * The meta object literal for the '<em><b>Left</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__LEFT = eINSTANCE.getMatchResource_Left();
+
+ /**
+ * The meta object literal for the '<em><b>Right</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__RIGHT = eINSTANCE.getMatchResource_Right();
+
+ /**
+ * The meta object literal for the '<em><b>Origin</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute MATCH_RESOURCE__ORIGIN = eINSTANCE.getMatchResource_Origin();
+
+ /**
+ * The meta object literal for the '<em><b>Comparison</b></em>' container reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH_RESOURCE__COMPARISON = eINSTANCE.getMatchResource_Comparison();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.MatchImpl <em>Match</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.MatchImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getMatch()
+ * @generated
+ */
+ EClass MATCH = eINSTANCE.getMatch();
+
+ /**
+ * The meta object literal for the '<em><b>Submatches</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH__SUBMATCHES = eINSTANCE.getMatch_Submatches();
+
+ /**
+ * The meta object literal for the '<em><b>Differences</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH__DIFFERENCES = eINSTANCE.getMatch_Differences();
+
+ /**
+ * The meta object literal for the '<em><b>Left</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH__LEFT = eINSTANCE.getMatch_Left();
+
+ /**
+ * The meta object literal for the '<em><b>Right</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH__RIGHT = eINSTANCE.getMatch_Right();
+
+ /**
+ * The meta object literal for the '<em><b>Origin</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference MATCH__ORIGIN = eINSTANCE.getMatch_Origin();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.DiffImpl <em>Diff</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.DiffImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDiff()
+ * @generated
+ */
+ EClass DIFF = eINSTANCE.getDiff();
+
+ /**
+ * The meta object literal for the '<em><b>Match</b></em>' container reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__MATCH = eINSTANCE.getDiff_Match();
+
+ /**
+ * The meta object literal for the '<em><b>Requires</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__REQUIRES = eINSTANCE.getDiff_Requires();
+
+ /**
+ * The meta object literal for the '<em><b>Required By</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__REQUIRED_BY = eINSTANCE.getDiff_RequiredBy();
+
+ /**
+ * The meta object literal for the '<em><b>Refines</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__REFINES = eINSTANCE.getDiff_Refines();
+
+ /**
+ * The meta object literal for the '<em><b>Refined By</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__REFINED_BY = eINSTANCE.getDiff_RefinedBy();
+
+ /**
+ * The meta object literal for the '<em><b>Kind</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute DIFF__KIND = eINSTANCE.getDiff_Kind();
+
+ /**
+ * The meta object literal for the '<em><b>Source</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute DIFF__SOURCE = eINSTANCE.getDiff_Source();
+
+ /**
+ * The meta object literal for the '<em><b>State</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute DIFF__STATE = eINSTANCE.getDiff_State();
+
+ /**
+ * The meta object literal for the '<em><b>Equivalence</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__EQUIVALENCE = eINSTANCE.getDiff_Equivalence();
+
+ /**
+ * The meta object literal for the '<em><b>Conflict</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference DIFF__CONFLICT = eINSTANCE.getDiff_Conflict();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl <em>Resource Attachment Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getResourceAttachmentChange()
+ * @generated
+ */
+ EClass RESOURCE_ATTACHMENT_CHANGE = eINSTANCE.getResourceAttachmentChange();
+
+ /**
+ * The meta object literal for the '<em><b>Resource URI</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI = eINSTANCE
+ .getResourceAttachmentChange_ResourceURI();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ReferenceChangeImpl <em>Reference Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ReferenceChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getReferenceChange()
+ * @generated
+ */
+ EClass REFERENCE_CHANGE = eINSTANCE.getReferenceChange();
+
+ /**
+ * The meta object literal for the '<em><b>Reference</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference REFERENCE_CHANGE__REFERENCE = eINSTANCE.getReferenceChange_Reference();
+
+ /**
+ * The meta object literal for the '<em><b>Value</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference REFERENCE_CHANGE__VALUE = eINSTANCE.getReferenceChange_Value();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.AttributeChangeImpl <em>Attribute Change</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.AttributeChangeImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getAttributeChange()
+ * @generated
+ */
+ EClass ATTRIBUTE_CHANGE = eINSTANCE.getAttributeChange();
+
+ /**
+ * The meta object literal for the '<em><b>Attribute</b></em>' reference feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference ATTRIBUTE_CHANGE__ATTRIBUTE = eINSTANCE.getAttributeChange_Attribute();
+
+ /**
+ * The meta object literal for the '<em><b>Value</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute ATTRIBUTE_CHANGE__VALUE = eINSTANCE.getAttributeChange_Value();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.ConflictImpl <em>Conflict</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.ConflictImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflict()
+ * @generated
+ */
+ EClass CONFLICT = eINSTANCE.getConflict();
+
+ /**
+ * The meta object literal for the '<em><b>Kind</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EAttribute CONFLICT__KIND = eINSTANCE.getConflict_Kind();
+
+ /**
+ * The meta object literal for the '<em><b>Differences</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference CONFLICT__DIFFERENCES = eINSTANCE.getConflict_Differences();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.impl.EquivalenceImpl <em>Equivalence</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.impl.EquivalenceImpl
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEquivalence()
+ * @generated
+ */
+ EClass EQUIVALENCE = eINSTANCE.getEquivalence();
+
+ /**
+ * The meta object literal for the '<em><b>Differences</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ EReference EQUIVALENCE__DIFFERENCES = eINSTANCE.getEquivalence_Differences();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceKind <em>Difference Kind</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceKind
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceKind()
+ * @generated
+ */
+ EEnum DIFFERENCE_KIND = eINSTANCE.getDifferenceKind();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceSource <em>Difference Source</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceSource
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceSource()
+ * @generated
+ */
+ EEnum DIFFERENCE_SOURCE = eINSTANCE.getDifferenceSource();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.DifferenceState <em>Difference State</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.DifferenceState
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getDifferenceState()
+ * @generated
+ */
+ EEnum DIFFERENCE_STATE = eINSTANCE.getDifferenceState();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.emf.compare.ConflictKind <em>Conflict Kind</em>}' enum.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.ConflictKind
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getConflictKind()
+ * @generated
+ */
+ EEnum CONFLICT_KIND = eINSTANCE.getConflictKind();
+
+ /**
+ * The meta object literal for the '<em>EIterable</em>' data type.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see java.lang.Iterable
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getEIterable()
+ * @generated
+ */
+ EDataType EITERABLE = eINSTANCE.getEIterable();
+
+ /**
+ * The meta object literal for the '<em>IEquality Helper</em>' data type.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see org.eclipse.emf.compare.utils.IEqualityHelper
+ * @see org.eclipse.emf.compare.impl.ComparePackageImpl#getIEqualityHelper()
+ * @generated
+ */
+ EDataType IEQUALITY_HELPER = eINSTANCE.getIEqualityHelper();
+
+ }
+
+} //ComparePackage
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Comparison.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Comparison.java
index 37c811e89..526b70d2a 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Comparison.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Comparison.java
@@ -1,170 +1,167 @@
-/**
- * Copyright (c) 2012 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;
-
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.utils.IEqualityHelper;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * <!-- begin-user-doc --> A representation of the model object '<em><b>Comparison</b></em>'. <!--
- * end-user-doc --> <!-- begin-model-doc --> This will act as the "root" of a comparison. It will reference
- * one match for every root of the input models, along with the differences detected for each of them. <!--
- * end-model-doc -->
- * <p>
- * The following features are supported:
- * <ul>
- * <li>{@link org.eclipse.emf.compare.Comparison#getMatchedResources <em>Matched Resources</em>}</li>
- * <li>{@link org.eclipse.emf.compare.Comparison#getMatches <em>Matches</em>}</li>
- * <li>{@link org.eclipse.emf.compare.Comparison#getConflicts <em>Conflicts</em>}</li>
- * <li>{@link org.eclipse.emf.compare.Comparison#getEquivalences <em>Equivalences</em>}</li>
- * <li>{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}</li>
- * </ul>
- * </p>
- *
- * @see org.eclipse.emf.compare.ComparePackage#getComparison()
- * @model
- * @generated
- */
-public interface Comparison extends EObject {
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * Returns the value of the '<em><b>Matched Resources</b></em>' containment reference list. The list
- * contents are of type {@link org.eclipse.emf.compare.MatchResource}. <!-- begin-user-doc --> <!--
- * end-user-doc --> <!-- begin-model-doc --> This contains the mappings for each compared Resource. <!--
- * end-model-doc -->
- *
- * @return the value of the '<em>Matched Resources</em>' containment reference list.
- * @see org.eclipse.emf.compare.ComparePackage#getComparison_MatchedResources()
- * @model containment="true"
- * @generated
- */
- EList<MatchResource> getMatchedResources();
-
- /**
- * Returns the value of the '<em><b>Matches</b></em>' containment reference list. The list contents are of
- * type {@link org.eclipse.emf.compare.Match}. <!-- begin-user-doc --> <!-- end-user-doc --> <!--
- * begin-model-doc --> This contains the match tree "mimicking" the input models' hierarchy. <!--
- * end-model-doc -->
- *
- * @return the value of the '<em>Matches</em>' containment reference list.
- * @see org.eclipse.emf.compare.ComparePackage#getComparison_Matches()
- * @model containment="true"
- * @generated
- */
- EList<Match> getMatches();
-
- /**
- * Returns the value of the '<em><b>Conflicts</b></em>' containment reference list. The list contents are
- * of type {@link org.eclipse.emf.compare.Conflict}. <!-- begin-user-doc --> <!-- end-user-doc --> <!--
- * begin-model-doc --> If we detected any conflict during the comparison process, this will contain them.
- * <!-- end-model-doc -->
- *
- * @return the value of the '<em>Conflicts</em>' containment reference list.
- * @see org.eclipse.emf.compare.ComparePackage#getComparison_Conflicts()
- * @model containment="true"
- * @generated
- */
- EList<Conflict> getConflicts();
-
- /**
- * Returns the value of the '<em><b>Equivalences</b></em>' containment reference list. The list contents
- * are of type {@link org.eclipse.emf.compare.Equivalence}. <!-- begin-user-doc --> <!-- end-user-doc -->
- * <!-- begin-model-doc --> If we detected any equivalence between diffs during the comparison process,
- * this will contain them. <!-- end-model-doc -->
- *
- * @return the value of the '<em>Equivalences</em>' containment reference list.
- * @see org.eclipse.emf.compare.ComparePackage#getComparison_Equivalences()
- * @model containment="true"
- * @generated
- */
- EList<Equivalence> getEquivalences();
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Returns all differences
- * contained by this Comparison and its children. <!-- end-model-doc -->
- *
- * @model kind="operation"
- * @generated
- */
- EList<Diff> getDifferences();
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Returns all differences that
- * reference the given EObject (for instance, all ReferenceChanges that reference the given EObject
- * through the "value" EReference).
- * <p>
- * To get differences detected on the given EObject or one of its counterpart in left, right or origin,
- * you should call the following code:
- *
- * <pre>
- * Match match = getMatch(eObject);
- * if (match != null) {
- * differences = match.getDifferences();
- * }
- * </pre>
- *
- * @param element
- * The EObject for which we seek all related differences. <!-- end-model-doc -->
- * @model
- * @generated
- */
- EList<Diff> getDifferences(EObject element);
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Finds and return the Match for
- * the given EObject.
- *
- * @param element
- * The EObject for which we seek the match. <!-- end-model-doc -->
- * @model
- * @generated
- */
- Match getMatch(EObject element);
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @model kind="operation" dataType="org.eclipse.emf.compare.IEqualityHelper"
- * @generated
- */
- IEqualityHelper getEqualityHelper();
-
- /**
- * Returns the value of the '<em><b>Three Way</b></em>' attribute. <!-- begin-user-doc --> <!--
- * end-user-doc -->
- *
- * @return the value of the '<em>Three Way</em>' attribute.
- * @see #setThreeWay(boolean)
- * @see org.eclipse.emf.compare.ComparePackage#getComparison_ThreeWay()
- * @model
- * @generated
- */
- boolean isThreeWay();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}'
- * attribute. <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @param value
- * the new value of the '<em>Three Way</em>' attribute.
- * @see #isThreeWay()
- * @generated
- */
- void setThreeWay(boolean value);
-
-} // Comparison
+/**
+ * Copyright (c) 2012 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;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.utils.IEqualityHelper;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc --> A representation of the model object '<em><b>Comparison</b></em>'. <!--
+ * end-user-doc --> <!-- begin-model-doc --> This will act as the "root" of a comparison. It will reference
+ * one match for every root of the input models, along with the differences detected for each of them. <!--
+ * end-model-doc -->
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.emf.compare.Comparison#getMatchedResources <em>Matched Resources</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.Comparison#getMatches <em>Matches</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.Comparison#getConflicts <em>Conflicts</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.Comparison#getEquivalences <em>Equivalences</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison()
+ * @model
+ * @generated
+ */
+public interface Comparison extends EObject {
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * Returns the value of the '<em><b>Matched Resources</b></em>' containment reference list. The list
+ * contents are of type {@link org.eclipse.emf.compare.MatchResource}. <!-- begin-user-doc --> <!--
+ * end-user-doc --> <!-- begin-model-doc --> This contains the mappings for each compared Resource. <!--
+ * end-model-doc -->
+ *
+ * @return the value of the '<em>Matched Resources</em>' containment reference list.
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison_MatchedResources()
+ * @model containment="true"
+ * @generated
+ */
+ EList<MatchResource> getMatchedResources();
+
+ /**
+ * Returns the value of the '<em><b>Matches</b></em>' containment reference list. The list contents are of
+ * type {@link org.eclipse.emf.compare.Match}. <!-- begin-user-doc --> <!-- end-user-doc --> <!--
+ * begin-model-doc --> This contains the match tree "mimicking" the input models' hierarchy. <!--
+ * end-model-doc -->
+ *
+ * @return the value of the '<em>Matches</em>' containment reference list.
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison_Matches()
+ * @model containment="true"
+ * @generated
+ */
+ EList<Match> getMatches();
+
+ /**
+ * Returns the value of the '<em><b>Conflicts</b></em>' containment reference list. The list contents are
+ * of type {@link org.eclipse.emf.compare.Conflict}. <!-- begin-user-doc --> <!-- end-user-doc --> <!--
+ * begin-model-doc --> If we detected any conflict during the comparison process, this will contain them.
+ * <!-- end-model-doc -->
+ *
+ * @return the value of the '<em>Conflicts</em>' containment reference list.
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison_Conflicts()
+ * @model containment="true"
+ * @generated
+ */
+ EList<Conflict> getConflicts();
+
+ /**
+ * Returns the value of the '<em><b>Equivalences</b></em>' containment reference list.
+ * The list contents are of type {@link org.eclipse.emf.compare.Equivalence}.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * If we detected any equivalence between diffs during the comparison process, this will contain them.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Equivalences</em>' containment reference list.
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison_Equivalences()
+ * @model containment="true"
+ * @generated
+ */
+ EList<Equivalence> getEquivalences();
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Returns all differences
+ * contained by this Comparison and its children. <!-- end-model-doc -->
+ *
+ * @model kind="operation"
+ * @generated
+ */
+ EList<Diff> getDifferences();
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Returns all differences that
+ * reference the given EObject (for instance, all ReferenceChanges that reference the given EObject
+ * through the "value" EReference).
+ * <p>
+ * To get differences detected on the given EObject or one of its counterpart in left, right or origin,
+ * you should call the following code:
+ *
+ * <pre>
+ * Match match = getMatch(eObject);
+ * if (match != null) {
+ * differences = match.getDifferences();
+ * }
+ * </pre>
+ *
+ * @param element
+ * The EObject for which we seek all related differences. <!-- end-model-doc -->
+ * @model
+ * @generated
+ */
+ EList<Diff> getDifferences(EObject element);
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc --> <!-- begin-model-doc --> Finds and return the Match for
+ * the given EObject.
+ *
+ * @param element
+ * The EObject for which we seek the match. <!-- end-model-doc -->
+ * @model
+ * @generated
+ */
+ Match getMatch(EObject element);
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @model kind="operation" dataType="org.eclipse.emf.compare.IEqualityHelper"
+ * @generated
+ */
+ IEqualityHelper getEqualityHelper();
+
+ /**
+ * Returns the value of the '<em><b>Three Way</b></em>' attribute.
+ * <!-- begin-user-doc --> <!--
+ * end-user-doc -->
+ * @return the value of the '<em>Three Way</em>' attribute.
+ * @see #setThreeWay(boolean)
+ * @see org.eclipse.emf.compare.ComparePackage#getComparison_ThreeWay()
+ * @model
+ * @generated
+ */
+ boolean isThreeWay();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.Comparison#isThreeWay <em>Three Way</em>}' attribute.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @param value the new value of the '<em>Three Way</em>' attribute.
+ * @see #isThreeWay()
+ * @generated
+ */
+ void setThreeWay(boolean value);
+
+} // Comparison
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Diff.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Diff.java
index 25870f8f7..23b9baf5d 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Diff.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/Diff.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -292,7 +292,11 @@ public interface Diff extends EObject {
* <!-- end-model-doc -->
* @model
* @generated
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
void copyRightToLeft();
/**
@@ -303,7 +307,11 @@ public interface Diff extends EObject {
* <!-- end-model-doc -->
* @model
* @generated
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
void copyLeftToRight();
/**
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/MatchResource.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/MatchResource.java
index cfee0875c..44a441494 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/MatchResource.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/MatchResource.java
@@ -1,199 +1,228 @@
-/**
- * Copyright (c) 2012 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;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-
-/**
- * <!-- begin-user-doc -->
- * A representation of the model object '<em><b>Match Resource</b></em>'.
- * <!-- end-user-doc -->
- *
- * <!-- begin-model-doc -->
- * A MatchResource element represents the mapping between two or three resources : left, right, and their optional common ancestor. The resource will be identified through its URI.
- * <!-- end-model-doc -->
- *
- * <p>
- * The following features are supported:
- * <ul>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}</li>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}</li>
- * <li>{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}</li>
- * </ul>
- * </p>
- *
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource()
- * @model
- * @generated
- */
-public interface MatchResource extends EObject {
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * Returns the value of the '<em><b>Left URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * Cannot be null. Represents the URI of the left resource of this mapping.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Left URI</em>' attribute.
- * @see #setLeftURI(String)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_LeftURI()
- * @model required="true"
- * @generated
- */
- String getLeftURI();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Left URI</em>' attribute.
- * @see #getLeftURI()
- * @generated
- */
- void setLeftURI(String value);
-
- /**
- * Returns the value of the '<em><b>Right URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * Cannot be null. Represents the URI of the right resource of this mapping.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Right URI</em>' attribute.
- * @see #setRightURI(String)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_RightURI()
- * @model required="true"
- * @generated
- */
- String getRightURI();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Right URI</em>' attribute.
- * @see #getRightURI()
- * @generated
- */
- void setRightURI(String value);
-
- /**
- * Returns the value of the '<em><b>Origin URI</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * This can be null in the case of two-way comparisons. If assigned, it will represent the URI of the origin resource for this mapping; the common ancestor of both others.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Origin URI</em>' attribute.
- * @see #setOriginURI(String)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_OriginURI()
- * @model
- * @generated
- */
- String getOriginURI();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Origin URI</em>' attribute.
- * @see #getOriginURI()
- * @generated
- */
- void setOriginURI(String value);
-
- /**
- * Returns the value of the '<em><b>Left</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * Keeps a reference towards the left Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the left EResource could not be loaded.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Left</em>' attribute.
- * @see #setLeft(Resource)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Left()
- * @model transient="true"
- * @generated
- */
- Resource getLeft();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Left</em>' attribute.
- * @see #getLeft()
- * @generated
- */
- void setLeft(Resource value);
-
- /**
- * Returns the value of the '<em><b>Right</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * Keeps a reference towards the right Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the right EResource could not be loaded.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Right</em>' attribute.
- * @see #setRight(Resource)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Right()
- * @model transient="true"
- * @generated
- */
- Resource getRight();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Right</em>' attribute.
- * @see #getRight()
- * @generated
- */
- void setRight(Resource value);
-
- /**
- * Returns the value of the '<em><b>Origin</b></em>' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * <!-- begin-model-doc -->
- * Keeps a reference towards the origin Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the origin EResource could not be loaded.
- * <!-- end-model-doc -->
- * @return the value of the '<em>Origin</em>' attribute.
- * @see #setOrigin(Resource)
- * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Origin()
- * @model transient="true"
- * @generated
- */
- Resource getOrigin();
-
- /**
- * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @param value the new value of the '<em>Origin</em>' attribute.
- * @see #getOrigin()
- * @generated
- */
- void setOrigin(Resource value);
-
-} // MatchResource
+/**
+ * Copyright (c) 2012 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;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Match Resource</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <!-- begin-model-doc -->
+ * A MatchResource element represents the mapping between two or three resources : left, right, and their optional common ancestor. The resource will be identified through its URI.
+ * <!-- end-model-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.MatchResource#getComparison <em>Comparison</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource()
+ * @model
+ * @generated
+ */
+public interface MatchResource extends EObject {
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * Returns the value of the '<em><b>Left URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * Cannot be null. Represents the URI of the left resource of this mapping.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Left URI</em>' attribute.
+ * @see #setLeftURI(String)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_LeftURI()
+ * @model required="true"
+ * @generated
+ */
+ String getLeftURI();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getLeftURI <em>Left URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Left URI</em>' attribute.
+ * @see #getLeftURI()
+ * @generated
+ */
+ void setLeftURI(String value);
+
+ /**
+ * Returns the value of the '<em><b>Right URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * Cannot be null. Represents the URI of the right resource of this mapping.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Right URI</em>' attribute.
+ * @see #setRightURI(String)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_RightURI()
+ * @model required="true"
+ * @generated
+ */
+ String getRightURI();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getRightURI <em>Right URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Right URI</em>' attribute.
+ * @see #getRightURI()
+ * @generated
+ */
+ void setRightURI(String value);
+
+ /**
+ * Returns the value of the '<em><b>Origin URI</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * This can be null in the case of two-way comparisons. If assigned, it will represent the URI of the origin resource for this mapping; the common ancestor of both others.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Origin URI</em>' attribute.
+ * @see #setOriginURI(String)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_OriginURI()
+ * @model
+ * @generated
+ */
+ String getOriginURI();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getOriginURI <em>Origin URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Origin URI</em>' attribute.
+ * @see #getOriginURI()
+ * @generated
+ */
+ void setOriginURI(String value);
+
+ /**
+ * Returns the value of the '<em><b>Left</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * Keeps a reference towards the left Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the left EResource could not be loaded.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Left</em>' attribute.
+ * @see #setLeft(Resource)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Left()
+ * @model transient="true"
+ * @generated
+ */
+ Resource getLeft();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getLeft <em>Left</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Left</em>' attribute.
+ * @see #getLeft()
+ * @generated
+ */
+ void setLeft(Resource value);
+
+ /**
+ * Returns the value of the '<em><b>Right</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * Keeps a reference towards the right Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the right EResource could not be loaded.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Right</em>' attribute.
+ * @see #setRight(Resource)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Right()
+ * @model transient="true"
+ * @generated
+ */
+ Resource getRight();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getRight <em>Right</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Right</em>' attribute.
+ * @see #getRight()
+ * @generated
+ */
+ void setRight(Resource value);
+
+ /**
+ * Returns the value of the '<em><b>Origin</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * <!-- begin-model-doc -->
+ * Keeps a reference towards the origin Resource of this Match. Might be null if this is a Comparison we have re-loaded from its serialized form and the origin EResource could not be loaded.
+ * <!-- end-model-doc -->
+ * @return the value of the '<em>Origin</em>' attribute.
+ * @see #setOrigin(Resource)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Origin()
+ * @model transient="true"
+ * @generated
+ */
+ Resource getOrigin();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getOrigin <em>Origin</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Origin</em>' attribute.
+ * @see #getOrigin()
+ * @generated
+ */
+ void setOrigin(Resource value);
+
+ /**
+ * Returns the value of the '<em><b>Comparison</b></em>' container reference.
+ * It is bidirectional and its opposite is '{@link org.eclipse.emf.compare.Comparison#getMatchedResources <em>Matched Resources</em>}'.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Comparison</em>' container reference isn't clear,
+ * there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ * @return the value of the '<em>Comparison</em>' container reference.
+ * @see #setComparison(Comparison)
+ * @see org.eclipse.emf.compare.ComparePackage#getMatchResource_Comparison()
+ * @see org.eclipse.emf.compare.Comparison#getMatchedResources
+ * @model opposite="matchedResources" transient="false"
+ * @generated
+ */
+ Comparison getComparison();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.emf.compare.MatchResource#getComparison <em>Comparison</em>}' container reference.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @param value the new value of the '<em>Comparison</em>' container reference.
+ * @see #getComparison()
+ * @generated
+ */
+ void setComparison(Comparison value);
+
+} // MatchResource
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparePackageImpl.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparePackageImpl.java
index b0fcbd36e..e8715ef14 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparePackageImpl.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparePackageImpl.java
@@ -1,1045 +1,987 @@
-/**
- * Copyright (c) 2012 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.impl;
-
-import org.eclipse.emf.compare.AttributeChange;
-import org.eclipse.emf.compare.CompareFactory;
-import org.eclipse.emf.compare.ComparePackage;
-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.DifferenceState;
-import org.eclipse.emf.compare.Equivalence;
-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.utils.IEqualityHelper;
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EEnum;
-import org.eclipse.emf.ecore.EGenericType;
-import org.eclipse.emf.ecore.EOperation;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.ecore.impl.EPackageImpl;
-
-/**
- * <!-- begin-user-doc --> An implementation of the model <b>Package</b>. <!-- end-user-doc -->
- *
- * @generated
- */
-public class ComparePackageImpl extends EPackageImpl implements ComparePackage {
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass comparisonEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass matchResourceEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass matchEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass diffEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass resourceAttachmentChangeEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass referenceChangeEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass attributeChangeEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass conflictEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EClass equivalenceEClass = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EEnum differenceKindEEnum = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EEnum differenceSourceEEnum = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EEnum differenceStateEEnum = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EEnum conflictKindEEnum = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EDataType eIterableEDataType = null;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private EDataType iEqualityHelperEDataType = null;
-
- /**
- * Creates an instance of the model <b>Package</b>, registered with
- * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package package URI value.
- * <p>
- * Note: the correct way to create the package is via the static factory method {@link #init init()},
- * which also performs initialization of the package, or returns the registered package, if one already
- * exists. <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @see org.eclipse.emf.ecore.EPackage.Registry
- * @see org.eclipse.emf.compare.ComparePackage#eNS_URI
- * @see #init()
- * @generated
- */
- private ComparePackageImpl() {
- super(eNS_URI, CompareFactory.eINSTANCE);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private static boolean isInited = false;
-
- /**
- * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it
- * depends.
- * <p>
- * This method is used to initialize {@link ComparePackage#eINSTANCE} when that field is accessed. Clients
- * should not invoke it directly. Instead, they should simply access that field to obtain the package.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @see #eNS_URI
- * @see #createPackageContents()
- * @see #initializePackageContents()
- * @generated
- */
- public static ComparePackage init() {
- if (isInited) {
- return (ComparePackage)EPackage.Registry.INSTANCE.getEPackage(ComparePackage.eNS_URI);
- }
-
- // Obtain or create and register package
- ComparePackageImpl theComparePackage = (ComparePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof ComparePackageImpl ? EPackage.Registry.INSTANCE
- .get(eNS_URI)
- : new ComparePackageImpl());
-
- isInited = true;
-
- // Initialize simple dependencies
- EcorePackage.eINSTANCE.eClass();
-
- // Create package meta-data objects
- theComparePackage.createPackageContents();
-
- // Initialize created meta-data
- theComparePackage.initializePackageContents();
-
- // Mark meta-data to indicate it can't be changed
- theComparePackage.freeze();
-
- // Update the registry and return the package
- EPackage.Registry.INSTANCE.put(ComparePackage.eNS_URI, theComparePackage);
- return theComparePackage;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getComparison() {
- return comparisonEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getComparison_MatchedResources() {
- return (EReference)comparisonEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getComparison_Matches() {
- return (EReference)comparisonEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getComparison_Conflicts() {
- return (EReference)comparisonEClass.getEStructuralFeatures().get(2);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getComparison_Equivalences() {
- return (EReference)comparisonEClass.getEStructuralFeatures().get(3);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getComparison_ThreeWay() {
- return (EAttribute)comparisonEClass.getEStructuralFeatures().get(4);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getMatchResource() {
- return matchResourceEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_LeftURI() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_RightURI() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_OriginURI() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(2);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_Left() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(3);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_Right() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(4);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getMatchResource_Origin() {
- return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(5);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getMatch() {
- return matchEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getMatch_Submatches() {
- return (EReference)matchEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getMatch_Differences() {
- return (EReference)matchEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getMatch_Left() {
- return (EReference)matchEClass.getEStructuralFeatures().get(2);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getMatch_Right() {
- return (EReference)matchEClass.getEStructuralFeatures().get(3);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getMatch_Origin() {
- return (EReference)matchEClass.getEStructuralFeatures().get(4);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getDiff() {
- return diffEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_Match() {
- return (EReference)diffEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_Requires() {
- return (EReference)diffEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_RequiredBy() {
- return (EReference)diffEClass.getEStructuralFeatures().get(2);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_Refines() {
- return (EReference)diffEClass.getEStructuralFeatures().get(3);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_RefinedBy() {
- return (EReference)diffEClass.getEStructuralFeatures().get(4);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getDiff_Kind() {
- return (EAttribute)diffEClass.getEStructuralFeatures().get(5);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getDiff_Source() {
- return (EAttribute)diffEClass.getEStructuralFeatures().get(6);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getDiff_State() {
- return (EAttribute)diffEClass.getEStructuralFeatures().get(7);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_Equivalence() {
- return (EReference)diffEClass.getEStructuralFeatures().get(8);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getDiff_Conflict() {
- return (EReference)diffEClass.getEStructuralFeatures().get(9);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getResourceAttachmentChange() {
- return resourceAttachmentChangeEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getResourceAttachmentChange_ResourceURI() {
- return (EAttribute)resourceAttachmentChangeEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getReferenceChange() {
- return referenceChangeEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getReferenceChange_Reference() {
- return (EReference)referenceChangeEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getReferenceChange_Value() {
- return (EReference)referenceChangeEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getAttributeChange() {
- return attributeChangeEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getAttributeChange_Attribute() {
- return (EReference)attributeChangeEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getAttributeChange_Value() {
- return (EAttribute)attributeChangeEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getConflict() {
- return conflictEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EAttribute getConflict_Kind() {
- return (EAttribute)conflictEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getConflict_Differences() {
- return (EReference)conflictEClass.getEStructuralFeatures().get(1);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EClass getEquivalence() {
- return equivalenceEClass;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EReference getEquivalence_Differences() {
- return (EReference)equivalenceEClass.getEStructuralFeatures().get(0);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EEnum getDifferenceKind() {
- return differenceKindEEnum;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EEnum getDifferenceSource() {
- return differenceSourceEEnum;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EEnum getDifferenceState() {
- return differenceStateEEnum;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EEnum getConflictKind() {
- return conflictKindEEnum;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EDataType getEIterable() {
- return eIterableEDataType;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EDataType getIEqualityHelper() {
- return iEqualityHelperEDataType;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public CompareFactory getCompareFactory() {
- return (CompareFactory)getEFactoryInstance();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private boolean isCreated = false;
-
- /**
- * Creates the meta-model objects for the package. This method is guarded to have no affect on any
- * invocation but its first. <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public void createPackageContents() {
- if (isCreated) {
- return;
- }
- isCreated = true;
-
- // Create classes and their features
- comparisonEClass = createEClass(COMPARISON);
- createEReference(comparisonEClass, COMPARISON__MATCHED_RESOURCES);
- createEReference(comparisonEClass, COMPARISON__MATCHES);
- createEReference(comparisonEClass, COMPARISON__CONFLICTS);
- createEReference(comparisonEClass, COMPARISON__EQUIVALENCES);
- createEAttribute(comparisonEClass, COMPARISON__THREE_WAY);
-
- matchResourceEClass = createEClass(MATCH_RESOURCE);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__LEFT_URI);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__RIGHT_URI);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__ORIGIN_URI);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__LEFT);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__RIGHT);
- createEAttribute(matchResourceEClass, MATCH_RESOURCE__ORIGIN);
-
- matchEClass = createEClass(MATCH);
- createEReference(matchEClass, MATCH__SUBMATCHES);
- createEReference(matchEClass, MATCH__DIFFERENCES);
- createEReference(matchEClass, MATCH__LEFT);
- createEReference(matchEClass, MATCH__RIGHT);
- createEReference(matchEClass, MATCH__ORIGIN);
-
- diffEClass = createEClass(DIFF);
- createEReference(diffEClass, DIFF__MATCH);
- createEReference(diffEClass, DIFF__REQUIRES);
- createEReference(diffEClass, DIFF__REQUIRED_BY);
- createEReference(diffEClass, DIFF__REFINES);
- createEReference(diffEClass, DIFF__REFINED_BY);
- createEAttribute(diffEClass, DIFF__KIND);
- createEAttribute(diffEClass, DIFF__SOURCE);
- createEAttribute(diffEClass, DIFF__STATE);
- createEReference(diffEClass, DIFF__EQUIVALENCE);
- createEReference(diffEClass, DIFF__CONFLICT);
-
- resourceAttachmentChangeEClass = createEClass(RESOURCE_ATTACHMENT_CHANGE);
- createEAttribute(resourceAttachmentChangeEClass, RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI);
-
- referenceChangeEClass = createEClass(REFERENCE_CHANGE);
- createEReference(referenceChangeEClass, REFERENCE_CHANGE__REFERENCE);
- createEReference(referenceChangeEClass, REFERENCE_CHANGE__VALUE);
-
- attributeChangeEClass = createEClass(ATTRIBUTE_CHANGE);
- createEReference(attributeChangeEClass, ATTRIBUTE_CHANGE__ATTRIBUTE);
- createEAttribute(attributeChangeEClass, ATTRIBUTE_CHANGE__VALUE);
-
- conflictEClass = createEClass(CONFLICT);
- createEAttribute(conflictEClass, CONFLICT__KIND);
- createEReference(conflictEClass, CONFLICT__DIFFERENCES);
-
- equivalenceEClass = createEClass(EQUIVALENCE);
- createEReference(equivalenceEClass, EQUIVALENCE__DIFFERENCES);
-
- // Create enums
- differenceKindEEnum = createEEnum(DIFFERENCE_KIND);
- differenceSourceEEnum = createEEnum(DIFFERENCE_SOURCE);
- differenceStateEEnum = createEEnum(DIFFERENCE_STATE);
- conflictKindEEnum = createEEnum(CONFLICT_KIND);
-
- // Create data types
- eIterableEDataType = createEDataType(EITERABLE);
- iEqualityHelperEDataType = createEDataType(IEQUALITY_HELPER);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- private boolean isInitialized = false;
-
- /**
- * Complete the initialization of the package and its meta-model. This method is guarded to have no affect
- * on any invocation but its first. <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public void initializePackageContents() {
- if (isInitialized) {
- return;
- }
- isInitialized = true;
-
- // Initialize package
- setName(eNAME);
- setNsPrefix(eNS_PREFIX);
- setNsURI(eNS_URI);
-
- // Obtain other dependent packages
- EcorePackage theEcorePackage = (EcorePackage)EPackage.Registry.INSTANCE
- .getEPackage(EcorePackage.eNS_URI);
-
- // Create type parameters
- addETypeParameter(eIterableEDataType, "T"); //$NON-NLS-1$
-
- // Set bounds for type parameters
-
- // Add supertypes to classes
- resourceAttachmentChangeEClass.getESuperTypes().add(this.getDiff());
- referenceChangeEClass.getESuperTypes().add(this.getDiff());
- attributeChangeEClass.getESuperTypes().add(this.getDiff());
-
- // Initialize classes and features; add operations and parameters
- initEClass(comparisonEClass, Comparison.class,
- "Comparison", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getComparison_MatchedResources(),
- this.getMatchResource(),
- null,
- "matchedResources", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getComparison_Matches(),
- this.getMatch(),
- null,
- "matches", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getComparison_Conflicts(),
- this.getConflict(),
- null,
- "conflicts", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getComparison_Equivalences(),
- this.getEquivalence(),
- null,
- "equivalences", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getComparison_ThreeWay(),
- ecorePackage.getEBoolean(),
- "threeWay", null, 0, 1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(comparisonEClass, this.getDiff(), "getDifferences", 0, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- EOperation op = addEOperation(comparisonEClass, this.getDiff(),
- "getDifferences", 0, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
- addEParameter(op, theEcorePackage.getEObject(), "element", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- op = addEOperation(comparisonEClass, this.getMatch(), "getMatch", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
- addEParameter(op, theEcorePackage.getEObject(), "element", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(comparisonEClass, this.getIEqualityHelper(),
- "getEqualityHelper", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(matchResourceEClass, MatchResource.class,
- "MatchResource", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_LeftURI(),
- ecorePackage.getEString(),
- "leftURI", null, 1, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_RightURI(),
- ecorePackage.getEString(),
- "rightURI", null, 1, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_OriginURI(),
- ecorePackage.getEString(),
- "originURI", null, 0, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_Left(),
- theEcorePackage.getEResource(),
- "left", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_Right(),
- theEcorePackage.getEResource(),
- "right", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getMatchResource_Origin(),
- theEcorePackage.getEResource(),
- "origin", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(matchEClass, Match.class,
- "Match", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getMatch_Submatches(),
- this.getMatch(),
- null,
- "submatches", null, 0, -1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getMatch_Differences(),
- this.getDiff(),
- this.getDiff_Match(),
- "differences", null, 0, -1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getMatch_Left(),
- ecorePackage.getEObject(),
- null,
- "left", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getMatch_Right(),
- ecorePackage.getEObject(),
- null,
- "right", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getMatch_Origin(),
- ecorePackage.getEObject(),
- null,
- "origin", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(matchEClass, this.getComparison(), "getComparison", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- op = addEOperation(matchEClass, null, "getAllSubmatches", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
- EGenericType g1 = createEGenericType(this.getEIterable());
- EGenericType g2 = createEGenericType(this.getMatch());
- g1.getETypeArguments().add(g2);
- initEOperation(op, g1);
-
- op = addEOperation(matchEClass, null, "getAllDifferences", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
- g1 = createEGenericType(this.getEIterable());
- g2 = createEGenericType(this.getDiff());
- g1.getETypeArguments().add(g2);
- initEOperation(op, g1);
-
- initEClass(diffEClass, Diff.class, "Diff", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getDiff_Match(),
- this.getMatch(),
- this.getMatch_Differences(),
- "match", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_Requires(),
- this.getDiff(),
- this.getDiff_RequiredBy(),
- "requires", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_RequiredBy(),
- this.getDiff(),
- this.getDiff_Requires(),
- "requiredBy", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_Refines(),
- this.getDiff(),
- this.getDiff_RefinedBy(),
- "refines", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_RefinedBy(),
- this.getDiff(),
- this.getDiff_Refines(),
- "refinedBy", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getDiff_Kind(),
- this.getDifferenceKind(),
- "kind", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getDiff_Source(),
- this.getDifferenceSource(),
- "source", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getDiff_State(),
- this.getDifferenceState(),
- "state", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_Equivalence(),
- this.getEquivalence(),
- this.getEquivalence_Differences(),
- "equivalence", null, 0, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getDiff_Conflict(),
- this.getConflict(),
- this.getConflict_Differences(),
- "conflict", null, 0, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(diffEClass, null, "copyRightToLeft", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(diffEClass, null, "copyLeftToRight", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(diffEClass, null, "discard", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(resourceAttachmentChangeEClass, ResourceAttachmentChange.class,
- "ResourceAttachmentChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEAttribute(
- getResourceAttachmentChange_ResourceURI(),
- ecorePackage.getEString(),
- "resourceURI", null, 1, 1, ResourceAttachmentChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(referenceChangeEClass, ReferenceChange.class,
- "ReferenceChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getReferenceChange_Reference(),
- theEcorePackage.getEReference(),
- null,
- "reference", null, 1, 1, ReferenceChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getReferenceChange_Value(),
- theEcorePackage.getEObject(),
- null,
- "value", null, 0, 1, ReferenceChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(attributeChangeEClass, AttributeChange.class,
- "AttributeChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getAttributeChange_Attribute(),
- theEcorePackage.getEAttribute(),
- null,
- "attribute", null, 1, 1, AttributeChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEAttribute(
- getAttributeChange_Value(),
- theEcorePackage.getEJavaObject(),
- "value", null, 0, 1, AttributeChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(conflictEClass, Conflict.class,
- "Conflict", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEAttribute(
- getConflict_Kind(),
- this.getConflictKind(),
- "kind", null, 1, 1, Conflict.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
- initEReference(
- getConflict_Differences(),
- this.getDiff(),
- this.getDiff_Conflict(),
- "differences", null, 2, -1, Conflict.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(conflictEClass, this.getDiff(), "getLeftDifferences", 1, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- addEOperation(conflictEClass, this.getDiff(), "getRightDifferences", 1, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
-
- initEClass(equivalenceEClass, Equivalence.class,
- "Equivalence", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEReference(
- getEquivalence_Differences(),
- this.getDiff(),
- this.getDiff_Equivalence(),
- "differences", null, 2, -1, Equivalence.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
-
- // Initialize enums and add enum literals
- initEEnum(differenceKindEEnum, DifferenceKind.class, "DifferenceKind"); //$NON-NLS-1$
- addEEnumLiteral(differenceKindEEnum, DifferenceKind.ADD);
- addEEnumLiteral(differenceKindEEnum, DifferenceKind.DELETE);
- addEEnumLiteral(differenceKindEEnum, DifferenceKind.CHANGE);
- addEEnumLiteral(differenceKindEEnum, DifferenceKind.MOVE);
-
- initEEnum(differenceSourceEEnum, DifferenceSource.class, "DifferenceSource"); //$NON-NLS-1$
- addEEnumLiteral(differenceSourceEEnum, DifferenceSource.LEFT);
- addEEnumLiteral(differenceSourceEEnum, DifferenceSource.RIGHT);
-
- initEEnum(differenceStateEEnum, DifferenceState.class, "DifferenceState"); //$NON-NLS-1$
- addEEnumLiteral(differenceStateEEnum, DifferenceState.UNRESOLVED);
- addEEnumLiteral(differenceStateEEnum, DifferenceState.MERGED);
- addEEnumLiteral(differenceStateEEnum, DifferenceState.DISCARDED);
-
- initEEnum(conflictKindEEnum, ConflictKind.class, "ConflictKind"); //$NON-NLS-1$
- addEEnumLiteral(conflictKindEEnum, ConflictKind.REAL);
- addEEnumLiteral(conflictKindEEnum, ConflictKind.PSEUDO);
-
- // Initialize data types
- initEDataType(eIterableEDataType, Iterable.class,
- "EIterable", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
- initEDataType(iEqualityHelperEDataType, IEqualityHelper.class,
- "IEqualityHelper", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
-
- // Create resource
- createResource(eNS_URI);
- }
-
-} // ComparePackageImpl
+/**
+ * Copyright (c) 2012 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.impl;
+
+import java.lang.Iterable;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.ComparePackage;
+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.DifferenceState;
+import org.eclipse.emf.compare.Equivalence;
+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.utils.IEqualityHelper;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EGenericType;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+/**
+ * <!-- begin-user-doc --> An implementation of the model <b>Package</b>. <!-- end-user-doc -->
+ * @generated
+ */
+public class ComparePackageImpl extends EPackageImpl implements ComparePackage {
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass comparisonEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass matchResourceEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass matchEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass diffEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass resourceAttachmentChangeEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass referenceChangeEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass attributeChangeEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass conflictEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EClass equivalenceEClass = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EEnum differenceKindEEnum = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EEnum differenceSourceEEnum = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EEnum differenceStateEEnum = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EEnum conflictKindEEnum = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EDataType eIterableEDataType = null;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private EDataType iEqualityHelperEDataType = null;
+
+ /**
+ * Creates an instance of the model <b>Package</b>, registered with
+ * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package
+ * package URI value.
+ * <p>Note: the correct way to create the package is via the static
+ * factory method {@link #init init()}, which also performs
+ * initialization of the package, or returns the registered package,
+ * if one already exists.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @see org.eclipse.emf.ecore.EPackage.Registry
+ * @see org.eclipse.emf.compare.ComparePackage#eNS_URI
+ * @see #init()
+ * @generated
+ */
+ private ComparePackageImpl() {
+ super(eNS_URI, CompareFactory.eINSTANCE);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private static boolean isInited = false;
+
+ /**
+ * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+ *
+ * <p>This method is used to initialize {@link ComparePackage#eINSTANCE} when that field is accessed.
+ * Clients should not invoke it directly. Instead, they should simply access that field to obtain the package.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @see #eNS_URI
+ * @see #createPackageContents()
+ * @see #initializePackageContents()
+ * @generated
+ */
+ public static ComparePackage init() {
+ if (isInited)
+ return (ComparePackage)EPackage.Registry.INSTANCE.getEPackage(ComparePackage.eNS_URI);
+
+ // Obtain or create and register package
+ ComparePackageImpl theComparePackage = (ComparePackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof ComparePackageImpl ? EPackage.Registry.INSTANCE
+ .get(eNS_URI)
+ : new ComparePackageImpl());
+
+ isInited = true;
+
+ // Initialize simple dependencies
+ EcorePackage.eINSTANCE.eClass();
+
+ // Create package meta-data objects
+ theComparePackage.createPackageContents();
+
+ // Initialize created meta-data
+ theComparePackage.initializePackageContents();
+
+ // Mark meta-data to indicate it can't be changed
+ theComparePackage.freeze();
+
+ // Update the registry and return the package
+ EPackage.Registry.INSTANCE.put(ComparePackage.eNS_URI, theComparePackage);
+ return theComparePackage;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getComparison() {
+ return comparisonEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getComparison_MatchedResources() {
+ return (EReference)comparisonEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getComparison_Matches() {
+ return (EReference)comparisonEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getComparison_Conflicts() {
+ return (EReference)comparisonEClass.getEStructuralFeatures().get(2);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getComparison_Equivalences() {
+ return (EReference)comparisonEClass.getEStructuralFeatures().get(3);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getComparison_ThreeWay() {
+ return (EAttribute)comparisonEClass.getEStructuralFeatures().get(4);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getMatchResource() {
+ return matchResourceEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_LeftURI() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_RightURI() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_OriginURI() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(2);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_Left() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(3);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_Right() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(4);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getMatchResource_Origin() {
+ return (EAttribute)matchResourceEClass.getEStructuralFeatures().get(5);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatchResource_Comparison() {
+ return (EReference)matchResourceEClass.getEStructuralFeatures().get(6);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getMatch() {
+ return matchEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatch_Submatches() {
+ return (EReference)matchEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatch_Differences() {
+ return (EReference)matchEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatch_Left() {
+ return (EReference)matchEClass.getEStructuralFeatures().get(2);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatch_Right() {
+ return (EReference)matchEClass.getEStructuralFeatures().get(3);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getMatch_Origin() {
+ return (EReference)matchEClass.getEStructuralFeatures().get(4);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getDiff() {
+ return diffEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_Match() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_Requires() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_RequiredBy() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(2);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_Refines() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(3);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_RefinedBy() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(4);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getDiff_Kind() {
+ return (EAttribute)diffEClass.getEStructuralFeatures().get(5);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getDiff_Source() {
+ return (EAttribute)diffEClass.getEStructuralFeatures().get(6);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getDiff_State() {
+ return (EAttribute)diffEClass.getEStructuralFeatures().get(7);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_Equivalence() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(8);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getDiff_Conflict() {
+ return (EReference)diffEClass.getEStructuralFeatures().get(9);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getResourceAttachmentChange() {
+ return resourceAttachmentChangeEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getResourceAttachmentChange_ResourceURI() {
+ return (EAttribute)resourceAttachmentChangeEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getReferenceChange() {
+ return referenceChangeEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getReferenceChange_Reference() {
+ return (EReference)referenceChangeEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getReferenceChange_Value() {
+ return (EReference)referenceChangeEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getAttributeChange() {
+ return attributeChangeEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getAttributeChange_Attribute() {
+ return (EReference)attributeChangeEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getAttributeChange_Value() {
+ return (EAttribute)attributeChangeEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getConflict() {
+ return conflictEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EAttribute getConflict_Kind() {
+ return (EAttribute)conflictEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getConflict_Differences() {
+ return (EReference)conflictEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EClass getEquivalence() {
+ return equivalenceEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EReference getEquivalence_Differences() {
+ return (EReference)equivalenceEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EEnum getDifferenceKind() {
+ return differenceKindEEnum;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EEnum getDifferenceSource() {
+ return differenceSourceEEnum;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EEnum getDifferenceState() {
+ return differenceStateEEnum;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EEnum getConflictKind() {
+ return conflictKindEEnum;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EDataType getEIterable() {
+ return eIterableEDataType;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EDataType getIEqualityHelper() {
+ return iEqualityHelperEDataType;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public CompareFactory getCompareFactory() {
+ return (CompareFactory)getEFactoryInstance();
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private boolean isCreated = false;
+
+ /**
+ * Creates the meta-model objects for the package. This method is
+ * guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public void createPackageContents() {
+ if (isCreated)
+ return;
+ isCreated = true;
+
+ // Create classes and their features
+ comparisonEClass = createEClass(COMPARISON);
+ createEReference(comparisonEClass, COMPARISON__MATCHED_RESOURCES);
+ createEReference(comparisonEClass, COMPARISON__MATCHES);
+ createEReference(comparisonEClass, COMPARISON__CONFLICTS);
+ createEReference(comparisonEClass, COMPARISON__EQUIVALENCES);
+ createEAttribute(comparisonEClass, COMPARISON__THREE_WAY);
+
+ matchResourceEClass = createEClass(MATCH_RESOURCE);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__LEFT_URI);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__RIGHT_URI);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__ORIGIN_URI);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__LEFT);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__RIGHT);
+ createEAttribute(matchResourceEClass, MATCH_RESOURCE__ORIGIN);
+ createEReference(matchResourceEClass, MATCH_RESOURCE__COMPARISON);
+
+ matchEClass = createEClass(MATCH);
+ createEReference(matchEClass, MATCH__SUBMATCHES);
+ createEReference(matchEClass, MATCH__DIFFERENCES);
+ createEReference(matchEClass, MATCH__LEFT);
+ createEReference(matchEClass, MATCH__RIGHT);
+ createEReference(matchEClass, MATCH__ORIGIN);
+
+ diffEClass = createEClass(DIFF);
+ createEReference(diffEClass, DIFF__MATCH);
+ createEReference(diffEClass, DIFF__REQUIRES);
+ createEReference(diffEClass, DIFF__REQUIRED_BY);
+ createEReference(diffEClass, DIFF__REFINES);
+ createEReference(diffEClass, DIFF__REFINED_BY);
+ createEAttribute(diffEClass, DIFF__KIND);
+ createEAttribute(diffEClass, DIFF__SOURCE);
+ createEAttribute(diffEClass, DIFF__STATE);
+ createEReference(diffEClass, DIFF__EQUIVALENCE);
+ createEReference(diffEClass, DIFF__CONFLICT);
+
+ resourceAttachmentChangeEClass = createEClass(RESOURCE_ATTACHMENT_CHANGE);
+ createEAttribute(resourceAttachmentChangeEClass, RESOURCE_ATTACHMENT_CHANGE__RESOURCE_URI);
+
+ referenceChangeEClass = createEClass(REFERENCE_CHANGE);
+ createEReference(referenceChangeEClass, REFERENCE_CHANGE__REFERENCE);
+ createEReference(referenceChangeEClass, REFERENCE_CHANGE__VALUE);
+
+ attributeChangeEClass = createEClass(ATTRIBUTE_CHANGE);
+ createEReference(attributeChangeEClass, ATTRIBUTE_CHANGE__ATTRIBUTE);
+ createEAttribute(attributeChangeEClass, ATTRIBUTE_CHANGE__VALUE);
+
+ conflictEClass = createEClass(CONFLICT);
+ createEAttribute(conflictEClass, CONFLICT__KIND);
+ createEReference(conflictEClass, CONFLICT__DIFFERENCES);
+
+ equivalenceEClass = createEClass(EQUIVALENCE);
+ createEReference(equivalenceEClass, EQUIVALENCE__DIFFERENCES);
+
+ // Create enums
+ differenceKindEEnum = createEEnum(DIFFERENCE_KIND);
+ differenceSourceEEnum = createEEnum(DIFFERENCE_SOURCE);
+ differenceStateEEnum = createEEnum(DIFFERENCE_STATE);
+ conflictKindEEnum = createEEnum(CONFLICT_KIND);
+
+ // Create data types
+ eIterableEDataType = createEDataType(EITERABLE);
+ iEqualityHelperEDataType = createEDataType(IEQUALITY_HELPER);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * Complete the initialization of the package and its meta-model. This
+ * method is guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public void initializePackageContents() {
+ if (isInitialized)
+ return;
+ isInitialized = true;
+
+ // Initialize package
+ setName(eNAME);
+ setNsPrefix(eNS_PREFIX);
+ setNsURI(eNS_URI);
+
+ // Obtain other dependent packages
+ EcorePackage theEcorePackage = (EcorePackage)EPackage.Registry.INSTANCE
+ .getEPackage(EcorePackage.eNS_URI);
+
+ // Create type parameters
+ addETypeParameter(eIterableEDataType, "T"); //$NON-NLS-1$
+
+ // Set bounds for type parameters
+
+ // Add supertypes to classes
+ resourceAttachmentChangeEClass.getESuperTypes().add(this.getDiff());
+ referenceChangeEClass.getESuperTypes().add(this.getDiff());
+ attributeChangeEClass.getESuperTypes().add(this.getDiff());
+
+ // Initialize classes and features; add operations and parameters
+ initEClass(comparisonEClass, Comparison.class,
+ "Comparison", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getComparison_MatchedResources(),
+ this.getMatchResource(),
+ this.getMatchResource_Comparison(),
+ "matchedResources", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getComparison_Matches(),
+ this.getMatch(),
+ null,
+ "matches", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getComparison_Conflicts(),
+ this.getConflict(),
+ null,
+ "conflicts", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getComparison_Equivalences(),
+ this.getEquivalence(),
+ null,
+ "equivalences", null, 0, -1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getComparison_ThreeWay(),
+ ecorePackage.getEBoolean(),
+ "threeWay", null, 0, 1, Comparison.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(comparisonEClass, this.getDiff(), "getDifferences", 0, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ EOperation op = addEOperation(comparisonEClass, this.getDiff(),
+ "getDifferences", 0, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+ addEParameter(op, theEcorePackage.getEObject(), "element", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ op = addEOperation(comparisonEClass, this.getMatch(), "getMatch", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+ addEParameter(op, theEcorePackage.getEObject(), "element", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(comparisonEClass, this.getIEqualityHelper(),
+ "getEqualityHelper", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(matchResourceEClass, MatchResource.class,
+ "MatchResource", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_LeftURI(),
+ ecorePackage.getEString(),
+ "leftURI", null, 1, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_RightURI(),
+ ecorePackage.getEString(),
+ "rightURI", null, 1, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_OriginURI(),
+ ecorePackage.getEString(),
+ "originURI", null, 0, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_Left(),
+ theEcorePackage.getEResource(),
+ "left", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_Right(),
+ theEcorePackage.getEResource(),
+ "right", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getMatchResource_Origin(),
+ theEcorePackage.getEResource(),
+ "origin", null, 0, 1, MatchResource.class, IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getMatchResource_Comparison(),
+ this.getComparison(),
+ this.getComparison_MatchedResources(),
+ "comparison", null, 0, 1, MatchResource.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(matchEClass, Match.class,
+ "Match", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getMatch_Submatches(),
+ this.getMatch(),
+ null,
+ "submatches", null, 0, -1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getMatch_Differences(),
+ this.getDiff(),
+ this.getDiff_Match(),
+ "differences", null, 0, -1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getMatch_Left(),
+ ecorePackage.getEObject(),
+ null,
+ "left", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getMatch_Right(),
+ ecorePackage.getEObject(),
+ null,
+ "right", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getMatch_Origin(),
+ ecorePackage.getEObject(),
+ null,
+ "origin", null, 0, 1, Match.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(matchEClass, this.getComparison(), "getComparison", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ op = addEOperation(matchEClass, null, "getAllSubmatches", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+ EGenericType g1 = createEGenericType(this.getEIterable());
+ EGenericType g2 = createEGenericType(this.getMatch());
+ g1.getETypeArguments().add(g2);
+ initEOperation(op, g1);
+
+ op = addEOperation(matchEClass, null, "getAllDifferences", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+ g1 = createEGenericType(this.getEIterable());
+ g2 = createEGenericType(this.getDiff());
+ g1.getETypeArguments().add(g2);
+ initEOperation(op, g1);
+
+ initEClass(diffEClass, Diff.class, "Diff", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getDiff_Match(),
+ this.getMatch(),
+ this.getMatch_Differences(),
+ "match", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_Requires(),
+ this.getDiff(),
+ this.getDiff_RequiredBy(),
+ "requires", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_RequiredBy(),
+ this.getDiff(),
+ this.getDiff_Requires(),
+ "requiredBy", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_Refines(),
+ this.getDiff(),
+ this.getDiff_RefinedBy(),
+ "refines", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_RefinedBy(),
+ this.getDiff(),
+ this.getDiff_Refines(),
+ "refinedBy", null, 0, -1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getDiff_Kind(),
+ this.getDifferenceKind(),
+ "kind", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getDiff_Source(),
+ this.getDifferenceSource(),
+ "source", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getDiff_State(),
+ this.getDifferenceState(),
+ "state", null, 1, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_Equivalence(),
+ this.getEquivalence(),
+ this.getEquivalence_Differences(),
+ "equivalence", null, 0, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getDiff_Conflict(),
+ this.getConflict(),
+ this.getConflict_Differences(),
+ "conflict", null, 0, 1, Diff.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(diffEClass, null, "copyRightToLeft", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(diffEClass, null, "copyLeftToRight", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(diffEClass, null, "discard", 0, 1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(resourceAttachmentChangeEClass, ResourceAttachmentChange.class,
+ "ResourceAttachmentChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEAttribute(
+ getResourceAttachmentChange_ResourceURI(),
+ ecorePackage.getEString(),
+ "resourceURI", null, 1, 1, ResourceAttachmentChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(referenceChangeEClass, ReferenceChange.class,
+ "ReferenceChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getReferenceChange_Reference(),
+ theEcorePackage.getEReference(),
+ null,
+ "reference", null, 1, 1, ReferenceChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getReferenceChange_Value(),
+ theEcorePackage.getEObject(),
+ null,
+ "value", null, 0, 1, ReferenceChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(attributeChangeEClass, AttributeChange.class,
+ "AttributeChange", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getAttributeChange_Attribute(),
+ theEcorePackage.getEAttribute(),
+ null,
+ "attribute", null, 1, 1, AttributeChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEAttribute(
+ getAttributeChange_Value(),
+ theEcorePackage.getEJavaObject(),
+ "value", null, 0, 1, AttributeChange.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(conflictEClass, Conflict.class,
+ "Conflict", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEAttribute(
+ getConflict_Kind(),
+ this.getConflictKind(),
+ "kind", null, 1, 1, Conflict.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(
+ getConflict_Differences(),
+ this.getDiff(),
+ this.getDiff_Conflict(),
+ "differences", null, 2, -1, Conflict.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(conflictEClass, this.getDiff(), "getLeftDifferences", 1, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ addEOperation(conflictEClass, this.getDiff(), "getRightDifferences", 1, -1, IS_UNIQUE, IS_ORDERED); //$NON-NLS-1$
+
+ initEClass(equivalenceEClass, Equivalence.class,
+ "Equivalence", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(
+ getEquivalence_Differences(),
+ this.getDiff(),
+ this.getDiff_Equivalence(),
+ "differences", null, 2, -1, Equivalence.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ // Initialize enums and add enum literals
+ initEEnum(differenceKindEEnum, DifferenceKind.class, "DifferenceKind"); //$NON-NLS-1$
+ addEEnumLiteral(differenceKindEEnum, DifferenceKind.ADD);
+ addEEnumLiteral(differenceKindEEnum, DifferenceKind.DELETE);
+ addEEnumLiteral(differenceKindEEnum, DifferenceKind.CHANGE);
+ addEEnumLiteral(differenceKindEEnum, DifferenceKind.MOVE);
+
+ initEEnum(differenceSourceEEnum, DifferenceSource.class, "DifferenceSource"); //$NON-NLS-1$
+ addEEnumLiteral(differenceSourceEEnum, DifferenceSource.LEFT);
+ addEEnumLiteral(differenceSourceEEnum, DifferenceSource.RIGHT);
+
+ initEEnum(differenceStateEEnum, DifferenceState.class, "DifferenceState"); //$NON-NLS-1$
+ addEEnumLiteral(differenceStateEEnum, DifferenceState.UNRESOLVED);
+ addEEnumLiteral(differenceStateEEnum, DifferenceState.MERGED);
+ addEEnumLiteral(differenceStateEEnum, DifferenceState.DISCARDED);
+
+ initEEnum(conflictKindEEnum, ConflictKind.class, "ConflictKind"); //$NON-NLS-1$
+ addEEnumLiteral(conflictKindEEnum, ConflictKind.REAL);
+ addEEnumLiteral(conflictKindEEnum, ConflictKind.PSEUDO);
+
+ // Initialize data types
+ initEDataType(eIterableEDataType, Iterable.class,
+ "EIterable", IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEDataType(iEqualityHelperEDataType, IEqualityHelper.class,
+ "IEqualityHelper", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+
+ // Create resource
+ createResource(eNS_URI);
+ }
+
+} // ComparePackageImpl
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparisonImpl.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparisonImpl.java
index 327bc816a..c9a8783b9 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparisonImpl.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/ComparisonImpl.java
@@ -1,398 +1,393 @@
-/**
- * Copyright (c) 2012 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.impl;
-
-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.compare.ComparePackage;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Conflict;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.Equivalence;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.MatchResource;
-import org.eclipse.emf.compare.utils.IEqualityHelper;
-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.EObjectContainmentEList;
-import org.eclipse.emf.ecore.util.InternalEList;
-
-/**
- * <!-- begin-user-doc --> An implementation of the model object '<em><b>Comparison</b></em>'. <!--
- * end-user-doc -->
- * <p>
- * The following features are implemented:
- * <ul>
- * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getMatchedResources <em>Matched Resources</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getMatches <em>Matches</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getConflicts <em>Conflicts</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getEquivalences <em>Equivalences</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#isThreeWay <em>Three Way</em>}</li>
- * </ul>
- * </p>
- *
- * @generated
- */
-@SuppressWarnings("boxing")
-public class ComparisonImpl extends MinimalEObjectImpl implements Comparison {
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * The cached value of the '{@link #getMatchedResources() <em>Matched Resources</em>}' containment
- * reference list. <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @see #getMatchedResources()
- * @generated
- * @ordered
- */
- protected EList<MatchResource> matchedResources;
-
- /**
- * The cached value of the '{@link #getMatches() <em>Matches</em>}' containment reference list. <!--
- * begin-user-doc --> <!-- end-user-doc -->
- *
- * @see #getMatches()
- * @generated
- * @ordered
- */
- protected EList<Match> matches;
-
- /**
- * The cached value of the '{@link #getConflicts() <em>Conflicts</em>}' containment reference list. <!--
- * begin-user-doc --> <!-- end-user-doc -->
- *
- * @see #getConflicts()
- * @generated
- * @ordered
- */
- protected EList<Conflict> conflicts;
-
- /**
- * The cached value of the '{@link #getEquivalences() <em>Equivalences</em>}' containment reference list.
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @see #getEquivalences()
- * @generated
- * @ordered
- */
- protected EList<Equivalence> equivalences;
-
- /**
- * The default value of the '{@link #isThreeWay() <em>Three Way</em>}' attribute. <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- *
- * @see #isThreeWay()
- * @generated
- * @ordered
- */
- protected static final boolean THREE_WAY_EDEFAULT = false;
-
- /**
- * The cached value of the '{@link #isThreeWay() <em>Three Way</em>}' attribute. <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- *
- * @see #isThreeWay()
- * @generated
- * @ordered
- */
- protected boolean threeWay = THREE_WAY_EDEFAULT;
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- protected ComparisonImpl() {
- super();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- protected EClass eStaticClass() {
- return ComparePackage.Literals.COMPARISON;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<MatchResource> getMatchedResources() {
- if (matchedResources == null) {
- matchedResources = new EObjectContainmentEList<MatchResource>(MatchResource.class, this,
- ComparePackage.COMPARISON__MATCHED_RESOURCES);
- }
- return matchedResources;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<Match> getMatches() {
- if (matches == null) {
- matches = new EObjectContainmentEList<Match>(Match.class, this,
- ComparePackage.COMPARISON__MATCHES);
- }
- return matches;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<Conflict> getConflicts() {
- if (conflicts == null) {
- conflicts = new EObjectContainmentEList<Conflict>(Conflict.class, this,
- ComparePackage.COMPARISON__CONFLICTS);
- }
- return conflicts;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<Equivalence> getEquivalences() {
- if (equivalences == null) {
- equivalences = new EObjectContainmentEList<Equivalence>(Equivalence.class, this,
- ComparePackage.COMPARISON__EQUIVALENCES);
- }
- return equivalences;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<Diff> getDifferences() {
- // TODO: implement this method
- // Ensure that you remove @generated or mark it @generated NOT
- throw new UnsupportedOperationException();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public EList<Diff> getDifferences(EObject element) {
- // TODO: implement this method
- // Ensure that you remove @generated or mark it @generated NOT
- throw new UnsupportedOperationException();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public Match getMatch(EObject element) {
- // TODO: implement this method
- // Ensure that you remove @generated or mark it @generated NOT
- throw new UnsupportedOperationException();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public IEqualityHelper getEqualityHelper() {
- // TODO: implement this method
- // Ensure that you remove @generated or mark it @generated NOT
- throw new UnsupportedOperationException();
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public boolean isThreeWay() {
- return threeWay;
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- public void setThreeWay(boolean newThreeWay) {
- boolean oldThreeWay = threeWay;
- threeWay = newThreeWay;
- if (eNotificationRequired()) {
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.COMPARISON__THREE_WAY,
- oldThreeWay, threeWay));
- }
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
- switch (featureID) {
- case ComparePackage.COMPARISON__MATCHED_RESOURCES:
- return ((InternalEList<?>)getMatchedResources()).basicRemove(otherEnd, msgs);
- case ComparePackage.COMPARISON__MATCHES:
- return ((InternalEList<?>)getMatches()).basicRemove(otherEnd, msgs);
- case ComparePackage.COMPARISON__CONFLICTS:
- return ((InternalEList<?>)getConflicts()).basicRemove(otherEnd, msgs);
- case ComparePackage.COMPARISON__EQUIVALENCES:
- return ((InternalEList<?>)getEquivalences()).basicRemove(otherEnd, msgs);
- }
- return super.eInverseRemove(otherEnd, featureID, msgs);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- public Object eGet(int featureID, boolean resolve, boolean coreType) {
- switch (featureID) {
- case ComparePackage.COMPARISON__MATCHED_RESOURCES:
- return getMatchedResources();
- case ComparePackage.COMPARISON__MATCHES:
- return getMatches();
- case ComparePackage.COMPARISON__CONFLICTS:
- return getConflicts();
- case ComparePackage.COMPARISON__EQUIVALENCES:
- return getEquivalences();
- case ComparePackage.COMPARISON__THREE_WAY:
- return isThreeWay();
- }
- return super.eGet(featureID, resolve, coreType);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @SuppressWarnings("unchecked")
- @Override
- public void eSet(int featureID, Object newValue) {
- switch (featureID) {
- case ComparePackage.COMPARISON__MATCHED_RESOURCES:
- getMatchedResources().clear();
- getMatchedResources().addAll((Collection<? extends MatchResource>)newValue);
- return;
- case ComparePackage.COMPARISON__MATCHES:
- getMatches().clear();
- getMatches().addAll((Collection<? extends Match>)newValue);
- return;
- case ComparePackage.COMPARISON__CONFLICTS:
- getConflicts().clear();
- getConflicts().addAll((Collection<? extends Conflict>)newValue);
- return;
- case ComparePackage.COMPARISON__EQUIVALENCES:
- getEquivalences().clear();
- getEquivalences().addAll((Collection<? extends Equivalence>)newValue);
- return;
- case ComparePackage.COMPARISON__THREE_WAY:
- setThreeWay((Boolean)newValue);
- return;
- }
- super.eSet(featureID, newValue);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- public void eUnset(int featureID) {
- switch (featureID) {
- case ComparePackage.COMPARISON__MATCHED_RESOURCES:
- getMatchedResources().clear();
- return;
- case ComparePackage.COMPARISON__MATCHES:
- getMatches().clear();
- return;
- case ComparePackage.COMPARISON__CONFLICTS:
- getConflicts().clear();
- return;
- case ComparePackage.COMPARISON__EQUIVALENCES:
- getEquivalences().clear();
- return;
- case ComparePackage.COMPARISON__THREE_WAY:
- setThreeWay(THREE_WAY_EDEFAULT);
- return;
- }
- super.eUnset(featureID);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- public boolean eIsSet(int featureID) {
- switch (featureID) {
- case ComparePackage.COMPARISON__MATCHED_RESOURCES:
- return matchedResources != null && !matchedResources.isEmpty();
- case ComparePackage.COMPARISON__MATCHES:
- return matches != null && !matches.isEmpty();
- case ComparePackage.COMPARISON__CONFLICTS:
- return conflicts != null && !conflicts.isEmpty();
- case ComparePackage.COMPARISON__EQUIVALENCES:
- return equivalences != null && !equivalences.isEmpty();
- case ComparePackage.COMPARISON__THREE_WAY:
- return threeWay != THREE_WAY_EDEFAULT;
- }
- return super.eIsSet(featureID);
- }
-
- /**
- * <!-- begin-user-doc --> <!-- end-user-doc -->
- *
- * @generated
- */
- @Override
- public String toString() {
- if (eIsProxy()) {
- return super.toString();
- }
-
- StringBuffer result = new StringBuffer(super.toString());
- result.append(" (threeWay: "); //$NON-NLS-1$
- result.append(threeWay);
- result.append(')');
- return result.toString();
- }
-
-} // ComparisonImpl
+/**
+ * Copyright (c) 2012 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.impl;
+
+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.compare.ComparePackage;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Equivalence;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.utils.IEqualityHelper;
+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.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * <!-- begin-user-doc --> An implementation of the model object '<em><b>Comparison</b></em>'. <!--
+ * end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getMatchedResources <em>Matched Resources</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getMatches <em>Matches</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getConflicts <em>Conflicts</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#getEquivalences <em>Equivalences</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.ComparisonImpl#isThreeWay <em>Three Way</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+@SuppressWarnings("boxing")
+public class ComparisonImpl extends MinimalEObjectImpl implements Comparison {
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * The cached value of the '{@link #getMatchedResources() <em>Matched Resources</em>}' containment reference list.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @see #getMatchedResources()
+ * @generated
+ * @ordered
+ */
+ protected EList<MatchResource> matchedResources;
+
+ /**
+ * The cached value of the '{@link #getMatches() <em>Matches</em>}' containment reference list. <!--
+ * begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see #getMatches()
+ * @generated
+ * @ordered
+ */
+ protected EList<Match> matches;
+
+ /**
+ * The cached value of the '{@link #getConflicts() <em>Conflicts</em>}' containment reference list. <!--
+ * begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see #getConflicts()
+ * @generated
+ * @ordered
+ */
+ protected EList<Conflict> conflicts;
+
+ /**
+ * The cached value of the '{@link #getEquivalences() <em>Equivalences</em>}' containment reference list.
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @see #getEquivalences()
+ * @generated
+ * @ordered
+ */
+ protected EList<Equivalence> equivalences;
+
+ /**
+ * The default value of the '{@link #isThreeWay() <em>Three Way</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #isThreeWay()
+ * @generated
+ * @ordered
+ */
+ protected static final boolean THREE_WAY_EDEFAULT = false;
+
+ /**
+ * The cached value of the '{@link #isThreeWay() <em>Three Way</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #isThreeWay()
+ * @generated
+ * @ordered
+ */
+ protected boolean threeWay = THREE_WAY_EDEFAULT;
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ protected ComparisonImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return ComparePackage.Literals.COMPARISON;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<MatchResource> getMatchedResources() {
+ if (matchedResources == null) {
+ matchedResources = new EObjectContainmentWithInverseEList<MatchResource>(MatchResource.class,
+ this, ComparePackage.COMPARISON__MATCHED_RESOURCES,
+ ComparePackage.MATCH_RESOURCE__COMPARISON);
+ }
+ return matchedResources;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<Match> getMatches() {
+ if (matches == null) {
+ matches = new EObjectContainmentEList<Match>(Match.class, this,
+ ComparePackage.COMPARISON__MATCHES);
+ }
+ return matches;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<Conflict> getConflicts() {
+ if (conflicts == null) {
+ conflicts = new EObjectContainmentEList<Conflict>(Conflict.class, this,
+ ComparePackage.COMPARISON__CONFLICTS);
+ }
+ return conflicts;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<Equivalence> getEquivalences() {
+ if (equivalences == null) {
+ equivalences = new EObjectContainmentEList<Equivalence>(Equivalence.class, this,
+ ComparePackage.COMPARISON__EQUIVALENCES);
+ }
+ return equivalences;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<Diff> getDifferences() {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public EList<Diff> getDifferences(EObject element) {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public Match getMatch(EObject element) {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public IEqualityHelper getEqualityHelper() {
+ // TODO: implement this method
+ // Ensure that you remove @generated or mark it @generated NOT
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ return ((InternalEList<InternalEObject>)(InternalEList<?>)getMatchedResources()).basicAdd(
+ otherEnd, msgs);
+ }
+ return super.eInverseAdd(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public boolean isThreeWay() {
+ return threeWay;
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ public void setThreeWay(boolean newThreeWay) {
+ boolean oldThreeWay = threeWay;
+ threeWay = newThreeWay;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.COMPARISON__THREE_WAY,
+ oldThreeWay, threeWay));
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ return ((InternalEList<?>)getMatchedResources()).basicRemove(otherEnd, msgs);
+ case ComparePackage.COMPARISON__MATCHES:
+ return ((InternalEList<?>)getMatches()).basicRemove(otherEnd, msgs);
+ case ComparePackage.COMPARISON__CONFLICTS:
+ return ((InternalEList<?>)getConflicts()).basicRemove(otherEnd, msgs);
+ case ComparePackage.COMPARISON__EQUIVALENCES:
+ return ((InternalEList<?>)getEquivalences()).basicRemove(otherEnd, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ return getMatchedResources();
+ case ComparePackage.COMPARISON__MATCHES:
+ return getMatches();
+ case ComparePackage.COMPARISON__CONFLICTS:
+ return getConflicts();
+ case ComparePackage.COMPARISON__EQUIVALENCES:
+ return getEquivalences();
+ case ComparePackage.COMPARISON__THREE_WAY:
+ return isThreeWay();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ getMatchedResources().clear();
+ getMatchedResources().addAll((Collection<? extends MatchResource>)newValue);
+ return;
+ case ComparePackage.COMPARISON__MATCHES:
+ getMatches().clear();
+ getMatches().addAll((Collection<? extends Match>)newValue);
+ return;
+ case ComparePackage.COMPARISON__CONFLICTS:
+ getConflicts().clear();
+ getConflicts().addAll((Collection<? extends Conflict>)newValue);
+ return;
+ case ComparePackage.COMPARISON__EQUIVALENCES:
+ getEquivalences().clear();
+ getEquivalences().addAll((Collection<? extends Equivalence>)newValue);
+ return;
+ case ComparePackage.COMPARISON__THREE_WAY:
+ setThreeWay((Boolean)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ getMatchedResources().clear();
+ return;
+ case ComparePackage.COMPARISON__MATCHES:
+ getMatches().clear();
+ return;
+ case ComparePackage.COMPARISON__CONFLICTS:
+ getConflicts().clear();
+ return;
+ case ComparePackage.COMPARISON__EQUIVALENCES:
+ getEquivalences().clear();
+ return;
+ case ComparePackage.COMPARISON__THREE_WAY:
+ setThreeWay(THREE_WAY_EDEFAULT);
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case ComparePackage.COMPARISON__MATCHED_RESOURCES:
+ return matchedResources != null && !matchedResources.isEmpty();
+ case ComparePackage.COMPARISON__MATCHES:
+ return matches != null && !matches.isEmpty();
+ case ComparePackage.COMPARISON__CONFLICTS:
+ return conflicts != null && !conflicts.isEmpty();
+ case ComparePackage.COMPARISON__EQUIVALENCES:
+ return equivalences != null && !equivalences.isEmpty();
+ case ComparePackage.COMPARISON__THREE_WAY:
+ return threeWay != THREE_WAY_EDEFAULT;
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc --> <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if (eIsProxy())
+ return super.toString();
+
+ StringBuffer result = new StringBuffer(super.toString());
+ result.append(" (threeWay: "); //$NON-NLS-1$
+ result.append(threeWay);
+ result.append(')');
+ return result.toString();
+ }
+
+} // ComparisonImpl
diff --git a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/MatchResourceImpl.java b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/MatchResourceImpl.java
index a84d24964..1e31cb775 100644
--- a/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/MatchResourceImpl.java
+++ b/plugins/org.eclipse.emf.compare/src-gen/org/eclipse/emf/compare/impl/MatchResourceImpl.java
@@ -1,457 +1,565 @@
-/**
- * Copyright (c) 2012 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.impl;
-
-import org.eclipse.emf.common.notify.Notification;
-
-import org.eclipse.emf.compare.ComparePackage;
-import org.eclipse.emf.compare.MatchResource;
-
-import org.eclipse.emf.ecore.EClass;
-
-import org.eclipse.emf.ecore.impl.ENotificationImpl;
-import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
-import org.eclipse.emf.ecore.resource.Resource;
-
-/**
- * <!-- begin-user-doc -->
- * An implementation of the model object '<em><b>Match Resource</b></em>'.
- * <!-- end-user-doc -->
- * <p>
- * The following features are implemented:
- * <ul>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getLeftURI <em>Left URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getRightURI <em>Right URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getOriginURI <em>Origin URI</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getLeft <em>Left</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getRight <em>Right</em>}</li>
- * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getOrigin <em>Origin</em>}</li>
- * </ul>
- * </p>
- *
- * @generated
- */
-public class MatchResourceImpl extends MinimalEObjectImpl implements MatchResource {
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
-
- /**
- * The default value of the '{@link #getLeftURI() <em>Left URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getLeftURI()
- * @generated
- * @ordered
- */
- protected static final String LEFT_URI_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getLeftURI() <em>Left URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getLeftURI()
- * @generated
- * @ordered
- */
- protected String leftURI = LEFT_URI_EDEFAULT;
-
- /**
- * The default value of the '{@link #getRightURI() <em>Right URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getRightURI()
- * @generated
- * @ordered
- */
- protected static final String RIGHT_URI_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getRightURI() <em>Right URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getRightURI()
- * @generated
- * @ordered
- */
- protected String rightURI = RIGHT_URI_EDEFAULT;
-
- /**
- * The default value of the '{@link #getOriginURI() <em>Origin URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getOriginURI()
- * @generated
- * @ordered
- */
- protected static final String ORIGIN_URI_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getOriginURI() <em>Origin URI</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getOriginURI()
- * @generated
- * @ordered
- */
- protected String originURI = ORIGIN_URI_EDEFAULT;
-
- /**
- * The default value of the '{@link #getLeft() <em>Left</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getLeft()
- * @generated
- * @ordered
- */
- protected static final Resource LEFT_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getLeft() <em>Left</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getLeft()
- * @generated
- * @ordered
- */
- protected Resource left = LEFT_EDEFAULT;
-
- /**
- * The default value of the '{@link #getRight() <em>Right</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getRight()
- * @generated
- * @ordered
- */
- protected static final Resource RIGHT_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getRight() <em>Right</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getRight()
- * @generated
- * @ordered
- */
- protected Resource right = RIGHT_EDEFAULT;
-
- /**
- * The default value of the '{@link #getOrigin() <em>Origin</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getOrigin()
- * @generated
- * @ordered
- */
- protected static final Resource ORIGIN_EDEFAULT = null;
-
- /**
- * The cached value of the '{@link #getOrigin() <em>Origin</em>}' attribute.
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @see #getOrigin()
- * @generated
- * @ordered
- */
- protected Resource origin = ORIGIN_EDEFAULT;
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- protected MatchResourceImpl() {
- super();
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- protected EClass eStaticClass() {
- return ComparePackage.Literals.MATCH_RESOURCE;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public String getLeftURI() {
- return leftURI;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setLeftURI(String newLeftURI) {
- String oldLeftURI = leftURI;
- leftURI = newLeftURI;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__LEFT_URI,
- oldLeftURI, leftURI));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public String getRightURI() {
- return rightURI;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setRightURI(String newRightURI) {
- String oldRightURI = rightURI;
- rightURI = newRightURI;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__RIGHT_URI,
- oldRightURI, rightURI));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public String getOriginURI() {
- return originURI;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setOriginURI(String newOriginURI) {
- String oldOriginURI = originURI;
- originURI = newOriginURI;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__ORIGIN_URI,
- oldOriginURI, originURI));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public Resource getLeft() {
- return left;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setLeft(Resource newLeft) {
- Resource oldLeft = left;
- left = newLeft;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__LEFT,
- oldLeft, left));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public Resource getRight() {
- return right;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setRight(Resource newRight) {
- Resource oldRight = right;
- right = newRight;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__RIGHT,
- oldRight, right));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public Resource getOrigin() {
- return origin;
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- public void setOrigin(Resource newOrigin) {
- Resource oldOrigin = origin;
- origin = newOrigin;
- if (eNotificationRequired())
- eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__ORIGIN,
- oldOrigin, origin));
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- public Object eGet(int featureID, boolean resolve, boolean coreType) {
- switch (featureID) {
- case ComparePackage.MATCH_RESOURCE__LEFT_URI:
- return getLeftURI();
- case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
- return getRightURI();
- case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
- return getOriginURI();
- case ComparePackage.MATCH_RESOURCE__LEFT:
- return getLeft();
- case ComparePackage.MATCH_RESOURCE__RIGHT:
- return getRight();
- case ComparePackage.MATCH_RESOURCE__ORIGIN:
- return getOrigin();
- }
- return super.eGet(featureID, resolve, coreType);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- public void eSet(int featureID, Object newValue) {
- switch (featureID) {
- case ComparePackage.MATCH_RESOURCE__LEFT_URI:
- setLeftURI((String)newValue);
- return;
- case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
- setRightURI((String)newValue);
- return;
- case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
- setOriginURI((String)newValue);
- return;
- case ComparePackage.MATCH_RESOURCE__LEFT:
- setLeft((Resource)newValue);
- return;
- case ComparePackage.MATCH_RESOURCE__RIGHT:
- setRight((Resource)newValue);
- return;
- case ComparePackage.MATCH_RESOURCE__ORIGIN:
- setOrigin((Resource)newValue);
- return;
- }
- super.eSet(featureID, newValue);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- public void eUnset(int featureID) {
- switch (featureID) {
- case ComparePackage.MATCH_RESOURCE__LEFT_URI:
- setLeftURI(LEFT_URI_EDEFAULT);
- return;
- case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
- setRightURI(RIGHT_URI_EDEFAULT);
- return;
- case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
- setOriginURI(ORIGIN_URI_EDEFAULT);
- return;
- case ComparePackage.MATCH_RESOURCE__LEFT:
- setLeft(LEFT_EDEFAULT);
- return;
- case ComparePackage.MATCH_RESOURCE__RIGHT:
- setRight(RIGHT_EDEFAULT);
- return;
- case ComparePackage.MATCH_RESOURCE__ORIGIN:
- setOrigin(ORIGIN_EDEFAULT);
- return;
- }
- super.eUnset(featureID);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- public boolean eIsSet(int featureID) {
- switch (featureID) {
- case ComparePackage.MATCH_RESOURCE__LEFT_URI:
- return LEFT_URI_EDEFAULT == null ? leftURI != null : !LEFT_URI_EDEFAULT.equals(leftURI);
- case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
- return RIGHT_URI_EDEFAULT == null ? rightURI != null : !RIGHT_URI_EDEFAULT.equals(rightURI);
- case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
- return ORIGIN_URI_EDEFAULT == null ? originURI != null : !ORIGIN_URI_EDEFAULT
- .equals(originURI);
- case ComparePackage.MATCH_RESOURCE__LEFT:
- return LEFT_EDEFAULT == null ? left != null : !LEFT_EDEFAULT.equals(left);
- case ComparePackage.MATCH_RESOURCE__RIGHT:
- return RIGHT_EDEFAULT == null ? right != null : !RIGHT_EDEFAULT.equals(right);
- case ComparePackage.MATCH_RESOURCE__ORIGIN:
- return ORIGIN_EDEFAULT == null ? origin != null : !ORIGIN_EDEFAULT.equals(origin);
- }
- return super.eIsSet(featureID);
- }
-
- /**
- * <!-- begin-user-doc -->
- * <!-- end-user-doc -->
- * @generated
- */
- @Override
- public String toString() {
- if (eIsProxy())
- return super.toString();
-
- StringBuffer result = new StringBuffer(super.toString());
- result.append(" (leftURI: "); //$NON-NLS-1$
- result.append(leftURI);
- result.append(", rightURI: "); //$NON-NLS-1$
- result.append(rightURI);
- result.append(", originURI: "); //$NON-NLS-1$
- result.append(originURI);
- result.append(", left: "); //$NON-NLS-1$
- result.append(left);
- result.append(", right: "); //$NON-NLS-1$
- result.append(right);
- result.append(", origin: "); //$NON-NLS-1$
- result.append(origin);
- result.append(')');
- return result.toString();
- }
-
-} //MatchResourceImpl
+/**
+ * Copyright (c) 2012 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.impl;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.compare.ComparePackage;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.MatchResource;
+
+import org.eclipse.emf.ecore.EClass;
+
+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.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Match Resource</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getLeftURI <em>Left URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getRightURI <em>Right URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getOriginURI <em>Origin URI</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getLeft <em>Left</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getRight <em>Right</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getOrigin <em>Origin</em>}</li>
+ * <li>{@link org.eclipse.emf.compare.impl.MatchResourceImpl#getComparison <em>Comparison</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+//Supressing warnings : generated code
+@SuppressWarnings("all")
+public class MatchResourceImpl extends MinimalEObjectImpl implements MatchResource {
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String copyright = "Copyright (c) 2012 Obeo.\r\nAll rights reserved. This program and the accompanying materials\r\nare made available under the terms of the Eclipse Public License v1.0\r\nwhich accompanies this distribution, and is available at\r\nhttp://www.eclipse.org/legal/epl-v10.html\r\n\r\nContributors:\r\n Obeo - initial API and implementation"; //$NON-NLS-1$
+
+ /**
+ * The default value of the '{@link #getLeftURI() <em>Left URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLeftURI()
+ * @generated
+ * @ordered
+ */
+ protected static final String LEFT_URI_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getLeftURI() <em>Left URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLeftURI()
+ * @generated
+ * @ordered
+ */
+ protected String leftURI = LEFT_URI_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getRightURI() <em>Right URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getRightURI()
+ * @generated
+ * @ordered
+ */
+ protected static final String RIGHT_URI_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getRightURI() <em>Right URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getRightURI()
+ * @generated
+ * @ordered
+ */
+ protected String rightURI = RIGHT_URI_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getOriginURI() <em>Origin URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getOriginURI()
+ * @generated
+ * @ordered
+ */
+ protected static final String ORIGIN_URI_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getOriginURI() <em>Origin URI</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getOriginURI()
+ * @generated
+ * @ordered
+ */
+ protected String originURI = ORIGIN_URI_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getLeft() <em>Left</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLeft()
+ * @generated
+ * @ordered
+ */
+ protected static final Resource LEFT_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getLeft() <em>Left</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getLeft()
+ * @generated
+ * @ordered
+ */
+ protected Resource left = LEFT_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getRight() <em>Right</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getRight()
+ * @generated
+ * @ordered
+ */
+ protected static final Resource RIGHT_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getRight() <em>Right</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getRight()
+ * @generated
+ * @ordered
+ */
+ protected Resource right = RIGHT_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #getOrigin() <em>Origin</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getOrigin()
+ * @generated
+ * @ordered
+ */
+ protected static final Resource ORIGIN_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getOrigin() <em>Origin</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @see #getOrigin()
+ * @generated
+ * @ordered
+ */
+ protected Resource origin = ORIGIN_EDEFAULT;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected MatchResourceImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return ComparePackage.Literals.MATCH_RESOURCE;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getLeftURI() {
+ return leftURI;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setLeftURI(String newLeftURI) {
+ String oldLeftURI = leftURI;
+ leftURI = newLeftURI;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__LEFT_URI,
+ oldLeftURI, leftURI));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getRightURI() {
+ return rightURI;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setRightURI(String newRightURI) {
+ String oldRightURI = rightURI;
+ rightURI = newRightURI;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__RIGHT_URI,
+ oldRightURI, rightURI));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getOriginURI() {
+ return originURI;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setOriginURI(String newOriginURI) {
+ String oldOriginURI = originURI;
+ originURI = newOriginURI;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__ORIGIN_URI,
+ oldOriginURI, originURI));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Resource getLeft() {
+ return left;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setLeft(Resource newLeft) {
+ Resource oldLeft = left;
+ left = newLeft;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__LEFT,
+ oldLeft, left));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Resource getRight() {
+ return right;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setRight(Resource newRight) {
+ Resource oldRight = right;
+ right = newRight;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__RIGHT,
+ oldRight, right));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Resource getOrigin() {
+ return origin;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setOrigin(Resource newOrigin) {
+ Resource oldOrigin = origin;
+ origin = newOrigin;
+ if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__ORIGIN,
+ oldOrigin, origin));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Comparison getComparison() {
+ if (eContainerFeatureID() != ComparePackage.MATCH_RESOURCE__COMPARISON)
+ return null;
+ return (Comparison)eContainer();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public NotificationChain basicSetComparison(Comparison newComparison, NotificationChain msgs) {
+ msgs = eBasicSetContainer((InternalEObject)newComparison, ComparePackage.MATCH_RESOURCE__COMPARISON,
+ msgs);
+ return msgs;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setComparison(Comparison newComparison) {
+ if (newComparison != eInternalContainer()
+ || (eContainerFeatureID() != ComparePackage.MATCH_RESOURCE__COMPARISON && newComparison != null)) {
+ if (EcoreUtil.isAncestor(this, newComparison))
+ throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); //$NON-NLS-1$
+ NotificationChain msgs = null;
+ if (eInternalContainer() != null)
+ msgs = eBasicRemoveFromContainer(msgs);
+ if (newComparison != null)
+ msgs = ((InternalEObject)newComparison).eInverseAdd(this,
+ ComparePackage.COMPARISON__MATCHED_RESOURCES, Comparison.class, msgs);
+ msgs = basicSetComparison(newComparison, msgs);
+ if (msgs != null)
+ msgs.dispatch();
+ } else if (eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, ComparePackage.MATCH_RESOURCE__COMPARISON,
+ newComparison, newComparison));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ if (eInternalContainer() != null)
+ msgs = eBasicRemoveFromContainer(msgs);
+ return basicSetComparison((Comparison)otherEnd, msgs);
+ }
+ return super.eInverseAdd(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ return basicSetComparison(null, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
+ switch (eContainerFeatureID()) {
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ return eInternalContainer().eInverseRemove(this,
+ ComparePackage.COMPARISON__MATCHED_RESOURCES, Comparison.class, msgs);
+ }
+ return super.eBasicRemoveFromContainerFeature(msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__LEFT_URI:
+ return getLeftURI();
+ case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
+ return getRightURI();
+ case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
+ return getOriginURI();
+ case ComparePackage.MATCH_RESOURCE__LEFT:
+ return getLeft();
+ case ComparePackage.MATCH_RESOURCE__RIGHT:
+ return getRight();
+ case ComparePackage.MATCH_RESOURCE__ORIGIN:
+ return getOrigin();
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ return getComparison();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__LEFT_URI:
+ setLeftURI((String)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
+ setRightURI((String)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
+ setOriginURI((String)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__LEFT:
+ setLeft((Resource)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__RIGHT:
+ setRight((Resource)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__ORIGIN:
+ setOrigin((Resource)newValue);
+ return;
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ setComparison((Comparison)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__LEFT_URI:
+ setLeftURI(LEFT_URI_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
+ setRightURI(RIGHT_URI_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
+ setOriginURI(ORIGIN_URI_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__LEFT:
+ setLeft(LEFT_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__RIGHT:
+ setRight(RIGHT_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__ORIGIN:
+ setOrigin(ORIGIN_EDEFAULT);
+ return;
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ setComparison((Comparison)null);
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch (featureID) {
+ case ComparePackage.MATCH_RESOURCE__LEFT_URI:
+ return LEFT_URI_EDEFAULT == null ? leftURI != null : !LEFT_URI_EDEFAULT.equals(leftURI);
+ case ComparePackage.MATCH_RESOURCE__RIGHT_URI:
+ return RIGHT_URI_EDEFAULT == null ? rightURI != null : !RIGHT_URI_EDEFAULT.equals(rightURI);
+ case ComparePackage.MATCH_RESOURCE__ORIGIN_URI:
+ return ORIGIN_URI_EDEFAULT == null ? originURI != null : !ORIGIN_URI_EDEFAULT
+ .equals(originURI);
+ case ComparePackage.MATCH_RESOURCE__LEFT:
+ return LEFT_EDEFAULT == null ? left != null : !LEFT_EDEFAULT.equals(left);
+ case ComparePackage.MATCH_RESOURCE__RIGHT:
+ return RIGHT_EDEFAULT == null ? right != null : !RIGHT_EDEFAULT.equals(right);
+ case ComparePackage.MATCH_RESOURCE__ORIGIN:
+ return ORIGIN_EDEFAULT == null ? origin != null : !ORIGIN_EDEFAULT.equals(origin);
+ case ComparePackage.MATCH_RESOURCE__COMPARISON:
+ return getComparison() != null;
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if (eIsProxy())
+ return super.toString();
+
+ StringBuffer result = new StringBuffer(super.toString());
+ result.append(" (leftURI: "); //$NON-NLS-1$
+ result.append(leftURI);
+ result.append(", rightURI: "); //$NON-NLS-1$
+ result.append(rightURI);
+ result.append(", originURI: "); //$NON-NLS-1$
+ result.append(originURI);
+ result.append(", left: "); //$NON-NLS-1$
+ result.append(left);
+ result.append(", right: "); //$NON-NLS-1$
+ result.append(right);
+ result.append(", origin: "); //$NON-NLS-1$
+ result.append(origin);
+ result.append(')');
+ return result.toString();
+ }
+
+} //MatchResourceImpl
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/emfcomparemessages.properties b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/emfcomparemessages.properties
index ebbe76290..cd1784e52 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/emfcomparemessages.properties
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/emfcomparemessages.properties
@@ -21,4 +21,6 @@ DiffUtil.IllegalDiff=Cannot determine an insertion index for {0} differences.
DiffUtil.IllegalFeature=Feature {0} is not multi-valued.
ResourceAttachmentChangeSpec.MissingMatch = Could not locate resource match for {0}
-ResourceAttachmentChangeSpec.MissingRS = Could not locate resource set to create {0} \ No newline at end of file
+ResourceAttachmentChangeSpec.MissingRS = Could not locate resource set to create {0}
+
+IMerger.MissingMerger = No merger found for diff {0} \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/MatchCrossReferencer.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/MatchCrossReferencer.java
index 1f2e7f99c..75a023da4 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/MatchCrossReferencer.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/MatchCrossReferencer.java
@@ -10,10 +10,10 @@
*******************************************************************************/
package org.eclipse.emf.compare.internal;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Collection;
+import java.util.Collections;
import java.util.Set;
import org.eclipse.emf.common.notify.Notifier;
@@ -55,15 +55,12 @@ public class MatchCrossReferencer extends ECrossReferenceAdapter {
*/
@Override
public Collection<Setting> getInverseReferences(EObject eObject, boolean resolve) {
- Collection<EStructuralFeature.Setting> result = Lists.newArrayList();
-
Collection<EStructuralFeature.Setting> nonNavigableInverseReferences = inverseCrossReferencer
.get(eObject);
- if (nonNavigableInverseReferences != null) {
- result.addAll(nonNavigableInverseReferences);
+ if (nonNavigableInverseReferences == null) {
+ return Collections.emptyList();
}
-
- return result;
+ return Collections.unmodifiableCollection(nonNavigableInverseReferences);
}
/**
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/ModelIdentifier.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/ModelIdentifier.java
deleted file mode 100644
index c757cf1e0..000000000
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/ModelIdentifier.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * Copyright (c) 2009, 2012 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.internal;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-
-// TODO subclass this in the compare.ide plugin to add the notion of content types identifier
-/**
- * This will be used in order to store the common identifiers of two or three Resources.
- * <p>
- * Namely, we consider "identifiers" the extension and namespace of these resources.<b>Note</b> that we expect
- * only one of {@link #extension} or {@link #namespace} to be set, in the order of importance : namespace is
- * usually better suited than the file extension to identify a model.
- * </p>
- *
- * @author <a href="mailto:gonzague.reydet@obeo.fr">Gonzague Reydet</a>
- * @since 1.1
- */
-public class ModelIdentifier {
- /** Default extension we'll use if the resources have none. */
- private static final String DEFAULT_EXTENSION = "ecore"; //$NON-NLS-1$
-
- /**
- * If this wildcard is passed over to {@link #matchExtension(String[])}, we will return {@code true}
- * whatever the actual extension this identified is for.
- */
- private static final String EXTENSIONS_WILDCARD = "*"; //$NON-NLS-1$
-
- /** Common namespace of the models. */
- private final String namespace;
-
- /** Common extension of the model. */
- private final String extension;
-
- /**
- * Default constructor.
- *
- * @param resources
- * Resources for which we need to identify an engine.
- */
- public ModelIdentifier(Resource... resources) {
- final List<URI> uris = new ArrayList<URI>();
- for (int i = 0; i < resources.length; i++) {
- if (resources[i] != null) {
- uris.add(resources[i].getURI());
- }
- }
- final URI[] uriArray = uris.toArray(new URI[uris.size()]);
-
- namespace = getCommonNamespace(resources);
-
- final String ext = getCommonExtension(uriArray);
- if (ext != null) {
- this.extension = ext;
- } else if (namespace == null) {
- this.extension = DEFAULT_EXTENSION;
- } else {
- this.extension = null;
- }
- }
-
- /**
- * This can be used to check whether this identifier matches the given extension.
- * <p>
- * A list of extensions can be passed over as a comma-separated list.
- * </p>
- *
- * @param extensions
- * Extension(s) for which we seek a model identifier. If {@code null}, this will return
- * {@code false}.
- * @return {@code true} if this {@link ModelIdentifier} matches the (or one of the) given extension.
- */
- public boolean matchExtension(String extensions) {
- if (extension == null || extensions == null) {
- return false;
- }
-
- boolean match = false;
- final String[] extensionsArray = extensions.split(","); //$NON-NLS-1$
- for (int i = 0; i < extensionsArray.length && !match; i++) {
- final String candidate = extensionsArray[i].trim();
- match = extension.equals(candidate) || EXTENSIONS_WILDCARD.equals(candidate);
- }
- return match;
- }
-
- /**
- * This can be used to check whether this identifier matches the given namespace.
- * <p>
- * The {@code candidate} here will be interpreted as a regular expression.
- * </p>
- *
- * @param candidate
- * Namespace for which we need to validate this {@link ModelIdentifier}. If {@code null}, this
- * will return {@code false} .
- * @return {@code true} if this {@link ModelIdentifier} matches the given namespace.
- */
- public boolean matchNamespace(String candidate) {
- if (namespace == null || candidate == null) {
- return false;
- }
-
- return namespace.matches(candidate.trim());
- }
-
- /**
- * This will try and find the common file extension for the compared models.
- *
- * @param uris
- * The resource URIs that will be compared.
- * @return The common extension of these files or <code>null</code> if file extensions are distinct.
- */
- private static String getCommonExtension(URI... uris) {
- String extension = null;
- for (int i = 0; i < uris.length; i++) {
- if (uris[i] != null) {
- final String fileExtension = uris[i].fileExtension();
- if (extension == null && fileExtension != null) {
- extension = fileExtension;
- } else if (fileExtension != null && !fileExtension.equals(extension)) {
- return null;
- }
- }
- }
- return extension;
- }
-
- /**
- * This will try and find the common namespace of the given resources.
- *
- * @param resources
- * The resources that will be compared.
- * @return The common namespace of these Resources or <code>null</code> if they are distinct.
- * @since 1.1
- */
- private static String getCommonNamespace(Resource... resources) {
- String namespace = null;
- for (int i = 0; i < resources.length; i++) {
- if (resources[i] != null && !resources[i].getContents().isEmpty()) {
- final EObject rootContainer = EcoreUtil.getRootContainer(resources[i].getContents().get(0)
- .eClass());
- if (rootContainer instanceof EPackage) {
- final String nsURI = ((EPackage)rootContainer).getNsURI();
- if (namespace == null && nsURI != null) {
- namespace = nsURI;
- } else if (nsURI == null || !nsURI.equals(namespace)) {
- return null;
- }
- }
- }
- }
- return namespace;
- }
-}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/AttributeChangeSpec.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/AttributeChangeSpec.java
index c336314fa..5cf0a5cf5 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/AttributeChangeSpec.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/AttributeChangeSpec.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -10,25 +10,15 @@
*******************************************************************************/
package org.eclipse.emf.compare.internal.spec;
-import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEGet;
-import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEIsSet;
-
import com.google.common.base.Objects;
-import java.util.List;
-
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.impl.AttributeChangeImpl;
-import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.ecore.EDataType;
-import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
/**
* This specialization of the {@link AttributeChangeImpl} class allows us to define the derived features and
@@ -41,132 +31,40 @@ public class AttributeChangeSpec extends AttributeChangeImpl {
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.DiffImpl#copyLeftToRight()
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
@Override
public void copyLeftToRight() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "requires" diffs
- mergeRequires(false);
-
- switch (getKind()) {
- case ADD:
- // Create the same element in right
- addInTarget(false);
- break;
- case DELETE:
- // Delete that same element from right
- removeFromTarget(false);
- break;
- case MOVE:
- moveElement(false);
- break;
- case CHANGE:
- changeValue(false);
- break;
- default:
- break;
- }
- } else {
- // merge all "required by" diffs
- mergeRequiredBy(false);
-
- switch (getKind()) {
- case ADD:
- // We have a ADD on right. we need to revert this addition
- removeFromTarget(false);
- break;
- case DELETE:
- // DELETE in the right. We need to re-create this element
- addInTarget(false);
- break;
- case MOVE:
- moveElement(false);
- break;
- case CHANGE:
- changeValue(false);
- break;
- default:
- break;
- }
- }
+ /*
+ * This is not extensible : we create a registry for each call and use the default mergers. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyLeftToRight(this, new BasicMonitor());
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.DiffImpl#copyRightToLeft()
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
@Override
public void copyRightToLeft() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "required by" diffs
- mergeRequiredBy(true);
-
- switch (getKind()) {
- case ADD:
- // We have a ADD on left, thus nothing in right. We need to revert the addition
- removeFromTarget(true);
- break;
- case DELETE:
- // DELETE in the left, thus an element in right. We need to re-create that element
- addInTarget(true);
- break;
- case MOVE:
- moveElement(true);
- break;
- case CHANGE:
- changeValue(true);
- break;
- default:
- break;
- }
- } else {
- // merge all "requires" diffs
- mergeRequires(true);
-
- switch (getKind()) {
- case ADD:
- addInTarget(true);
- break;
- case DELETE:
- removeFromTarget(true);
- break;
- case MOVE:
- moveElement(true);
- break;
- case CHANGE:
- changeValue(true);
- break;
- default:
- break;
- }
- }
+ /*
+ * This is not extensible : we create a registry for each call and use the default mergers. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyRightToLeft(this, new BasicMonitor());
}
/**
@@ -181,287 +79,6 @@ public class AttributeChangeSpec extends AttributeChangeImpl {
}
/**
- * This will merge all {@link #getRequiredBy() differences that require us} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequiredBy() differences
- * that require us}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequiredBy(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequiredBy()) {
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequires() required differences} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequires() required
- * differences}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequires(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequires()) {
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will be called when we need to create an element in the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * create an object in its side or add an objet to an attribute. In other words, either :
- * <ul>
- * <li>We are copying from right to left and
- * <ul>
- * <li>we are copying an addition to the right side (we need to create the same object in the left), or</li>
- * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
- * </ul>
- * </li>
- * <li>We are copying from left to right and
- * <ul>
- * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
- * <li>we are copying an addition to the left side (we need to create the same object in the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void addInTarget(boolean rightToLeft) {
- final EObject expectedContainer;
- if (rightToLeft) {
- expectedContainer = getMatch().getLeft();
- } else {
- expectedContainer = getMatch().getRight();
- }
-
- if (expectedContainer == null) {
- // FIXME throw exception? log? re-try to merge our requirements?
- // one of the "required" diffs should have created our container.
- } else {
- final Comparison comparison = getMatch().getComparison();
- final Object expectedValue = getValue();
- // We have the container, attribute and value. We need to know the insertion index.
- if (getAttribute().isMany()) {
- final int insertionIndex = DiffUtil.findInsertionIndex(comparison, this, rightToLeft);
-
- final List<Object> targetList = (List<Object>)expectedContainer.eGet(getAttribute());
- if (targetList instanceof InternalEList<?>) {
- ((InternalEList<Object>)targetList).addUnique(insertionIndex, expectedValue);
- } else {
- targetList.add(insertionIndex, expectedValue);
- }
- } else {
- expectedContainer.eSet(getAttribute(), expectedValue);
- }
- }
- }
-
- /**
- * This will be called when we need to remove an element from the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * delete an object. In other words, we are :
- * <ul>
- * <li>Copying from right to left and either
- * <ul>
- * <li>we are copying a deletion from the right side (we need to remove the same object in the left) or,</li>
- * <li>we are copying an addition to the left side (we need to revert the addition).</li>
- * </ul>
- * </li>
- * <li>Copying from left to right and either
- * <ul>
- * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
- * <li>we are copying a deletion from the left side (we need to remove the same object in the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void removeFromTarget(boolean rightToLeft) {
- final EObject currentContainer;
- if (rightToLeft) {
- currentContainer = getMatch().getLeft();
- } else {
- currentContainer = getMatch().getRight();
- }
-
- if (currentContainer == null) {
- // FIXME throw exception? log? re-try to merge our requirements?
- } else {
- final Object expectedValue = getValue();
- // We have the container, attribute and value to remove.
- if (getAttribute().isMany()) {
- /*
- * TODO if the same value appears twice, should we try and find the one that has actually been
- * deleted? Will it happen that often? For now, remove the first occurence we find.
- */
- final List<Object> targetList = (List<Object>)currentContainer.eGet(getAttribute());
- targetList.remove(expectedValue);
- } else {
- currentContainer.eUnset(getAttribute());
- }
- }
- }
-
- /**
- * This will be called when trying to copy a "MOVE" diff.
- *
- * @param rightToLeft
- * Whether we should move the value in the left or right side.
- */
- protected void moveElement(boolean rightToLeft) {
- final EObject expectedContainer;
- if (rightToLeft) {
- expectedContainer = getMatch().getLeft();
- } else {
- expectedContainer = getMatch().getRight();
- }
-
- if (expectedContainer == null) {
- // TODO throws exception?
- } else {
- final Comparison comparison = getMatch().getComparison();
- final Object expectedValue = getValue();
-
- // We now know the target container, target attribute and target value.
- doMove(comparison, expectedContainer, expectedValue, rightToLeft);
- }
- }
-
- /**
- * This will do the actual work of moving the element into its attribute. All sanity checks were made in
- * {@link #moveElement(boolean)} and no more verification will be made here.
- *
- * @param comparison
- * Comparison holding this Diff.
- * @param expectedContainer
- * The container in which we are reorganizing an attribute.
- * @param expectedValue
- * The value that is to be moved within its attribute.
- * @param rightToLeft
- * Whether we should move the value in the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void doMove(Comparison comparison, EObject expectedContainer, Object expectedValue,
- boolean rightToLeft) {
- if (getAttribute().isMany()) {
- int insertionIndex = DiffUtil.findInsertionIndex(comparison, this, rightToLeft);
- /*
- * However, it could still have been located "before" its new index, in which case we need to take
- * it into account.
- */
- final List<Object> targetList = (List<Object>)expectedContainer.eGet(getAttribute());
- if (insertionIndex > targetList.indexOf(expectedValue)) {
- insertionIndex--;
- }
-
- if (targetList instanceof EList<?>) {
- ((EList<Object>)targetList).move(insertionIndex, expectedValue);
- } else {
- targetList.remove(expectedValue);
- targetList.add(insertionIndex, expectedValue);
- }
- } else {
- // This will never happen with the default diff engine, but may still be done from extenders
- expectedContainer.eSet(getAttribute(), expectedValue);
- }
- }
-
- /**
- * This will be called by the merge operations in order to reset an attribute to its original value, be
- * that the left or right side.
- * <p>
- * Should never be called on multi-valued attributes.
- * </p>
- *
- * @param rightToLeft
- * Tells us the direction of this merge operation.
- */
- protected void resetInTarget(boolean rightToLeft) {
- final EObject targetContainer;
- if (rightToLeft) {
- targetContainer = getMatch().getLeft();
- } else {
- targetContainer = getMatch().getRight();
- }
-
- final EObject originContainer;
- if (getMatch().getComparison().isThreeWay()) {
- originContainer = getMatch().getOrigin();
- } else if (rightToLeft) {
- originContainer = getMatch().getRight();
- } else {
- originContainer = getMatch().getLeft();
- }
-
- if (originContainer == null || !safeEIsSet(targetContainer, getAttribute())
- || !safeEIsSet(originContainer, getAttribute())) {
- targetContainer.eUnset(getAttribute());
- } else {
- final Object expectedValue = originContainer.eGet(getAttribute());
- targetContainer.eSet(getAttribute(), expectedValue);
- }
- }
-
- /**
- * This will be called by the merge operations in order to change single-valued attributes.
- *
- * @param rightToLeft
- * Direction of the merge.
- */
- protected void changeValue(boolean rightToLeft) {
- final EObject expectedContainer;
- if (rightToLeft) {
- expectedContainer = getMatch().getLeft();
- } else {
- expectedContainer = getMatch().getRight();
- }
-
- final EObject originContainer;
- final boolean resetToOrigin = getSource() == DifferenceSource.LEFT && rightToLeft
- || getSource() == DifferenceSource.RIGHT && !rightToLeft;
- if (resetToOrigin && getMatch().getComparison().isThreeWay()) {
- originContainer = getMatch().getOrigin();
- } else if (rightToLeft) {
- originContainer = getMatch().getRight();
- } else {
- originContainer = getMatch().getLeft();
- }
-
- final Object targetValue = safeEGet(originContainer, getAttribute());
-
- // Though not the "default value", we consider that an empty string is an unset attribute.
- final Object defaultValue = getAttribute().getDefaultValue();
- boolean isUnset = targetValue == null || targetValue.equals(defaultValue)
- || (defaultValue == null && "".equals(targetValue)); //$NON-NLS-1$
-
- if (isUnset) {
- expectedContainer.eUnset(attribute);
- } else {
- expectedContainer.eSet(attribute, targetValue);
- }
- }
-
- /**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.AttributeChangeImpl#toString()
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
index 1a6c3d16f..6befb7146 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ComparisonSpec.java
@@ -11,16 +11,18 @@
package org.eclipse.emf.compare.internal.spec;
import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.transform;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
import org.eclipse.emf.common.util.AbstractEList;
import org.eclipse.emf.common.util.BasicEList;
@@ -35,7 +37,6 @@ import org.eclipse.emf.compare.utils.EqualityHelper;
import org.eclipse.emf.compare.utils.IEqualityHelper;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -46,25 +47,6 @@ import org.eclipse.emf.ecore.util.EcoreUtil;
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
public class ComparisonSpec extends ComparisonImpl {
- /**
- * Converts an inverse reference to its corresponding EObject.
- *
- * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
- */
- private static final Function<EStructuralFeature.Setting, EObject> INVERSE_REFERENCES = new Function<EStructuralFeature.Setting, EObject>() {
- /**
- * {@inheritDoc}
- *
- * @see com.google.common.base.Function#apply(java.lang.Object)
- */
- public EObject apply(Setting input) {
- if (input != null) {
- return input.getEObject();
- }
- return null;
- }
- };
-
/** Keeps a reference to our match cross referencer. */
private MatchCrossReferencer matchCrossReferencer;
@@ -103,13 +85,29 @@ public class ComparisonSpec extends ComparisonImpl {
diffCrossReferencer = new DiffCrossReferencer();
eAdapters().add(diffCrossReferencer);
}
- Iterable<Diff> crossRefs = filter(getInverse(element, diffCrossReferencer), Diff.class);
- final BasicEList<Diff> diffs = new BasicEList<Diff>();
- for (Diff diff : crossRefs) {
- diffs.add(diff);
+ final EList<Diff> result;
+ Iterable<Diff> diffOnElement = filter(getInverse(element, diffCrossReferencer), Diff.class);
+ final Match match = getMatch(element);
+ if (match != null) {
+ Iterable<Diff> left = ImmutableList.of();
+ Iterable<Diff> right = ImmutableList.of();
+ Iterable<Diff> origin = ImmutableList.of();
+ if (match.getLeft() != null) {
+ left = filter(getInverse(match.getLeft(), diffCrossReferencer), Diff.class);
+ }
+ if (match.getRight() != null) {
+ right = filter(getInverse(match.getRight(), diffCrossReferencer), Diff.class);
+ }
+ if (match.getOrigin() != null) {
+ origin = filter(getInverse(match.getOrigin(), diffCrossReferencer), Diff.class);
+ }
+ Set<Diff> crossRefs = ImmutableSet.copyOf(Iterables.concat(diffOnElement, left, right, origin));
+ result = new BasicEList<Diff>(crossRefs);
+ } else {
+ result = new BasicEList<Diff>(ImmutableSet.copyOf(diffOnElement));
}
- return diffs;
+ return result;
}
/**
@@ -143,27 +141,12 @@ public class ComparisonSpec extends ComparisonImpl {
* @return a possibly empty {@link Iterable} of inverse references.
*/
private Iterable<EObject> getInverse(EObject element, ECrossReferenceAdapter adapter) {
- return getInverse(element, adapter, Predicates.<Setting> alwaysTrue());
- }
-
- /**
- * Returns an {@link Iterable} of EObject being inverse references of the given {@code element} stored by
- * the {@code adapter}. It is possible to filter returned EObject by filtering out on {@link Setting cross
- * references}.
- *
- * @param element
- * the target of the search cross references.
- * @param adapter
- * the {@link ECrossReferenceAdapter} to use to look for inverse references.
- * @param settingsFilter
- * a filter of {@link Setting} applied on the output of
- * {@link ECrossReferenceAdapter#getInverseReferences(EObject, boolean)}.
- * @return a possibly empty {@link Iterable} of inverse references.
- */
- private Iterable<EObject> getInverse(EObject element, ECrossReferenceAdapter adapter,
- Predicate<Setting> settingsFilter) {
- final Iterable<EStructuralFeature.Setting> settings = adapter.getInverseReferences(element, false);
- return transform(filter(settings, settingsFilter), INVERSE_REFERENCES);
+ final Collection<EStructuralFeature.Setting> settings = adapter.getInverseReferences(element, false);
+ final List<EObject> eObjects = Lists.newArrayList();
+ for (EStructuralFeature.Setting setting : settings) {
+ eObjects.add(setting.getEObject());
+ }
+ return eObjects;
}
/**
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ReferenceChangeSpec.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ReferenceChangeSpec.java
index 6d8bbc2b3..36bcac680 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ReferenceChangeSpec.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ReferenceChangeSpec.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -10,30 +10,12 @@
*******************************************************************************/
package org.eclipse.emf.compare.internal.spec;
-import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEIsSet;
-
import com.google.common.base.Objects;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.emf.common.util.EList;
-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.common.util.BasicMonitor;
import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.impl.ReferenceChangeImpl;
-import org.eclipse.emf.compare.utils.DiffUtil;
-import org.eclipse.emf.compare.utils.EMFCompareCopier;
-import org.eclipse.emf.compare.utils.IEqualityHelper;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.emf.compare.merge.IMerger;
/**
* This specialization of the {@link ReferenceChangeImpl} class allows us to define the derived features and
@@ -43,201 +25,43 @@ import org.eclipse.emf.ecore.xmi.XMIResource;
*/
public class ReferenceChangeSpec extends ReferenceChangeImpl {
/**
- * Set this to <code>true</code> to activate checking the merge state through
- * {@link #checkMergeState(boolean)}.
- */
- private static final boolean DEBUG_MERGE = false;
-
- /**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.DiffImpl#copyLeftToRight()
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
@Override
public void copyLeftToRight() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- boolean continueMerge = handleEquivalences(false);
- if (!continueMerge) {
- return;
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "requires" diffs
- mergeRequires(false);
-
- switch (getKind()) {
- case ADD:
- // Create the same element in right
- addInTarget(false);
- break;
- case DELETE:
- // Delete that same element from right
- removeFromTarget(false);
- break;
- case MOVE:
- moveElement(false);
- break;
- case CHANGE:
- // Is it an unset?
- if (getMatch().getLeft() != null) {
- final EObject leftValue = (EObject)getMatch().getLeft().eGet(getReference(), false);
- if (leftValue == null) {
- removeFromTarget(false);
- } else {
- addInTarget(false);
- }
- } else {
- // we have no left, and the source is on the left. Can only be an unset
- removeFromTarget(false);
- }
- break;
- default:
- break;
- }
- } else {
- // merge all "required by" diffs
- mergeRequiredBy(false);
-
- switch (getKind()) {
- case ADD:
- // We have a ADD on right. we need to revert this addition
- removeFromTarget(false);
- break;
- case DELETE:
- // DELETE in the right. We need to re-create this element
- addInTarget(false);
- break;
- case MOVE:
- moveElement(false);
- break;
- case CHANGE:
- // Is it an unset?
- if (getMatch().getRight() != null) {
- final EObject rightValue = (EObject)getMatch().getRight().eGet(getReference(), false);
- if (rightValue == null) {
- // Value has been unset in the right, and we are merging towards right.
- // We need to re-add this element
- addInTarget(false);
- } else {
- // We'll actually need to "reset" this reference to its original value
- resetInTarget(false);
- }
- } else {
- // we have no right, and the source is on the right. Can only be an unset
- addInTarget(false);
- }
- break;
- default:
- break;
- }
- }
-
- if (DEBUG_MERGE) {
- checkMergeState(false);
- }
+ /*
+ * This is not extensible : we create a registry for each call and use the default mergers. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyLeftToRight(this, new BasicMonitor());
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.DiffImpl#copyRightToLeft()
+ * @deprecated Use
+ * {@link org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff, org.eclipse.emf.common.util.Monitor)}
+ * instead. See javadoc of IMerger.Registry for usage instructions.
*/
+ @Deprecated
@Override
public void copyRightToLeft() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- boolean continueMerge = handleEquivalences(true);
- if (!continueMerge) {
- return;
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "required by" diffs
- mergeRequiredBy(true);
-
- switch (getKind()) {
- case ADD:
- // We have a ADD on left, thus nothing in right. We need to revert the addition
- removeFromTarget(true);
- break;
- case DELETE:
- // DELETE in the left, thus an element in right. We need to re-create that element
- addInTarget(true);
- break;
- case MOVE:
- moveElement(true);
- break;
- case CHANGE:
- // Is it an unset?
- if (getMatch().getLeft() != null) {
- final EObject leftValue = (EObject)getMatch().getLeft().eGet(getReference(), false);
- if (leftValue == null) {
- // Value has been unset in the right, and we are merging towards right.
- // We need to re-add this element
- addInTarget(true);
- } else {
- // We'll actually need to "reset" this reference to its original value
- resetInTarget(true);
- }
- } else {
- // we have no left, and the source is on the left. Can only be an unset
- addInTarget(true);
- }
- break;
- default:
- break;
- }
- } else {
- // merge all "requires" diffs
- mergeRequires(true);
-
- switch (getKind()) {
- case ADD:
- addInTarget(true);
- break;
- case DELETE:
- removeFromTarget(true);
- break;
- case MOVE:
- moveElement(true);
- break;
- case CHANGE:
- // Is it an unset?
- if (getMatch().getRight() != null) {
- final EObject rightValue = (EObject)getMatch().getRight().eGet(getReference(), false);
- if (rightValue == null) {
- removeFromTarget(true);
- } else {
- addInTarget(true);
- }
- } else {
- // we have no right, and the source is on the right. Can only be an unset
- removeFromTarget(true);
- }
- break;
- default:
- break;
- }
- }
-
- if (DEBUG_MERGE) {
- checkMergeState(true);
- }
+ /*
+ * This is not extensible : we always use the default merger instead of querying the registry. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyRightToLeft(this, new BasicMonitor());
}
/**
@@ -252,496 +76,6 @@ public class ReferenceChangeSpec extends ReferenceChangeImpl {
}
/**
- * This will merge all {@link #getRequiredBy() differences that require us} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequiredBy() differences
- * that require us}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequiredBy(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequiredBy()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequires() required differences} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequires() required
- * differences}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequires(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequires()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will be called when trying to copy a "MOVE" diff.
- *
- * @param rightToLeft
- * Whether we should move the value in the left or right side.
- */
- protected void moveElement(boolean rightToLeft) {
- final Comparison comparison = getMatch().getComparison();
- final Match valueMatch = comparison.getMatch(getValue());
-
- final EObject expectedContainer;
- if (getReference().isContainment()) {
- /*
- * We cannot "trust" the holding match (getMatch) in this case. However, "valueMatch" cannot be
- * null : we cannot have detected a move if the moved element is not matched on both sides. Use
- * that information to retrieve the proper "target" container.
- */
- final Match targetContainerMatch;
- // If it exists, use the source side's container as reference
- if (rightToLeft && valueMatch.getRight() != null) {
- targetContainerMatch = comparison.getMatch(valueMatch.getRight().eContainer());
- } else if (!rightToLeft && valueMatch.getLeft() != null) {
- targetContainerMatch = comparison.getMatch(valueMatch.getLeft().eContainer());
- } else {
- // Otherwise, the value we're moving on one side has been removed from its source side.
- targetContainerMatch = comparison.getMatch(valueMatch.getOrigin().eContainer());
- }
- if (rightToLeft) {
- expectedContainer = targetContainerMatch.getLeft();
- } else {
- expectedContainer = targetContainerMatch.getRight();
- }
- } else if (rightToLeft) {
- expectedContainer = getMatch().getLeft();
- } else {
- expectedContainer = getMatch().getRight();
- }
- if (expectedContainer == null) {
- // FIXME throw exception? log? re-try to merge our requirements?
- // one of the "required" diffs should have created our container.
- return;
- }
-
- final EObject expectedValue;
- if (valueMatch == null) {
- // The value being moved is out of the scope
- /*
- * Note : there should not be a way to end up with a "move" for an out of scope value : a move can
- * only be detected if the object is matched on both sides, otherwise all we can see is "add" and
- * "delete"... Is this "fallback" code even reachable? If so, how?
- */
- // We need to look it up
- if (getReference().isMany()) {
- @SuppressWarnings("unchecked")
- final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(getReference());
- expectedValue = findMatchIn(targetList, getValue());
- } else {
- expectedValue = (EObject)expectedContainer.eGet(getReference());
- }
- } else {
- if (rightToLeft) {
- expectedValue = valueMatch.getLeft();
- } else {
- expectedValue = valueMatch.getRight();
- }
- }
- // We now know the target container, target reference and target value.
- doMove(comparison, expectedContainer, expectedValue, rightToLeft);
-
- // TODO check that XMI IDs were preserved
- }
-
- /**
- * This will do the actual work of moving the element into its reference. All sanity checks were made in
- * {@link #moveElement(boolean)} and no more verification will be made here.
- *
- * @param comparison
- * Comparison holding this Diff.
- * @param expectedContainer
- * The container in which we are reorganizing a reference.
- * @param expectedValue
- * The value that is to be moved within its reference.
- * @param rightToLeft
- * Whether we should move the value in the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void doMove(Comparison comparison, EObject expectedContainer, EObject expectedValue,
- boolean rightToLeft) {
- if (getReference().isMany()) {
- // Element to move cannot be part of the LCS... or there would not be a MOVE diff
- int insertionIndex = DiffUtil.findInsertionIndex(comparison, this, rightToLeft);
-
- /*
- * However, it could still have been located "before" its new index, in which case we need to take
- * it into account.
- */
- final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(getReference());
- final int currentIndex = targetList.indexOf(expectedValue);
- if (insertionIndex > currentIndex && currentIndex >= 0) {
- insertionIndex--;
- }
-
- if (currentIndex == -1) {
- // happens for container changes for example.
- if (!getReference().isContainment()) {
- targetList.remove(expectedValue);
- }
- if (insertionIndex >= 0) {
- targetList.add(insertionIndex, expectedValue);
- } else {
- targetList.add(expectedValue);
- }
- } else if (targetList instanceof EList<?>) {
- ((EList<EObject>)targetList).move(insertionIndex, expectedValue);
- } else {
- targetList.remove(expectedValue);
- targetList.add(insertionIndex, expectedValue);
- }
- } else {
- expectedContainer.eSet(getReference(), expectedValue);
- }
- }
-
- /**
- * This will be called when we need to create an element in the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * create an object in its side or add an objet to a reference. In other words, either :
- * <ul>
- * <li>We are copying from right to left and
- * <ul>
- * <li>we are copying an addition to the right side (we need to create the same object in the left), or</li>
- * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
- * </ul>
- * </li>
- * <li>We are copying from left to right and
- * <ul>
- * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
- * <li>we are copying an addition to the left side (we need to create the same object in the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void addInTarget(boolean rightToLeft) {
- final EObject expectedContainer;
- if (rightToLeft) {
- expectedContainer = getMatch().getLeft();
- } else {
- expectedContainer = getMatch().getRight();
- }
- final Comparison comparison = getMatch().getComparison();
-
- if (expectedContainer == null) {
- // FIXME throw exception? log? re-try to merge our requirements?
- // one of the "required" diffs should have created our container.
- return;
- }
-
- final EObject expectedValue;
- final Match valueMatch = comparison.getMatch(getValue());
- if (valueMatch == null) {
- // This is an out of scope value.
- if (getValue().eIsProxy()) {
- // Copy the proxy
- expectedValue = EcoreUtil.copy(getValue());
- } else {
- // Use the same value.
- expectedValue = getValue();
- }
- } else if (rightToLeft) {
- if (getReference().isContainment()) {
- expectedValue = createTarget(getValue());
- valueMatch.setLeft(expectedValue);
- } else {
- expectedValue = valueMatch.getLeft();
- }
- } else {
- if (getReference().isContainment()) {
- expectedValue = createTarget(getValue());
- valueMatch.setRight(expectedValue);
- } else {
- expectedValue = valueMatch.getRight();
- }
- }
-
- // We have the container, reference and value. We need to know the insertion index.
- if (getReference().isMany()) {
- final int insertionIndex = DiffUtil.findInsertionIndex(comparison, this, rightToLeft);
-
- final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(getReference());
-
- if (targetList instanceof InternalEList<?>) {
- ((InternalEList<EObject>)targetList).addUnique(insertionIndex, expectedValue);
- } else {
- targetList.add(insertionIndex, expectedValue);
- }
- } else {
- expectedContainer.eSet(getReference(), expectedValue);
- }
-
- if (getReference().isContainment()) {
- // Copy XMI ID when applicable.
- final Resource initialResource = getValue().eResource();
- final Resource targetResource = expectedValue.eResource();
- if (initialResource instanceof XMIResource && targetResource instanceof XMIResource) {
- ((XMIResource)targetResource).setID(expectedValue, ((XMIResource)initialResource)
- .getID(getValue()));
- }
- }
- }
-
- /**
- * This will create a copy of the given EObject that can be used as the target of an addition (or the
- * reverting of a deletion).
- * <p>
- * The target will be self-contained and will have no reference towards any other EObject set (neither
- * containment nor "classic" references). All of its attributes' values will match the given
- * {@code referenceObject}'s.
- * </p>
- *
- * @param referenceObject
- * The EObject for which we'll create a copy.
- * @return A self-contained copy of {@code referenceObject}.
- * @see EMFCompareCopier#copy(EObject)
- */
- protected EObject createTarget(EObject referenceObject) {
- /*
- * We can't simply use EcoreUtil.copy. References will have their own diffs and will thus be merged
- * later on.
- */
- final EcoreUtil.Copier copier = new EMFCompareCopier();
- return copier.copy(referenceObject);
- }
-
- /**
- * This will be called when we need to remove an element from the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * delete an object. In other words, we are :
- * <ul>
- * <li>Copying from right to left and either
- * <ul>
- * <li>we are copying a deletion from the right side (we need to remove the same object in the left) or,</li>
- * <li>we are copying an addition to the left side (we need to revert the addition).</li>
- * </ul>
- * </li>
- * <li>Copying from left to right and either
- * <ul>
- * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
- * <li>we are copying a deletion from the left side (we need to remove the same object in the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- @SuppressWarnings("unchecked")
- protected void removeFromTarget(boolean rightToLeft) {
- final EObject currentContainer;
- if (rightToLeft) {
- currentContainer = getMatch().getLeft();
- } else {
- currentContainer = getMatch().getRight();
- }
- final Comparison comparison = getMatch().getComparison();
- final Match valueMatch = comparison.getMatch(getValue());
-
- if (currentContainer == null) {
- // FIXME throw exception? log? re-try to merge our requirements?
- // one of the "required" diffs should have created our container.
- return;
- }
-
- final EObject expectedValue;
- if (valueMatch == null) {
- // value is out of the scope... we need to look it up
- if (getReference().isMany()) {
- final List<EObject> targetList = (List<EObject>)currentContainer.eGet(getReference());
- expectedValue = findMatchIn(targetList, getValue());
- } else {
- // the value will not be needed anyway
- expectedValue = null;
- }
- } else if (rightToLeft) {
- expectedValue = valueMatch.getLeft();
- } else {
- expectedValue = valueMatch.getRight();
- }
-
- // We have the container, reference and value to remove. Expected value can be null when the
- // deletion was made on both side (i.e. a pseudo delete)
- if (getReference().isContainment() && expectedValue != null) {
- EcoreUtil.remove(expectedValue);
- if (rightToLeft && valueMatch != null) {
- valueMatch.setLeft(null);
- } else if (valueMatch != null) {
- valueMatch.setRight(null);
- }
- // TODO remove dangling? remove empty Match?
- } else if (getReference().isMany()) {
- /*
- * TODO if the same value appears twice, should we try and find the one that has actually been
- * deleted? Can it happen? For now, remove the first occurence we find.
- */
- final List<EObject> targetList = (List<EObject>)currentContainer.eGet(getReference());
- targetList.remove(expectedValue);
- } else {
- currentContainer.eUnset(getReference());
- }
- }
-
- /**
- * This will be called by the merge operations in order to reset a reference to its original value, be
- * that the left or right side.
- * <p>
- * Should never be called on multi-valued references.
- * </p>
- *
- * @param rightToLeft
- * Tells us the direction of this merge operation.
- */
- protected void resetInTarget(boolean rightToLeft) {
- final EObject targetContainer;
- if (rightToLeft) {
- targetContainer = getMatch().getLeft();
- } else {
- targetContainer = getMatch().getRight();
- }
-
- final EObject originContainer;
- if (getMatch().getComparison().isThreeWay()) {
- originContainer = getMatch().getOrigin();
- } else if (rightToLeft) {
- originContainer = getMatch().getRight();
- } else {
- originContainer = getMatch().getLeft();
- }
-
- if (originContainer == null || !safeEIsSet(targetContainer, getReference())
- || !safeEIsSet(originContainer, getReference())) {
- targetContainer.eUnset(getReference());
- } else {
- final EObject originalValue = (EObject)originContainer.eGet(getReference());
- final Match valueMatch = getMatch().getComparison().getMatch(originalValue);
- final EObject expectedValue;
- if (valueMatch == null) {
- // Value is out of the scope, use it as-is
- expectedValue = originalValue;
- } else if (rightToLeft) {
- expectedValue = valueMatch.getLeft();
- } else {
- expectedValue = valueMatch.getRight();
- }
- targetContainer.eSet(getReference(), expectedValue);
- }
- }
-
- /**
- * Handles the equivalences of this difference.
- * <p>
- * Note that in certain cases, we'll merge our opposite instead of merging this diff. Specifically, we'll
- * do that for one-to-many eOpposites : we'll merge the 'many' side instead of the 'unique' one. This
- * allows us not to worry about the order of the references on that 'many' side.
- * </p>
- * <p>
- * This is called before the merge of <code>this</code>. In short, if this returns <code>false</code>, we
- * won't carry on merging <code>this</code> after returning.
- * </p>
- *
- * @param rightToLeft
- * Direction of the merge.
- * @return <code>true</code> if the current difference should still be merged after handling its
- * equivalences, <code>false</code> if it should be considered "already merged".
- */
- protected boolean handleEquivalences(boolean rightToLeft) {
- boolean continueMerge = true;
- for (Diff equivalent : getEquivalence().getDifferences()) {
- if (equivalent instanceof ReferenceChange
- && getReference().getEOpposite() == ((ReferenceChange)equivalent).getReference()
- && equivalent.getState() == DifferenceState.UNRESOLVED) {
- // This equivalence is on our eOpposite. Should we merge it instead of 'this'?
- final boolean mergeEquivalence = !getReference().isMany()
- && ((ReferenceChange)equivalent).getReference().isMany();
- if (mergeEquivalence && rightToLeft) {
- equivalent.copyRightToLeft();
- continueMerge = false;
- } else if (mergeEquivalence) {
- equivalent.copyLeftToRight();
- continueMerge = false;
- }
- } else if (getSource() == DifferenceSource.LEFT) {
- // This can happen when merging subset/supersets... see AddInterfaceTest#testA50UseCase
- /*
- * This should be removed (or we should make sure that we can never be here) when bug 398402
- * is fixed.
- */
- if (rightToLeft && getRequiredBy().contains(equivalent)) {
- equivalent.copyRightToLeft();
- continueMerge = false;
- } else if (!rightToLeft && getRequires().contains(equivalent)) {
- equivalent.copyLeftToRight();
- continueMerge = false;
- }
- } else if (getSource() == DifferenceSource.RIGHT) {
- // This can happen when merging subset/supersets... see AddInterfaceTest#testA50UseCase
- /*
- * This should be removed (or we should make sure that we can never be here) when bug 398402
- * is fixed.
- */
- if (rightToLeft && getRequires().contains(equivalent)) {
- equivalent.copyRightToLeft();
- continueMerge = false;
- } else if (!rightToLeft && getRequiredBy().contains(equivalent)) {
- equivalent.copyLeftToRight();
- continueMerge = false;
- }
- }
- equivalent.setState(DifferenceState.MERGED);
- }
- return continueMerge;
- }
-
- /**
- * Seeks a match of the given {@code element} in the given list, using the equality helper to find it.
- * This is only used when moving or deleting proxies for now.
- *
- * @param list
- * The list from which we seek a value.
- * @param element
- * The value for which we need a match in {@code list}.
- * @return The match of {@code element} in {@code list}, {@code null} if none.
- */
- private EObject findMatchIn(List<EObject> list, EObject element) {
- final Comparison comparison = getMatch().getComparison();
- final IEqualityHelper helper = comparison.getEqualityHelper();
- final Iterator<EObject> it = list.iterator();
- while (it.hasNext()) {
- final EObject next = it.next();
- if (helper.matchingValues(next, element)) {
- return next;
- }
- }
- return null;
- }
-
- /**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.impl.DiffImpl#toString()
@@ -760,168 +94,4 @@ public class ReferenceChangeSpec extends ReferenceChangeImpl {
.add("state", getState()).toString();
// @formatter:on
}
-
- /**
- * This should only be activated when debugging. Not only may this long list of assertions not cover every
- * possible case, but it would impair performance. Even when debugging, take these with a grain of salt :
- * we've covered the known cases, but the assertions here could still fail on some cases where the merge
- * worked.
- * <p>
- * Set {@link #DEBUG_MERGE} to <code>true</code> to activate checking the merge state through here.
- * </p>
- *
- * @param rightToLeft
- * Direction of the merge.
- */
- // This is a long list of assertions ... disable formatting and style checking.
- // @formatter:off
- // CHECKSTYLE:OFF
- @SuppressWarnings("nls")
- private void checkMergeState(boolean rightToLeft) {
- final Match containerMatch = getMatch();
- final Comparison comparison = containerMatch.getComparison();
- final Match valueMatch = comparison.getMatch(getValue());
-
- Object leftValue = null;
- if (containerMatch.getLeft() != null) {
- leftValue = containerMatch.getLeft().eGet(getReference());
- }
- Object rightValue = null;
- if (containerMatch.getRight() != null) {
- rightValue = containerMatch.getRight().eGet(getReference());
- }
-
- final boolean mergeTowardsSource = rightToLeft && getSource() == DifferenceSource.LEFT
- || !rightToLeft && getSource() == DifferenceSource.RIGHT;
- final boolean wasDeleteMerge = getKind() == DifferenceKind.ADD && mergeTowardsSource
- || getKind() == DifferenceKind.DELETE && !mergeTowardsSource;
-
- assert getState() == DifferenceState.MERGED : "Difference has not been set as MERGED.";
- if (mergeTowardsSource) {
- for (Diff diff : getRequiredBy()) {
- assert diff.getState() == DifferenceState.MERGED : "Requirement has not been merged.";
- }
- } else {
- for (Diff diff : getRequires()) {
- assert diff.getState() == DifferenceState.MERGED : "Requirement has not been merged.";
- }
- }
- if (getEquivalence() != null) {
- for (Diff diff : getEquivalence().getDifferences()) {
- assert diff.getState() == DifferenceState.MERGED : "Equivalence has not been set as MERGED.";
- }
- }
-
- assert getReference() != null : "Cannot have an empty reference";
-
- if (getReference().isContainment()) {
- if (valueMatch == null) {
- // Value was out of the scope. This could only be an "ADD" or "DELETE" diff. Whatever the direction, both sides now point towards the very same instance
- if (getReference().isMany()) {
- if (wasDeleteMerge) {
- if (leftValue != null) {
- assert leftValue instanceof List<?>;
- assert !((List<?>)leftValue).contains(getValue()) : "None of the sides should contain the value";
- }
- if (rightValue != null) {
- assert rightValue instanceof List<?>;
- assert !((List<?>)rightValue).contains(getValue()) : "None of the sides should contain the value";
- }
- } else {
- if (leftValue != null) {
- assert leftValue instanceof List<?>;
- assert ((List<?>)leftValue).contains(getValue()) : "Both sides shoulds point towards the same instance";
- }
- if (rightValue != null) {
- assert rightValue instanceof List<?>;
- assert ((List<?>)rightValue).contains(getValue()) : "Both sides shoulds point towards the same instance";
- }
- }
- } else {
- // EObject or null, but same instance anyway
- assert leftValue == rightValue : "Both sides should point towards the same instance";
- }
- } else {
- if (getKind() == DifferenceKind.MOVE && valueMatch.getLeft() != null && valueMatch.getRight() != null) {
- // We can only trust the value match here.
- final EObject leftContainer = valueMatch.getLeft().eContainer();
- final EObject rightContainer = valueMatch.getRight().eContainer();
- // The "values" we computed beforehand are thus wrong.
- leftValue = leftContainer.eGet(getReference());
- rightValue = rightContainer.eGet(getReference());
- }
-
- if (getReference().isMany()) {
- if (wasDeleteMerge) {
- if (leftValue != null) {
- assert leftValue instanceof List<?>;
- assert !((List<?>)leftValue).contains(valueMatch.getLeft()) : "None of the sides should contain the matched value";
- }
- if (rightValue != null) {
- assert rightValue instanceof List<?>;
- assert !((List<?>)rightValue).contains(valueMatch.getRight()) : "None of the sides should contain the matched value";
- }
- } else {
- if (leftValue != null) {
- assert leftValue instanceof List<?>;
- assert ((List<?>)leftValue).contains(valueMatch.getLeft()) : "Both sides shoulds point towards the matched value";
- }
- if (rightValue != null) {
- assert rightValue instanceof List<?>;
- assert ((List<?>)rightValue).contains(valueMatch.getRight()) : "Both sides shoulds point towards the matchedValue";
- }
- }
- } else if (wasDeleteMerge) {
- assert leftValue == null && rightValue == null : "Both values should be 'null'.";
- } else {
- assert leftValue == valueMatch.getLeft() && rightValue == valueMatch.getRight() : "The value should be the matched one on both sides.";
- }
- }
- } else {
- if (leftValue instanceof EObject) {
- final Match leftValueMatch = comparison.getMatch((EObject)leftValue);
- if (leftValueMatch == null) {
- assert leftValue == rightValue : "Merging an out-of-scope element should leave both sides pointing towards the instance.";
- } else {
- assert leftValueMatch.getRight() == rightValue : "Merging should leave both sides pointing towards the same matched value";
- }
- } else {
- if (valueMatch == null) {
- if (wasDeleteMerge) {
- if (leftValue instanceof List<?>) {
- assert !((List<?>)leftValue).contains(getValue()) : "Value should have been deleted from both sides.";
- }
- if (rightValue instanceof List<?>) {
- assert !((List<?>)rightValue).contains(getValue()) : "Value should have been deleted from both sides.";
- }
- } else {
- if (leftValue instanceof List<?>) {
- assert ((List<?>)leftValue).contains(getValue()) : "Merging an out-of-scope element should leave both sides pointing towards the instance.";
- }
- if (rightValue instanceof List<?>) {
- assert ((List<?>)rightValue).contains(getValue()) : "Merging an out-of-scope element should leave both sides pointing towards the instance.";
- }
- }
- } else {
- if (wasDeleteMerge) {
- if (leftValue instanceof List<?>) {
- assert !((List<?>)leftValue).contains(valueMatch.getLeft()) : "None of the sides should contain the matched value";
- }
- if (rightValue instanceof List<?>) {
- assert !((List<?>)rightValue).contains(valueMatch.getRight()) : "None of the sides should contain the matched value";
- }
- } else {
- if (leftValue instanceof List<?>) {
- assert ((List<?>)leftValue).contains(valueMatch.getLeft()) : "Both sides shoulds point towards the matched value";
- }
- if (rightValue instanceof List<?>) {
- assert ((List<?>)rightValue).contains(valueMatch.getRight()) : "Both sides shoulds point towards the matchedValue";
- }
- }
- }
- }
- }
- }
- // @formatter:on
- // CHECKSTYLE:ON
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ResourceAttachmentChangeSpec.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ResourceAttachmentChangeSpec.java
index 792dfc001..acb024fa8 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ResourceAttachmentChangeSpec.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/spec/ResourceAttachmentChangeSpec.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -10,27 +10,10 @@
*******************************************************************************/
package org.eclipse.emf.compare.internal.spec;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.compare.Comparison;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.DifferenceState;
-import org.eclipse.emf.compare.EMFCompareMessages;
-import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.MatchResource;
import org.eclipse.emf.compare.impl.ResourceAttachmentChangeImpl;
-import org.eclipse.emf.compare.utils.DiffUtil;
-import org.eclipse.emf.compare.utils.EMFCompareCopier;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.ecore.xmi.XMIResource;
+import org.eclipse.emf.compare.merge.IMerger;
/**
* This specialization of the {@link ResourceAttachmentChangeImpl} class allows us to define the derived
@@ -46,54 +29,13 @@ public class ResourceAttachmentChangeSpec extends ResourceAttachmentChangeImpl {
*/
@Override
public void copyLeftToRight() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "requires" diffs
- mergeRequires(false);
-
- switch (getKind()) {
- case ADD:
- // Create the same root in right
- addInTarget(false);
- break;
- case DELETE:
- // Delete that same root from right
- removeFromTarget(false);
- break;
- default:
- // other cases are unknown at the time of writing
- break;
- }
- } else {
- // merge all "required by" diffs
- mergeRequiredBy(false);
-
- switch (getKind()) {
- case ADD:
- // Revert the addition of this root
- removeFromTarget(false);
- break;
- case DELETE:
- // re-create this element
- addInTarget(false);
- break;
- default:
- // other cases are unknown at the time of writing
- break;
- }
- }
+ /*
+ * This is not extensible : we create a registry for each call and use the default mergers. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyLeftToRight(this, new BasicMonitor());
}
/**
@@ -103,54 +45,13 @@ public class ResourceAttachmentChangeSpec extends ResourceAttachmentChangeImpl {
*/
@Override
public void copyRightToLeft() {
- // Don't merge an already merged (or discarded) diff
- if (getState() != DifferenceState.UNRESOLVED) {
- return;
- }
-
- // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
- setState(DifferenceState.MERGED);
- if (getEquivalence() != null) {
- for (Diff equivalent : getEquivalence().getDifferences()) {
- equivalent.setState(DifferenceState.MERGED);
- }
- }
-
- if (getSource() == DifferenceSource.LEFT) {
- // merge all "required by" diffs
- mergeRequiredBy(true);
-
- switch (getKind()) {
- case ADD:
- // Revert the addition of this root
- removeFromTarget(true);
- break;
- case DELETE:
- // re-create this element
- addInTarget(true);
- break;
- default:
- // other cases are unknown at the time of writing
- break;
- }
- } else {
- // merge all "requires" diffs
- mergeRequires(true);
-
- switch (getKind()) {
- case ADD:
- // Create the same root in left
- addInTarget(true);
- break;
- case DELETE:
- // Delete that same root from left
- removeFromTarget(true);
- break;
- default:
- // other cases are unknown at the time of writing
- break;
- }
- }
+ /*
+ * This is not extensible : we create a registry for each call and use the default mergers. This
+ * implementation is merely a placeholder to avoid API breakage. Please refer to IMerger.Registry for
+ * merging instructions.
+ */
+ final IMerger merger = IMerger.RegistryImpl.createStandaloneInstance().getHighestRankingMerger(this);
+ merger.copyRightToLeft(this, new BasicMonitor());
}
/**
@@ -163,344 +64,4 @@ public class ResourceAttachmentChangeSpec extends ResourceAttachmentChangeImpl {
setState(DifferenceState.DISCARDED);
// Should we also discard equivalent diffs? And diffs that require this one?
}
-
- /**
- * This will merge all {@link #getRequiredBy() differences that require us} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequiredBy() differences
- * that require us}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequiredBy(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequiredBy()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will merge all {@link #getRequires() required differences} in the given direction.
- *
- * @param rightToLeft
- * If {@code true}, {@link #copyRightToLeft() apply} all {@link #getRequires() required
- * differences}. Otherwise, {@link #copyLeftToRight() revert} them.
- */
- protected void mergeRequires(boolean rightToLeft) {
- // TODO log back to the user what we will merge along?
- for (Diff dependency : getRequires()) {
- // TODO: what to do when state = Discarded but is required?
- if (rightToLeft) {
- dependency.copyRightToLeft();
- } else {
- dependency.copyLeftToRight();
- }
- }
- }
-
- /**
- * This will be called when we need to create an element in the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * create an object in its side. In other words, either :
- * <ul>
- * <li>We are copying from right to left and
- * <ul>
- * <li>we are copying an addition to the right side (we need to create the same root in the left), or</li>
- * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
- * </ul>
- * </li>
- * <li>We are copying from left to right and
- * <ul>
- * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
- * <li>we are copying an addition to the left side (we need to create the same root in the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- protected void addInTarget(boolean rightToLeft) {
- final Comparison comparison = getMatch().getComparison();
- final Resource expectedContainer = findOrCreateTargetResource(rightToLeft);
-
- final EObject sourceValue;
- if (rightToLeft) {
- sourceValue = getMatch().getRight();
- } else {
- sourceValue = getMatch().getLeft();
- }
-
- final EObject expectedValue;
- final Match valueMatch = getMatch();
- if (rightToLeft) {
- if (valueMatch.getLeft() != null) {
- expectedValue = valueMatch.getLeft();
- } else {
- expectedValue = createTarget(sourceValue);
- valueMatch.setLeft(expectedValue);
- }
- } else if (valueMatch.getRight() != null) {
- expectedValue = valueMatch.getRight();
- } else {
- expectedValue = createTarget(sourceValue);
- valueMatch.setRight(expectedValue);
- }
-
- // double-check : is our target already present in the target resource?
- final URI sourceURI = EcoreUtil.getURI(sourceValue);
- if (expectedContainer.getEObject(sourceURI.fragment()) != null) {
- /*
- * The only way for this use case to kick in is if we have both (or "all three") compared models
- * side-by-side during a local comparison. In such an event, the "new" resource can only be an
- * existing one (since relative paths will always resolve to the same location whatever the side),
- * and it will obviously already contain the object since we detected the resource change. In such
- * a case, we do not want to erase the already existing object or copy a duplicate in the target
- * resource. We'll simply change the "to-be-modified" object to point to that already existing one
- * through proxification and re-resolution. This is costly and clumsy, but this use case should be
- * sufficiently rare to not be noticed, we only want it to be functional.
- */
- ((InternalEObject)expectedValue).eSetProxyURI(sourceURI);
- if (expectedContainer.getResourceSet() != null) {
- EcoreUtil.resolveAll(expectedContainer.getResourceSet());
- } else {
- EcoreUtil.resolveAll(expectedContainer);
- }
- if (rightToLeft) {
- valueMatch.setLeft(expectedContainer.getEObject(sourceURI.fragment()));
- } else {
- valueMatch.setRight(expectedContainer.getEObject(sourceURI.fragment()));
- }
- return;
- }
-
- // We have the container, reference and value. We need to know the insertion index.
- final Resource initialResource = sourceValue.eResource();
- final List<EObject> sourceList = initialResource.getContents();
- final List<EObject> targetList = expectedContainer.getContents();
- final int insertionIndex = DiffUtil.findInsertionIndex(comparison, sourceList, targetList,
- expectedValue);
-
- if (targetList instanceof InternalEList<?>) {
- ((InternalEList<EObject>)targetList).addUnique(insertionIndex, expectedValue);
- } else {
- targetList.add(insertionIndex, expectedValue);
- }
-
- // Copy XMI ID when applicable.
- if (initialResource instanceof XMIResource && expectedContainer instanceof XMIResource) {
- ((XMIResource)expectedContainer).setID(expectedValue, ((XMIResource)initialResource)
- .getID(sourceValue));
- }
- }
-
- /**
- * This will try and locate the "target" resource of this merge in the current comparison. If we can't
- * locate it, we assume that it needs to be created as we are in the process of adding a new element to
- * it.
- *
- * @param rightToLeft
- * Direction of the merge. This will tell us which side we are to look up for the target
- * resource.
- * @return The resource we could find in the current comparison if any. Otherwise, we'll return either a
- * newly created resource that can serve as a target of this merge, or <code>null</code> if no
- * valid target resource can be created.
- */
- private Resource findOrCreateTargetResource(boolean rightToLeft) {
- final Comparison comparison = getMatch().getComparison();
- final Resource sourceRes;
- if (rightToLeft) {
- sourceRes = getMatch().getRight().eResource();
- } else {
- sourceRes = getMatch().getLeft().eResource();
- }
-
- final List<MatchResource> matchedResources = comparison.getMatchedResources();
- final int size = matchedResources.size();
- final MatchResource soughtMatch = getMatchResource(sourceRes);
-
- // Is the resource already existing or do we need to create it?
- final Resource target;
- if (rightToLeft && soughtMatch.getLeft() != null) {
- target = soughtMatch.getLeft();
- } else if (!rightToLeft && soughtMatch.getRight() != null) {
- target = soughtMatch.getRight();
- } else {
- // we need to create it.
- final URI targetURI = computeTargetURI(rightToLeft);
- // FIXME this will most likely fail with remote URIs : we'll need to make it local afterwards
- if (targetURI == null) {
- // We treat null as "no valid target". We'll cancel the merge operation.
- return null;
- }
-
- ResourceSet targetSet = null;
- for (int i = 0; i < size && targetSet == null; i++) {
- final MatchResource matchRes = matchedResources.get(i);
- if (rightToLeft && matchRes.getLeft() != null) {
- targetSet = matchRes.getLeft().getResourceSet();
- } else if (!rightToLeft && matchRes.getRight() != null) {
- targetSet = matchRes.getRight().getResourceSet();
- }
- }
-
- if (targetSet == null) {
- // Cannot create the target
- throw new RuntimeException(EMFCompareMessages.getString(
- "ResourceAttachmentChangeSpec.MissingRS", targetURI.lastSegment())); //$NON-NLS-1$
- }
-
- // This resource might already exists
- if (targetSet.getURIConverter().exists(targetURI, Collections.emptyMap())) {
- target = targetSet.getResource(targetURI, true);
- } else {
- target = targetSet.createResource(targetURI);
- }
-
- if (rightToLeft) {
- soughtMatch.setLeft(target);
- } else {
- soughtMatch.setRight(target);
- }
-
- }
-
- return target;
- }
-
- /**
- * Computes the URI of the "target" resource. Will be used if we need to create or "find" it.
- *
- * @param rightToLeft
- * Direction of the merge.
- * @return The URI that is to be used for our target resource. <code>null</code> if we cannot compute a
- * valid target URI.
- */
- protected URI computeTargetURI(boolean rightToLeft) {
- final EObject sourceObject;
- final EObject targetObject;
- if (rightToLeft) {
- sourceObject = getMatch().getRight();
- targetObject = getMatch().getLeft();
- } else {
- sourceObject = getMatch().getLeft();
- targetObject = getMatch().getRight();
- }
- final Resource sourceResource = sourceObject.eResource();
- // This is the resource that will change through this merge.
- // We will only use it to determine a relative path for the real target resource.
- final Resource currentResource = targetObject.eResource();
-
- final MatchResource matchCurrent = getMatchResource(currentResource);
- final Resource currentFromSourceSide;
- if (rightToLeft) {
- currentFromSourceSide = matchCurrent.getRight();
- } else {
- currentFromSourceSide = matchCurrent.getLeft();
- }
-
- // Case of control/uncontrol
- final URI relativeTargetURI = sourceResource.getURI().deresolve(currentFromSourceSide.getURI());
-
- return relativeTargetURI.resolve(currentResource.getURI());
- }
-
- /**
- * Returns the MatchResource corresponding to the given <code>resource</code>.
- *
- * @param resource
- * Resource for which we need a MatchResource.
- * @return The MatchResource corresponding to the given <code>resource</code>.
- */
- protected MatchResource getMatchResource(Resource resource) {
- final List<MatchResource> matchedResources = getMatch().getComparison().getMatchedResources();
- final int size = matchedResources.size();
- MatchResource soughtMatch = null;
- for (int i = 0; i < size && soughtMatch == null; i++) {
- final MatchResource matchRes = matchedResources.get(i);
- if (matchRes.getRight() == resource || matchRes.getLeft() == resource
- || matchRes.getOrigin() == resource) {
- soughtMatch = matchRes;
- }
- }
-
- if (soughtMatch == null) {
- // This should never happen
- throw new RuntimeException(EMFCompareMessages.getString(
- "ResourceAttachmentChangeSpec.MissingMatch", resource.getURI().lastSegment())); //$NON-NLS-1$
- }
-
- return soughtMatch;
- }
-
- /**
- * This will create a copy of the given EObject that can be used as the target of an addition (or the
- * reverting of a deletion).
- * <p>
- * The target will be self-contained and will have no reference towards any other EObject set (neither
- * containment nor "classic" references). All of its attributes' values will match the given
- * {@code referenceObject}'s.
- * </p>
- *
- * @param referenceObject
- * The EObject for which we'll create a copy.
- * @return A self-contained copy of {@code referenceObject}.
- * @see EMFCompareCopier#copy(EObject)
- */
- protected EObject createTarget(EObject referenceObject) {
- /*
- * We can't simply use EcoreUtil.copy. References will have their own diffs and will thus be merged
- * later on.
- */
- final EcoreUtil.Copier copier = new EMFCompareCopier();
- return copier.copy(referenceObject);
- }
-
- /**
- * This will be called when we need to remove an element from the target side.
- * <p>
- * All necessary sanity checks have been made to ensure that the current operation is one that should
- * delete an object. In other words, we are :
- * <ul>
- * <li>Copying from right to left and either
- * <ul>
- * <li>we are copying a deletion from the right side (we need to remove the same root from the left) or,</li>
- * <li>we are copying an addition to the left side (we need to revert the addition).</li>
- * </ul>
- * </li>
- * <li>Copying from left to right and either
- * <ul>
- * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
- * <li>we are copying a deletion from the left side (we need to remove the same root from the right).</li>
- * </ul>
- * </li>
- * </ul>
- * </p>
- *
- * @param rightToLeft
- * Tells us whether we are to add an object on the left or right side.
- */
- protected void removeFromTarget(boolean rightToLeft) {
- final Match valueMatch = getMatch();
- final EObject expectedValue;
- if (rightToLeft) {
- expectedValue = valueMatch.getLeft();
- } else {
- expectedValue = valueMatch.getRight();
- }
-
- // if this is a pseudo conflict, we have no value to remove
- if (expectedValue != null) {
- // We only wish to remove the element from its containing resource, not from its container.
- // This will not affect the match.
- final Resource resource = ((InternalEObject)expectedValue).eDirectResource();
- resource.getContents().remove(expectedValue);
- }
- }
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AbstractMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AbstractMerger.java
new file mode 100644
index 000000000..8d852314c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AbstractMerger.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * 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.merge;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.utils.EMFCompareCopier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+/**
+ * Abstract implementation of an {@link IMerger}. This can be used as a base implementation to avoid
+ * re-implementing the whole contract.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public abstract class AbstractMerger implements IMerger {
+ /** Ranking of this merger. */
+ private int ranking;
+
+ /** Registry from which this merger has been created.. */
+ private Registry registry;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#getRanking()
+ */
+ public int getRanking() {
+ return ranking;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#setRanking(int)
+ */
+ public void setRanking(int r) {
+ ranking = r;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#getRegistry()
+ */
+ public Registry getRegistry() {
+ return registry;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#setRegistry(org.eclipse.emf.compare.merge.IMerger.Registry)
+ */
+ public void setRegistry(Registry registry) {
+ if (this.registry != null && registry != null) {
+ throw new IllegalStateException("The registry has to be set only once."); //$NON-NLS-1$
+ }
+ this.registry = registry;
+ }
+
+ /**
+ * This will merge all {@link Diff#getRequiredBy() differences that require} {@code diff} in the given
+ * direction.
+ *
+ * @param diff
+ * We need to merge all differences that require this one (see {@link Diff#getRequiredBy()}.
+ * @param rightToLeft
+ * If {@code true}, {@link #copyRightToLeft(Diff, Monitor) apply} all differences that require
+ * {@code diff}. Otherwise, {@link #copyLeftToRight(Diff, Monitor) revert} them.
+ * @param monitor
+ * The monitor we should use to report progress.
+ */
+ protected void mergeRequiredBy(Diff diff, boolean rightToLeft, Monitor monitor) {
+ // TODO log back to the user what we will merge along?
+ for (Diff dependency : diff.getRequiredBy()) {
+ // TODO: what to do when state = Discarded but is required?
+ mergeDiff(dependency, rightToLeft, monitor);
+ }
+ }
+
+ /**
+ * This will merge all {@link Diff#getRequires() differences required by} {@code diff} in the given
+ * direction.
+ *
+ * @param diff
+ * The difference which requirements we need to merge.
+ * @param rightToLeft
+ * If {@code true}, {@link #copyRightToLeft(Diff, Monitor) apply} all required differences.
+ * Otherwise, {@link #copyLeftToRight(Diff, Monitor) revert} them.
+ * @param monitor
+ * The monitor we should use to report progress.
+ */
+ protected void mergeRequires(Diff diff, boolean rightToLeft, Monitor monitor) {
+ // TODO log back to the user what we will merge along?
+ for (Diff dependency : diff.getRequires()) {
+ // TODO: what to do when state = Discarded but is required?
+ mergeDiff(dependency, rightToLeft, monitor);
+ }
+ }
+
+ /**
+ * This can be used by mergers to merge another (required, equivalent...) difference using the right
+ * merger for that diff.
+ *
+ * @param diff
+ * The diff we need to merge.
+ * @param rightToLeft
+ * Direction of that merge.
+ * @param monitor
+ * The monitor we should use to report progress.
+ */
+ protected void mergeDiff(Diff diff, boolean rightToLeft, Monitor monitor) {
+ if (rightToLeft) {
+ final IMerger delegate = getRegistry().getHighestRankingMerger(diff);
+ delegate.copyRightToLeft(diff, monitor);
+ } else {
+ final IMerger delegate = getRegistry().getHighestRankingMerger(diff);
+ delegate.copyLeftToRight(diff, monitor);
+ }
+ }
+
+ /**
+ * This will create a copy of the given EObject that can be used as the target of an addition (or the
+ * reverting of a deletion).
+ * <p>
+ * The target will be self-contained and will have no reference towards any other EObject set (neither
+ * containment nor "classic" references). All of its attributes' values will match the given
+ * {@code referenceObject}'s.
+ * </p>
+ *
+ * @param referenceObject
+ * The EObject for which we'll create a copy.
+ * @return A self-contained copy of {@code referenceObject}.
+ * @see EMFCompareCopier#copy(EObject)
+ */
+ protected EObject createCopy(EObject referenceObject) {
+ /*
+ * We can't simply use EcoreUtil.copy. References will have their own diffs and will thus be merged
+ * later on.
+ */
+ final EcoreUtil.Copier copier = new EMFCompareCopier();
+ return copier.copy(referenceObject);
+ }
+
+ /**
+ * Adds the given {@code value} into the given {@code list} at the given {@code index}. An {@code index}
+ * under than zero or above the list's size will mean that the value should be appended at the end of the
+ * list.
+ *
+ * @param list
+ * The list into which {@code value} should be added.
+ * @param value
+ * The value we need to add to {@code list}.
+ * @param <E>
+ * Type of objects contained in the list.
+ * @param insertionIndex
+ * The index at which {@code value} should be inserted into {@code list}. {@code -1} if it
+ * should be appended at the end of the list.
+ */
+ @SuppressWarnings("unchecked")
+ protected <E> void addAt(List<E> list, E value, int insertionIndex) {
+ if (list instanceof InternalEList<?>) {
+ if (insertionIndex < 0 || insertionIndex > list.size()) {
+ ((InternalEList<Object>)list).addUnique(value);
+ } else {
+ ((InternalEList<Object>)list).addUnique(insertionIndex, value);
+ }
+ } else {
+ if (insertionIndex < 0 || insertionIndex > list.size()) {
+ list.add(value);
+ } else {
+ list.add(insertionIndex, value);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AttributeChangeMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AttributeChangeMerger.java
new file mode 100644
index 000000000..b2911dd43
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/AttributeChangeMerger.java
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ * 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.merge;
+
+import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEGet;
+import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEIsSet;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.AttributeChange;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+/**
+ * This specific implementation of {@link AbstractMerger} will be used to merge attribute changes.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public class AttributeChangeMerger extends AbstractMerger {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
+ */
+ public boolean isMergerFor(Diff target) {
+ return target instanceof AttributeChange;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyLeftToRight(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final AttributeChange diff = (AttributeChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "requires" diffs
+ mergeRequires(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Create the same element in right
+ addInTarget(diff, false);
+ break;
+ case DELETE:
+ // Delete that same element from right
+ removeFromTarget(diff, false);
+ break;
+ case MOVE:
+ moveElement(diff, false);
+ break;
+ case CHANGE:
+ changeValue(diff, false);
+ break;
+ default:
+ break;
+ }
+ } else {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // We have a ADD on right. we need to revert this addition
+ removeFromTarget(diff, false);
+ break;
+ case DELETE:
+ // DELETE in the right. We need to re-create this element
+ addInTarget(diff, false);
+ break;
+ case MOVE:
+ moveElement(diff, false);
+ break;
+ case CHANGE:
+ changeValue(diff, false);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyRightToLeft(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final AttributeChange diff = (AttributeChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // We have a ADD on left, thus nothing in right. We need to revert the addition
+ removeFromTarget(diff, true);
+ break;
+ case DELETE:
+ // DELETE in the left, thus an element in right. We need to re-create that element
+ addInTarget(diff, true);
+ break;
+ case MOVE:
+ moveElement(diff, true);
+ break;
+ case CHANGE:
+ changeValue(diff, true);
+ break;
+ default:
+ break;
+ }
+ } else {
+ // merge all "requires" diffs
+ mergeRequires(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ addInTarget(diff, true);
+ break;
+ case DELETE:
+ removeFromTarget(diff, true);
+ break;
+ case MOVE:
+ moveElement(diff, true);
+ break;
+ case CHANGE:
+ changeValue(diff, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * This will be called when we need to create an element in the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * create an object in its side or add an objet to an attribute. In other words, either :
+ * <ul>
+ * <li>We are copying from right to left and
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to create the same object in the left), or</li>
+ * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
+ * </ul>
+ * </li>
+ * <li>We are copying from left to right and
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
+ * <li>we are copying an addition to the left side (we need to create the same object in the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void addInTarget(AttributeChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EObject expectedContainer;
+ if (rightToLeft) {
+ expectedContainer = match.getLeft();
+ } else {
+ expectedContainer = match.getRight();
+ }
+
+ if (expectedContainer == null) {
+ // FIXME throw exception? log? re-try to merge our requirements?
+ // one of the "required" diffs should have created our container.
+ } else {
+ final Comparison comparison = match.getComparison();
+ final EStructuralFeature attribute = diff.getAttribute();
+ final Object expectedValue = diff.getValue();
+ // We have the container, attribute and value. We need to know the insertion index.
+ if (attribute.isMany()) {
+ final int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);
+
+ final List<Object> targetList = (List<Object>)expectedContainer.eGet(attribute);
+ addAt(targetList, expectedValue, insertionIndex);
+ } else {
+ expectedContainer.eSet(attribute, expectedValue);
+ }
+ }
+ }
+
+ /**
+ * This will be called when we need to remove an element from the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * delete an object. In other words, we are :
+ * <ul>
+ * <li>Copying from right to left and either
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to remove the same object in the left) or,</li>
+ * <li>we are copying an addition to the left side (we need to revert the addition).</li>
+ * </ul>
+ * </li>
+ * <li>Copying from left to right and either
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
+ * <li>we are copying a deletion from the left side (we need to remove the same object in the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void removeFromTarget(AttributeChange diff, boolean rightToLeft) {
+ final EObject currentContainer;
+ if (rightToLeft) {
+ currentContainer = diff.getMatch().getLeft();
+ } else {
+ currentContainer = diff.getMatch().getRight();
+ }
+
+ if (currentContainer == null) {
+ // FIXME throw exception? log? re-try to merge our requirements?
+ } else {
+ final Object expectedValue = diff.getValue();
+ final EStructuralFeature attribute = diff.getAttribute();
+ // We have the container, attribute and value to remove.
+ if (attribute.isMany()) {
+ /*
+ * TODO if the same value appears twice, should we try and find the one that has actually been
+ * deleted? Will it happen that often? For now, remove the first occurence we find.
+ */
+ final List<Object> targetList = (List<Object>)currentContainer.eGet(attribute);
+ targetList.remove(expectedValue);
+ } else {
+ currentContainer.eUnset(attribute);
+ }
+ }
+ }
+
+ /**
+ * This will be called when trying to copy a "MOVE" diff.
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Whether we should move the value in the left or right side.
+ */
+ protected void moveElement(AttributeChange diff, boolean rightToLeft) {
+ final EObject expectedContainer;
+ if (rightToLeft) {
+ expectedContainer = diff.getMatch().getLeft();
+ } else {
+ expectedContainer = diff.getMatch().getRight();
+ }
+
+ if (expectedContainer == null) {
+ // TODO throws exception?
+ } else {
+ final Comparison comparison = diff.getMatch().getComparison();
+ final Object expectedValue = diff.getValue();
+
+ // We now know the target container, target attribute and target value.
+ doMove(diff, comparison, expectedContainer, expectedValue, rightToLeft);
+ }
+ }
+
+ /**
+ * This will do the actual work of moving the element into its attribute. All sanity checks were made in
+ * {@link #moveElement(boolean)} and no more verification will be made here.
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param comparison
+ * Comparison holding this Diff.
+ * @param expectedContainer
+ * The container in which we are reorganizing an attribute.
+ * @param expectedValue
+ * The value that is to be moved within its attribute.
+ * @param rightToLeft
+ * Whether we should move the value in the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void doMove(AttributeChange diff, Comparison comparison, EObject expectedContainer,
+ Object expectedValue, boolean rightToLeft) {
+ final EStructuralFeature attribute = diff.getAttribute();
+ if (attribute.isMany()) {
+ // Element to move cannot be part of the LCS... or there would not be a MOVE diff
+ int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);
+ /*
+ * However, it could still have been located "before" its new index, in which case we need to take
+ * it into account.
+ */
+ final List<Object> targetList = (List<Object>)expectedContainer.eGet(attribute);
+ final int currentIndex = targetList.indexOf(expectedValue);
+ if (insertionIndex > currentIndex) {
+ insertionIndex--;
+ }
+
+ if (targetList instanceof EList<?>) {
+ if (insertionIndex < 0 || insertionIndex > targetList.size()) {
+ ((EList<Object>)targetList).move(targetList.size() - 1, expectedValue);
+ } else {
+ ((EList<Object>)targetList).move(insertionIndex, expectedValue);
+ }
+ } else {
+ targetList.remove(expectedValue);
+ if (insertionIndex < 0 || insertionIndex > targetList.size()) {
+ targetList.add(expectedValue);
+ } else {
+ targetList.add(insertionIndex, expectedValue);
+ }
+ }
+ } else {
+ // This will never happen with the default diff engine, but may still be done from extenders
+ expectedContainer.eSet(attribute, expectedValue);
+ }
+ }
+
+ /**
+ * This will be called by the merge operations in order to reset an attribute to its original value, be
+ * that the left or right side.
+ * <p>
+ * Should never be called on multi-valued attributes.
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us the direction of this merge operation.
+ */
+ protected void resetInTarget(AttributeChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EStructuralFeature attribute = diff.getAttribute();
+ final EObject targetContainer;
+ if (rightToLeft) {
+ targetContainer = match.getLeft();
+ } else {
+ targetContainer = match.getRight();
+ }
+
+ final EObject originContainer;
+ if (match.getComparison().isThreeWay()) {
+ originContainer = match.getOrigin();
+ } else if (rightToLeft) {
+ originContainer = match.getRight();
+ } else {
+ originContainer = match.getLeft();
+ }
+
+ if (originContainer == null || !safeEIsSet(targetContainer, attribute)
+ || !safeEIsSet(originContainer, attribute)) {
+ targetContainer.eUnset(attribute);
+ } else {
+ final Object expectedValue = originContainer.eGet(attribute);
+ targetContainer.eSet(attribute, expectedValue);
+ }
+ }
+
+ /**
+ * This will be called by the merge operations in order to change single-valued attributes.
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Direction of the merge.
+ */
+ protected void changeValue(AttributeChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EStructuralFeature attribute = diff.getAttribute();
+ final EObject expectedContainer;
+ if (rightToLeft) {
+ expectedContainer = match.getLeft();
+ } else {
+ expectedContainer = match.getRight();
+ }
+
+ final EObject originContainer;
+ final boolean resetToOrigin = diff.getSource() == DifferenceSource.LEFT && rightToLeft
+ || diff.getSource() == DifferenceSource.RIGHT && !rightToLeft;
+ if (resetToOrigin && match.getComparison().isThreeWay()) {
+ originContainer = match.getOrigin();
+ } else if (rightToLeft) {
+ originContainer = match.getRight();
+ } else {
+ originContainer = match.getLeft();
+ }
+
+ final Object targetValue = safeEGet(originContainer, attribute);
+
+ // Though not the "default value", we consider that an empty string is an unset attribute.
+ final Object defaultValue = attribute.getDefaultValue();
+ boolean isUnset = targetValue == null || targetValue.equals(defaultValue)
+ || (defaultValue == null && "".equals(targetValue)); //$NON-NLS-1$
+
+ if (isUnset) {
+ expectedContainer.eUnset(attribute);
+ } else {
+ expectedContainer.eSet(attribute, targetValue);
+ }
+ }
+
+ /**
+ * This will be used by the distinct merge actions in order to find the index at which a value should be
+ * inserted in its target list. See {@link DiffUtil#findInsertionIndex(Comparison, Diff, boolean)} for
+ * more on this.
+ * <p>
+ * Sub-classes can override this if the insertion order is irrelevant. A return value of {@code -1} will
+ * be considered as "no index" and the value will be inserted at the end of its target list.
+ * </p>
+ *
+ * @param comparison
+ * This will be used in order to retrieve the Match for EObjects when comparing them.
+ * @param diff
+ * The diff which merging will trigger the need for an insertion index in its target list.
+ * @param rightToLeft
+ * {@code true} if the merging will be done into the left list, so that we should consider the
+ * right model as the source and the left as the target.
+ * @return The index at which this {@code diff}'s value should be inserted into the 'target' list, as
+ * inferred from {@code rightToLeft}. {@code -1} if the value should be inserted at the end of its
+ * target list.
+ * @see DiffUtil#findInsertionIndex(Comparison, Diff, boolean)
+ */
+ protected int findInsertionIndex(Comparison comparison, Diff diff, boolean rightToLeft) {
+ return DiffUtil.findInsertionIndex(comparison, diff, rightToLeft);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java
new file mode 100644
index 000000000..904983503
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/BatchMerger.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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.merge;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.alwaysTrue;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceState;
+
+/**
+ * This implementation of an {@link IBatchMerger} leaves some choice to the client as to what should be
+ * merged.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public class BatchMerger implements IBatchMerger {
+ /** The registry from which we'll retrieve our mergers. */
+ private final IMerger.Registry registry;
+
+ /** Filter the differences that should be merged. */
+ private final Predicate<? super Diff> filter;
+
+ /**
+ * Constructs our batch merger provided the registry from which to retrieve the delegate mergers. Using
+ * such a merger will merge every differences passed to its "copy" methods : conflictual or not.
+ *
+ * @param registry
+ * The registry from which we'll retrieve delegate mergers.
+ */
+ public BatchMerger(IMerger.Registry registry) {
+ this(registry, alwaysTrue());
+ }
+
+ /**
+ * Constructs our batch merger provided the registry from which to retrieve the delegate mergers, and a
+ * filter if you only wish to merge specific differences.
+ * <p>
+ * <b>Note</b> that the filter indicates differences that will be merged, not those that will be ignored.
+ * </p>
+ * <p>
+ * For example, if you wish to ignore all differences in conflict, you can use :
+ *
+ * <pre>
+ * IMerger.Registry registry = IMerger.RegistryImpl.createStandaloneInstance();
+ * IBatchMerger bathMerger = new BatchMerger(registry, {@link com.google.common.base.Predicates#not(Predicate) not}({@link org.eclipse.emf.compare.utils.EMFComparePredicates#hasConflict(org.eclipse.emf.compare.ConflictKind...) hasConflict}(ConflictKind.PSEUDO, ConflictKind.REAL)));
+ * bathMerger.copyAll...
+ * </pre>
+ *
+ * </p>
+ *
+ * @param registry
+ * The registry from which we'll retrieve delegate mergers.
+ * @param filter
+ * Additional filter for the differences. This could be set in order to ignore diffs
+ * originating from a given side. Note that the filter describes the differences that will be
+ * merged, not those that will be ignored.
+ * @see com.google.common.base.Predicates
+ * @see org.eclipse.emf.compare.utils.EMFComparePredicates
+ */
+ public BatchMerger(IMerger.Registry registry, Predicate<? super Diff> filter) {
+ this.registry = checkNotNull(registry);
+ this.filter = checkNotNull(filter);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IBatchMerger#copyAllLeftToRight(java.lang.Iterable,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyAllLeftToRight(Iterable<? extends Diff> differences, Monitor monitor) {
+ if (filter == alwaysTrue()) {
+ for (Diff diff : differences) {
+ if (diff.getState() != DifferenceState.MERGED) {
+ final IMerger merger = registry.getHighestRankingMerger(diff);
+ merger.copyLeftToRight(diff, monitor);
+ }
+ }
+ } else {
+ for (Diff diff : Iterables.filter(differences, filter)) {
+ if (diff.getState() != DifferenceState.MERGED) {
+ final IMerger merger = registry.getHighestRankingMerger(diff);
+ merger.copyLeftToRight(diff, monitor);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IBatchMerger#copyAllRightToLeft(java.lang.Iterable,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyAllRightToLeft(Iterable<? extends Diff> differences, Monitor monitor) {
+ if (filter == alwaysTrue()) {
+ for (Diff diff : differences) {
+ if (diff.getState() != DifferenceState.MERGED) {
+ final IMerger merger = registry.getHighestRankingMerger(diff);
+ merger.copyRightToLeft(diff, monitor);
+ }
+ }
+ } else {
+ for (Diff diff : Iterables.filter(differences, filter)) {
+ if (diff.getState() != DifferenceState.MERGED) {
+ final IMerger merger = registry.getHighestRankingMerger(diff);
+ merger.copyRightToLeft(diff, monitor);
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IBatchMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IBatchMerger.java
new file mode 100644
index 000000000..be9a02260
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IBatchMerger.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.merge;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+
+/**
+ * This interface describes the general contract of what EMF Compare expects in order to "copy all" diffs from
+ * a given Comparison or list.
+ * <p>
+ * Clients can either implement this interface or inherit from the default {@link BatchMerger}.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @since 3.0
+ */
+public interface IBatchMerger {
+ /**
+ * This will be called to copy all of the differences from the given list from the left to the right side.
+ *
+ * @param differences
+ * The differences that will be merged.
+ * @param monitor
+ * Monitor on which to report progress information.
+ */
+ void copyAllLeftToRight(Iterable<? extends Diff> differences, Monitor monitor);
+
+ /**
+ * This will be called to copy all of the differences from the given list from the right to the left side.
+ *
+ * @param differences
+ * The differences that will be merged.
+ * @param monitor
+ * Monitor on which to report progress information.
+ */
+ void copyAllRightToLeft(Iterable<? extends Diff> differences, Monitor monitor);
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IMerger.java
new file mode 100644
index 000000000..0bd2f3d4e
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/IMerger.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * 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.merge;
+
+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.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.EMFCompareMessages;
+
+/**
+ * Mergers are used by EMF Compare to merge specific differences from one side to the other. A number of
+ * default mergers are provided by EMF Compare, but they can be sub-classed and extended by clients through
+ * the extension point "org.eclipse.emf.compare.ide.mergerExtension".
+ * <p>
+ * Clients can either implement the whole merger contract or extend {@link AbstractMerger} instead.
+ * </p>
+ *
+ * @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
+ * @since 3.0
+ */
+public interface IMerger {
+ /**
+ * Check if the merger is a good candidate to merge the given difference.
+ *
+ * @param target
+ * The given target difference.
+ * @return True if it is the good candidate, false otherwise.
+ */
+ boolean isMergerFor(Diff target);
+
+ /**
+ * Returns the ranking of this merger.
+ *
+ * @return The ranking.
+ */
+ int getRanking();
+
+ /**
+ * Set the ranking of this merger.
+ *
+ * @param parseInt
+ * The ranking.
+ */
+ void setRanking(int parseInt);
+
+ /**
+ * Executes the copy from right to left.
+ *
+ * @param target
+ * The difference to handle.
+ * @param monitor
+ * Monitor.
+ */
+ void copyRightToLeft(Diff target, Monitor monitor);
+
+ /**
+ * Executes the copy from left to right.
+ *
+ * @param target
+ * The difference to handle.
+ * @param monitor
+ * Monitor.
+ */
+ void copyLeftToRight(Diff target, Monitor monitor);
+
+ /**
+ * Set the registry containing this merger.
+ *
+ * @param registry
+ * The merger registry.
+ */
+ void setRegistry(Registry registry);
+
+ /**
+ * Get the registry.
+ *
+ * @return The registry.
+ */
+ Registry getRegistry();
+
+ /**
+ * This will hold all registered mergers. Mergers can be registered manually in the registry, but they are
+ * usually registered through the "org.eclipse.emf.compare.ide.mergerExtension" extension point.
+ * <p>
+ * An instance of the registry is usually accessed through
+ * "EMFCompareIDEPlugin.getDefault().getMergerRegistry()". However, if you need an instance of the
+ * registry in a standalone environment, you should use "IMerger.RegistryImpl.createStandaloneInstance()"
+ * so that the default registrations are taken care of.
+ * </p>
+ */
+ public interface Registry {
+ /**
+ * Returns the merger, for the given target, owning the highest ranking.
+ *
+ * @param target
+ * The given target difference.
+ * @return The found merger.
+ */
+ IMerger getHighestRankingMerger(Diff target);
+
+ /**
+ * Returns the list of the candidate mergers for the given difference.
+ *
+ * @param target
+ * The given difference.
+ * @return The list of the found mergers.
+ */
+ Collection<IMerger> getMergers(Diff target);
+
+ /**
+ * Adds a merger to the registry.
+ *
+ * @param merger
+ * The merger.
+ * @return The previously registered merger.
+ */
+ IMerger add(IMerger merger);
+
+ /**
+ * Removes a merger from the registry, from its class name.
+ *
+ * @param className
+ * The class name.
+ * @return The previously registered merger.
+ */
+ IMerger remove(String className);
+
+ /**
+ * Clear the registry.
+ */
+ void clear();
+ }
+
+ /**
+ * A default implementation of an {@link IMerger.Registry}. This is the implementation EMF Compare will
+ * use through its GUI.
+ */
+ public class RegistryImpl implements Registry {
+
+ /**
+ * Map which references the registered mergers per their class name.
+ */
+ private final Map<String, IMerger> map;
+
+ /**
+ * Constructor.
+ */
+ public RegistryImpl() {
+ map = new ConcurrentHashMap<String, IMerger>();
+ }
+
+ /**
+ * Returns a registry filled with the default mergers provided by EMF Compare; namely
+ * {@link AttributeChangeMerger}, {@link ReferenceChangeMerger} and
+ * {@link ResourceAttachmentChangeMerger}.
+ *
+ * @return A registry filled with the default mergers provided by EMF Compare.
+ */
+ public static IMerger.Registry createStandaloneInstance() {
+ final IMerger.Registry registry = new RegistryImpl();
+
+ final IMerger attributeMerger = new AttributeChangeMerger();
+ attributeMerger.setRanking(10);
+ final IMerger referenceMerger = new ReferenceChangeMerger();
+ referenceMerger.setRanking(10);
+ final IMerger resourceAttachmentMerger = new ResourceAttachmentChangeMerger();
+ resourceAttachmentMerger.setRanking(10);
+
+ registry.add(attributeMerger);
+ registry.add(referenceMerger);
+ registry.add(resourceAttachmentMerger);
+
+ return registry;
+ }
+
+ /**
+ * Returns the predicate to check if the current merger is a good candidate to handle the given target
+ * difference.
+ *
+ * @param target
+ * The given difference.
+ * @return The predicate.
+ */
+ private static Predicate<IMerger> isMergerFor(final Diff target) {
+ return new Predicate<IMerger>() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see com.google.common.base.Predicate#apply(java.lang.Object)
+ */
+ public boolean apply(IMerger d) {
+ return d.isMergerFor(target);
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger.Registry#add(org.eclipse.emf.compare.merge.IMerger)
+ */
+ public IMerger add(IMerger merger) {
+ Preconditions.checkNotNull(merger);
+ merger.setRegistry(this);
+ return map.put(merger.getClass().getName(), merger);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger.Registry#remove(java.lang.String)
+ */
+ public IMerger remove(String className) {
+ IMerger previous = map.remove(className);
+ if (previous != null) {
+ previous.setRegistry(null);
+ }
+ return previous;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger.Registry#clear()
+ */
+ public void clear() {
+ map.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger.Registry#getHighestRankingMerger(org.eclipse.emf.compare.Diff)
+ */
+ public IMerger getHighestRankingMerger(Diff target) {
+ Iterator<IMerger> mergers = getMergers(target).iterator();
+
+ IMerger ret = null;
+
+ if (mergers.hasNext()) {
+ IMerger highestRanking = mergers.next();
+ while (mergers.hasNext()) {
+ IMerger merger = mergers.next();
+ if (merger.getRanking() > highestRanking.getRanking()) {
+ highestRanking = merger;
+ }
+ }
+ ret = highestRanking;
+ }
+
+ if (ret == null) {
+ throw new IllegalStateException(EMFCompareMessages.getString("IMerger.MissingMerger", target //$NON-NLS-1$
+ .getClass().getSimpleName()));
+ }
+
+ return ret;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger.Registry#getMergers(org.eclipse.emf.compare.Diff)
+ */
+ public Collection<IMerger> getMergers(Diff target) {
+ Iterable<IMerger> mergers = filter(map.values(), isMergerFor(target));
+ List<IMerger> ret = newArrayList();
+ for (IMerger merger : mergers) {
+ ret.add(merger);
+ }
+ return ret;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ReferenceChangeMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ReferenceChangeMerger.java
new file mode 100644
index 000000000..398c33963
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ReferenceChangeMerger.java
@@ -0,0 +1,714 @@
+/*******************************************************************************
+ * 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.merge;
+
+import static org.eclipse.emf.compare.utils.ReferenceUtil.safeEIsSet;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.ReferenceChange;
+import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.compare.utils.IEqualityHelper;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+
+/**
+ * This specific implementation of {@link AbstractMerger} will be used to merge reference changes.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public class ReferenceChangeMerger extends AbstractMerger {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
+ */
+ public boolean isMergerFor(Diff target) {
+ return target instanceof ReferenceChange;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyLeftToRight(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final ReferenceChange diff = (ReferenceChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ boolean continueMerge = handleEquivalences(diff, false, monitor);
+ if (!continueMerge) {
+ return;
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "requires" diffs
+ mergeRequires(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Create the same element in right
+ addInTarget(diff, false);
+ break;
+ case DELETE:
+ // Delete that same element from right
+ removeFromTarget(diff, false);
+ break;
+ case MOVE:
+ moveElement(diff, false);
+ break;
+ case CHANGE:
+ // Is it an unset?
+ if (diff.getMatch().getLeft() != null) {
+ final EObject leftValue = (EObject)diff.getMatch().getLeft().eGet(
+ diff.getReference(), false);
+ if (leftValue == null) {
+ removeFromTarget(diff, false);
+ } else {
+ addInTarget(diff, false);
+ }
+ } else {
+ // we have no left, and the source is on the left. Can only be an unset
+ removeFromTarget(diff, false);
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // We have a ADD on right. we need to revert this addition
+ removeFromTarget(diff, false);
+ break;
+ case DELETE:
+ // DELETE in the right. We need to re-create this element
+ addInTarget(diff, false);
+ break;
+ case MOVE:
+ moveElement(diff, false);
+ break;
+ case CHANGE:
+ // Is it an unset?
+ if (diff.getMatch().getRight() != null) {
+ final EObject rightValue = (EObject)diff.getMatch().getRight().eGet(
+ diff.getReference(), false);
+ if (rightValue == null) {
+ // Value has been unset in the right, and we are merging towards right.
+ // We need to re-add this element
+ addInTarget(diff, false);
+ } else {
+ // We'll actually need to "reset" this reference to its original value
+ resetInTarget(diff, false);
+ }
+ } else {
+ // we have no right, and the source is on the right. Can only be an unset
+ addInTarget(diff, false);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyRightToLeft(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final ReferenceChange diff = (ReferenceChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ boolean continueMerge = handleEquivalences(diff, true, monitor);
+ if (!continueMerge) {
+ return;
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // We have a ADD on left, thus nothing in right. We need to revert the addition
+ removeFromTarget(diff, true);
+ break;
+ case DELETE:
+ // DELETE in the left, thus an element in right. We need to re-create that element
+ addInTarget(diff, true);
+ break;
+ case MOVE:
+ moveElement(diff, true);
+ break;
+ case CHANGE:
+ // Is it an unset?
+ if (diff.getMatch().getLeft() != null) {
+ final EObject leftValue = (EObject)diff.getMatch().getLeft().eGet(
+ diff.getReference(), false);
+ if (leftValue == null) {
+ // Value has been unset in the right, and we are merging towards right.
+ // We need to re-add this element
+ addInTarget(diff, true);
+ } else {
+ // We'll actually need to "reset" this reference to its original value
+ resetInTarget(diff, true);
+ }
+ } else {
+ // we have no left, and the source is on the left. Can only be an unset
+ addInTarget(diff, true);
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ // merge all "requires" diffs
+ mergeRequires(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ addInTarget(diff, true);
+ break;
+ case DELETE:
+ removeFromTarget(diff, true);
+ break;
+ case MOVE:
+ moveElement(diff, true);
+ break;
+ case CHANGE:
+ // Is it an unset?
+ if (diff.getMatch().getRight() != null) {
+ final EObject rightValue = (EObject)diff.getMatch().getRight().eGet(
+ diff.getReference(), false);
+ if (rightValue == null) {
+ removeFromTarget(diff, true);
+ } else {
+ addInTarget(diff, true);
+ }
+ } else {
+ // we have no right, and the source is on the right. Can only be an unset
+ removeFromTarget(diff, true);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * This will be called when trying to copy a "MOVE" diff.
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Whether we should move the value in the left or right side.
+ */
+ protected void moveElement(ReferenceChange diff, boolean rightToLeft) {
+ final Comparison comparison = diff.getMatch().getComparison();
+ final Match valueMatch = comparison.getMatch(diff.getValue());
+ final EReference reference = diff.getReference();
+
+ final EObject expectedContainer;
+ if (reference.isContainment()) {
+ /*
+ * We cannot "trust" the holding match (getMatch) in this case. However, "valueMatch" cannot be
+ * null : we cannot have detected a move if the moved element is not matched on both sides. Use
+ * that information to retrieve the proper "target" container.
+ */
+ final Match targetContainerMatch;
+ // If it exists, use the source side's container as reference
+ if (rightToLeft && valueMatch.getRight() != null) {
+ targetContainerMatch = comparison.getMatch(valueMatch.getRight().eContainer());
+ } else if (!rightToLeft && valueMatch.getLeft() != null) {
+ targetContainerMatch = comparison.getMatch(valueMatch.getLeft().eContainer());
+ } else {
+ // Otherwise, the value we're moving on one side has been removed from its source side.
+ targetContainerMatch = comparison.getMatch(valueMatch.getOrigin().eContainer());
+ }
+ if (rightToLeft) {
+ expectedContainer = targetContainerMatch.getLeft();
+ } else {
+ expectedContainer = targetContainerMatch.getRight();
+ }
+ } else if (rightToLeft) {
+ expectedContainer = diff.getMatch().getLeft();
+ } else {
+ expectedContainer = diff.getMatch().getRight();
+ }
+ if (expectedContainer == null) {
+ // FIXME throw exception? log? re-try to merge our requirements?
+ // one of the "required" diffs should have created our container.
+ return;
+ }
+
+ final EObject expectedValue;
+ if (valueMatch == null) {
+ // The value being moved is out of the scope
+ /*
+ * Note : there should not be a way to end up with a "move" for an out of scope value : a move can
+ * only be detected if the object is matched on both sides, otherwise all we can see is "add" and
+ * "delete"... Is this "fallback" code even reachable? If so, how?
+ */
+ // We need to look it up
+ if (reference.isMany()) {
+ @SuppressWarnings("unchecked")
+ final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(reference);
+ expectedValue = findMatchIn(comparison, targetList, diff.getValue());
+ } else {
+ expectedValue = (EObject)expectedContainer.eGet(reference);
+ }
+ } else {
+ if (rightToLeft) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+ }
+ // We now know the target container, target reference and target value.
+ doMove(diff, comparison, expectedContainer, expectedValue, rightToLeft);
+ }
+
+ /**
+ * This will do the actual work of moving the element into its reference. All sanity checks were made in
+ * {@link #moveElement(boolean)} and no more verification will be made here.
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param comparison
+ * Comparison holding this Diff.
+ * @param expectedContainer
+ * The container in which we are reorganizing a reference.
+ * @param expectedValue
+ * The value that is to be moved within its reference.
+ * @param rightToLeft
+ * Whether we should move the value in the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void doMove(ReferenceChange diff, Comparison comparison, EObject expectedContainer,
+ EObject expectedValue, boolean rightToLeft) {
+ final EReference reference = diff.getReference();
+ if (reference.isMany()) {
+ // Element to move cannot be part of the LCS... or there would not be a MOVE diff
+ int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);
+
+ /*
+ * However, it could still have been located "before" its new index, in which case we need to take
+ * it into account.
+ */
+ final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(reference);
+ final int currentIndex = targetList.indexOf(expectedValue);
+ if (insertionIndex > currentIndex && currentIndex >= 0) {
+ insertionIndex--;
+ }
+
+ if (currentIndex == -1) {
+ // happens for container changes for example.
+ if (!reference.isContainment()) {
+ targetList.remove(expectedValue);
+ }
+ if (insertionIndex < 0 && insertionIndex > targetList.size()) {
+ targetList.add(expectedValue);
+ } else {
+ targetList.add(insertionIndex, expectedValue);
+ }
+ } else if (targetList instanceof EList<?>) {
+ if (insertionIndex < 0 && insertionIndex > targetList.size()) {
+ ((EList<EObject>)targetList).move(targetList.size() - 1, expectedValue);
+ } else {
+ ((EList<EObject>)targetList).move(insertionIndex, expectedValue);
+ }
+ } else {
+ targetList.remove(expectedValue);
+ if (insertionIndex < 0 && insertionIndex > targetList.size()) {
+ targetList.add(expectedValue);
+ } else {
+ targetList.add(insertionIndex, expectedValue);
+ }
+ }
+ } else {
+ expectedContainer.eSet(reference, expectedValue);
+ }
+ }
+
+ /**
+ * This will be called when we need to create an element in the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * create an object in its side or add an objet to a reference. In other words, either :
+ * <ul>
+ * <li>We are copying from right to left and
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to create the same object in the left), or</li>
+ * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
+ * </ul>
+ * </li>
+ * <li>We are copying from left to right and
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
+ * <li>we are copying an addition to the left side (we need to create the same object in the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void addInTarget(ReferenceChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EObject expectedContainer;
+ if (rightToLeft) {
+ expectedContainer = match.getLeft();
+ } else {
+ expectedContainer = match.getRight();
+ }
+
+ if (expectedContainer == null) {
+ // FIXME throw exception? log? re-try to merge our requirements?
+ // one of the "required" diffs should have created our container.
+ return;
+ }
+
+ final Comparison comparison = match.getComparison();
+ final EReference reference = diff.getReference();
+ final EObject expectedValue;
+ final Match valueMatch = comparison.getMatch(diff.getValue());
+ if (valueMatch == null) {
+ // This is an out of scope value.
+ if (diff.getValue().eIsProxy()) {
+ // Copy the proxy
+ expectedValue = EcoreUtil.copy(diff.getValue());
+ } else {
+ // Use the same value.
+ expectedValue = diff.getValue();
+ }
+ } else if (rightToLeft) {
+ if (reference.isContainment()) {
+ expectedValue = createCopy(diff.getValue());
+ valueMatch.setLeft(expectedValue);
+ } else {
+ expectedValue = valueMatch.getLeft();
+ }
+ } else {
+ if (reference.isContainment()) {
+ expectedValue = createCopy(diff.getValue());
+ valueMatch.setRight(expectedValue);
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+ }
+
+ // We have the container, reference and value. We need to know the insertion index.
+ if (reference.isMany()) {
+ final int insertionIndex = findInsertionIndex(comparison, diff, rightToLeft);
+
+ final List<EObject> targetList = (List<EObject>)expectedContainer.eGet(reference);
+ addAt(targetList, expectedValue, insertionIndex);
+ } else {
+ expectedContainer.eSet(reference, expectedValue);
+ }
+
+ if (reference.isContainment()) {
+ // Copy XMI ID when applicable.
+ final Resource initialResource = diff.getValue().eResource();
+ final Resource targetResource = expectedValue.eResource();
+ if (initialResource instanceof XMIResource && targetResource instanceof XMIResource) {
+ ((XMIResource)targetResource).setID(expectedValue, ((XMIResource)initialResource).getID(diff
+ .getValue()));
+ }
+ }
+ }
+
+ /**
+ * This will be called when we need to remove an element from the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * delete an object. In other words, we are :
+ * <ul>
+ * <li>Copying from right to left and either
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to remove the same object in the left) or,</li>
+ * <li>we are copying an addition to the left side (we need to revert the addition).</li>
+ * </ul>
+ * </li>
+ * <li>Copying from left to right and either
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
+ * <li>we are copying a deletion from the left side (we need to remove the same object in the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ @SuppressWarnings("unchecked")
+ protected void removeFromTarget(ReferenceChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EReference reference = diff.getReference();
+ final EObject currentContainer;
+ if (rightToLeft) {
+ currentContainer = match.getLeft();
+ } else {
+ currentContainer = match.getRight();
+ }
+ final Comparison comparison = match.getComparison();
+ final Match valueMatch = comparison.getMatch(diff.getValue());
+
+ if (currentContainer == null) {
+ // FIXME throw exception? log? re-try to merge our requirements?
+ // one of the "required" diffs should have created our container.
+ return;
+ }
+
+ final EObject expectedValue;
+ if (valueMatch == null) {
+ // value is out of the scope... we need to look it up
+ if (reference.isMany()) {
+ final List<EObject> targetList = (List<EObject>)currentContainer.eGet(reference);
+ expectedValue = findMatchIn(comparison, targetList, diff.getValue());
+ } else {
+ // the value will not be needed anyway
+ expectedValue = null;
+ }
+ } else if (rightToLeft) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+
+ // We have the container, reference and value to remove. Expected value can be null when the
+ // deletion was made on both side (i.e. a pseudo delete)
+ if (reference.isContainment() && expectedValue != null) {
+ EcoreUtil.remove(expectedValue);
+ if (rightToLeft && valueMatch != null) {
+ valueMatch.setLeft(null);
+ } else if (valueMatch != null) {
+ valueMatch.setRight(null);
+ }
+ // TODO remove dangling? remove empty Match?
+ } else if (reference.isMany()) {
+ /*
+ * TODO if the same value appears twice, should we try and find the one that has actually been
+ * deleted? Can it happen? For now, remove the first occurence we find.
+ */
+ final List<EObject> targetList = (List<EObject>)currentContainer.eGet(reference);
+ targetList.remove(expectedValue);
+ } else {
+ currentContainer.eUnset(reference);
+ }
+ }
+
+ /**
+ * This will be called by the merge operations in order to reset a reference to its original value, be
+ * that the left or right side.
+ * <p>
+ * Should never be called on multi-valued references.
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Tells us the direction of this merge operation.
+ */
+ protected void resetInTarget(ReferenceChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final EReference reference = diff.getReference();
+ final EObject targetContainer;
+ if (rightToLeft) {
+ targetContainer = match.getLeft();
+ } else {
+ targetContainer = match.getRight();
+ }
+
+ final EObject originContainer;
+ if (match.getComparison().isThreeWay()) {
+ originContainer = match.getOrigin();
+ } else if (rightToLeft) {
+ originContainer = match.getRight();
+ } else {
+ originContainer = match.getLeft();
+ }
+
+ if (originContainer == null || !safeEIsSet(targetContainer, reference)
+ || !safeEIsSet(originContainer, reference)) {
+ targetContainer.eUnset(reference);
+ } else {
+ final EObject originalValue = (EObject)originContainer.eGet(reference);
+ final Match valueMatch = match.getComparison().getMatch(originalValue);
+ final EObject expectedValue;
+ if (valueMatch == null) {
+ // Value is out of the scope, use it as-is
+ expectedValue = originalValue;
+ } else if (rightToLeft) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+ targetContainer.eSet(reference, expectedValue);
+ }
+ }
+
+ /**
+ * Handles the equivalences of this difference.
+ * <p>
+ * Note that in certain cases, we'll merge our opposite instead of merging this diff. Specifically, we'll
+ * do that for one-to-many eOpposites : we'll merge the 'many' side instead of the 'unique' one. This
+ * allows us not to worry about the order of the references on that 'many' side.
+ * </p>
+ * <p>
+ * This is called before the merge of <code>this</code>. In short, if this returns <code>false</code>, we
+ * won't carry on merging <code>this</code> after returning.
+ * </p>
+ *
+ * @param diff
+ * The diff we are currently merging.
+ * @param rightToLeft
+ * Direction of the merge.
+ * @param monitor
+ * The monitor to use in order to report progress information.
+ * @return <code>true</code> if the current difference should still be merged after handling its
+ * equivalences, <code>false</code> if it should be considered "already merged".
+ */
+ protected boolean handleEquivalences(ReferenceChange diff, boolean rightToLeft, Monitor monitor) {
+ final EReference reference = diff.getReference();
+ boolean continueMerge = true;
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ if (equivalent instanceof ReferenceChange
+ && reference.getEOpposite() == ((ReferenceChange)equivalent).getReference()
+ && equivalent.getState() == DifferenceState.UNRESOLVED) {
+ // This equivalence is on our eOpposite. Should we merge it instead of 'this'?
+ final boolean mergeEquivalence = !reference.isMany()
+ && ((ReferenceChange)equivalent).getReference().isMany();
+ if (mergeEquivalence) {
+ mergeDiff(equivalent, rightToLeft, monitor);
+ continueMerge = false;
+ }
+ } else if (diff.getSource() == DifferenceSource.LEFT) {
+ // This can happen when merging subset/supersets... see AddInterfaceTest#testA50UseCase
+ /*
+ * This should be removed (or we should make sure that we can never be here) when bug 398402
+ * is fixed.
+ */
+ if (rightToLeft && diff.getRequiredBy().contains(equivalent)) {
+ mergeDiff(equivalent, rightToLeft, monitor);
+ continueMerge = false;
+ } else if (!rightToLeft && diff.getRequires().contains(equivalent)) {
+ mergeDiff(equivalent, rightToLeft, monitor);
+ continueMerge = false;
+ }
+ } else if (diff.getSource() == DifferenceSource.RIGHT) {
+ // This can happen when merging subset/supersets... see AddInterfaceTest#testA50UseCase
+ /*
+ * This should be removed (or we should make sure that we can never be here) when bug 398402
+ * is fixed.
+ */
+ if (rightToLeft && diff.getRequires().contains(equivalent)) {
+ mergeDiff(equivalent, rightToLeft, monitor);
+ continueMerge = false;
+ } else if (!rightToLeft && diff.getRequiredBy().contains(equivalent)) {
+ mergeDiff(equivalent, rightToLeft, monitor);
+ continueMerge = false;
+ }
+ }
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ return continueMerge;
+ }
+
+ /**
+ * Seeks a match of the given {@code element} in the given list, using the equality helper to find it.
+ * This is only used when moving or deleting proxies for now.
+ *
+ * @param comparison
+ * The comparison which Diff we are currently merging.
+ * @param list
+ * The list from which we seek a value.
+ * @param element
+ * The value for which we need a match in {@code list}.
+ * @return The match of {@code element} in {@code list}, {@code null} if none.
+ */
+ protected EObject findMatchIn(Comparison comparison, List<EObject> list, EObject element) {
+ final IEqualityHelper helper = comparison.getEqualityHelper();
+ final Iterator<EObject> it = list.iterator();
+ while (it.hasNext()) {
+ final EObject next = it.next();
+ if (helper.matchingValues(next, element)) {
+ return next;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This will be used by the distinct merge actions in order to find the index at which a value should be
+ * inserted in its target list. See {@link DiffUtil#findInsertionIndex(Comparison, Diff, boolean)} for
+ * more on this.
+ * <p>
+ * Sub-classes can override this if the insertion order is irrelevant. A return value of {@code -1} will
+ * be considered as "no index" and the value will be inserted at the end of its target list.
+ * </p>
+ *
+ * @param comparison
+ * This will be used in order to retrieve the Match for EObjects when comparing them.
+ * @param diff
+ * The diff which merging will trigger the need for an insertion index in its target list.
+ * @param rightToLeft
+ * {@code true} if the merging will be done into the left list, so that we should consider the
+ * right model as the source and the left as the target.
+ * @return The index at which this {@code diff}'s value should be inserted into the 'target' list, as
+ * inferred from {@code rightToLeft}. {@code -1} if the value should be inserted at the end of its
+ * target list.
+ * @see DiffUtil#findInsertionIndex(Comparison, Diff, boolean)
+ */
+ protected int findInsertionIndex(Comparison comparison, Diff diff, boolean rightToLeft) {
+ return DiffUtil.findInsertionIndex(comparison, diff, rightToLeft);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ResourceAttachmentChangeMerger.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ResourceAttachmentChangeMerger.java
new file mode 100644
index 000000000..b46d70e67
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/merge/ResourceAttachmentChangeMerger.java
@@ -0,0 +1,475 @@
+/*******************************************************************************
+ * 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.merge;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.EMFCompareMessages;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.MatchResource;
+import org.eclipse.emf.compare.ResourceAttachmentChange;
+import org.eclipse.emf.compare.utils.DiffUtil;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+
+/**
+ * This specific implementation of {@link AbstractMerger} will be used to merge resource attachment changes.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public class ResourceAttachmentChangeMerger extends AbstractMerger {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#isMergerFor(org.eclipse.emf.compare.Diff)
+ */
+ public boolean isMergerFor(Diff target) {
+ return target instanceof ResourceAttachmentChange;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyLeftToRight(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyLeftToRight(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final ResourceAttachmentChange diff = (ResourceAttachmentChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "requires" diffs
+ mergeRequires(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Create the same root in right
+ addInTarget(diff, false);
+ break;
+ case DELETE:
+ // Delete that same root from right
+ removeFromTarget(diff, false);
+ break;
+ default:
+ // other cases are unknown at the time of writing
+ break;
+ }
+ } else {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, false, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Revert the addition of this root
+ removeFromTarget(diff, false);
+ break;
+ case DELETE:
+ // re-create this element
+ addInTarget(diff, false);
+ break;
+ default:
+ // other cases are unknown at the time of writing
+ break;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.merge.IMerger#copyRightToLeft(org.eclipse.emf.compare.Diff,
+ * org.eclipse.emf.common.util.Monitor)
+ */
+ public void copyRightToLeft(Diff target, Monitor monitor) {
+ // Don't merge an already merged (or discarded) diff
+ if (target.getState() != DifferenceState.UNRESOLVED) {
+ return;
+ }
+ final ResourceAttachmentChange diff = (ResourceAttachmentChange)target;
+
+ // Change the diff's state before we actually merge it : this allows us to avoid requirement cycles.
+ diff.setState(DifferenceState.MERGED);
+ if (diff.getEquivalence() != null) {
+ for (Diff equivalent : diff.getEquivalence().getDifferences()) {
+ equivalent.setState(DifferenceState.MERGED);
+ }
+ }
+
+ if (diff.getSource() == DifferenceSource.LEFT) {
+ // merge all "required by" diffs
+ mergeRequiredBy(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Revert the addition of this root
+ removeFromTarget(diff, true);
+ break;
+ case DELETE:
+ // re-create this element
+ addInTarget(diff, true);
+ break;
+ default:
+ // other cases are unknown at the time of writing
+ break;
+ }
+ } else {
+ // merge all "requires" diffs
+ mergeRequires(diff, true, monitor);
+
+ switch (diff.getKind()) {
+ case ADD:
+ // Create the same root in left
+ addInTarget(diff, true);
+ break;
+ case DELETE:
+ // Delete that same root from left
+ removeFromTarget(diff, true);
+ break;
+ default:
+ // other cases are unknown at the time of writing
+ break;
+ }
+ }
+ }
+
+ /**
+ * This will be called when we need to create an element in the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * create an object in its side. In other words, either :
+ * <ul>
+ * <li>We are copying from right to left and
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to create the same root in the left), or</li>
+ * <li>we are copying a deletion from the left side (we need to revert the deletion).</li>
+ * </ul>
+ * </li>
+ * <li>We are copying from left to right and
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to revert the deletion), or</li>
+ * <li>we are copying an addition to the left side (we need to create the same root in the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The difference we are to merge.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ protected void addInTarget(ResourceAttachmentChange diff, boolean rightToLeft) {
+ final Match match = diff.getMatch();
+ final Comparison comparison = match.getComparison();
+ final Resource expectedContainer = findOrCreateTargetResource(match, rightToLeft);
+
+ final EObject sourceValue;
+ if (rightToLeft) {
+ sourceValue = match.getRight();
+ } else {
+ sourceValue = match.getLeft();
+ }
+
+ final EObject expectedValue;
+ if (rightToLeft) {
+ if (match.getLeft() != null) {
+ expectedValue = match.getLeft();
+ } else {
+ expectedValue = createCopy(sourceValue);
+ match.setLeft(expectedValue);
+ }
+ } else if (match.getRight() != null) {
+ expectedValue = match.getRight();
+ } else {
+ expectedValue = createCopy(sourceValue);
+ match.setRight(expectedValue);
+ }
+
+ // double-check : is our target already present in the target resource?
+ final URI sourceURI = EcoreUtil.getURI(sourceValue);
+ if (expectedContainer.getEObject(sourceURI.fragment()) != null) {
+ /*
+ * The only way for this use case to kick in is if we have both (or "all three") compared models
+ * side-by-side during a local comparison. In such an event, the "new" resource can only be an
+ * existing one (since relative paths will always resolve to the same location whatever the side),
+ * and it will obviously already contain the object since we detected the resource change. In such
+ * a case, we do not want to erase the already existing object or copy a duplicate in the target
+ * resource. We'll simply change the "to-be-modified" object to point to that already existing one
+ * through proxification and re-resolution. This is costly and clumsy, but this use case should be
+ * sufficiently rare to not be noticed, we only want it to be functional.
+ */
+ ((InternalEObject)expectedValue).eSetProxyURI(sourceURI);
+ if (expectedContainer.getResourceSet() != null) {
+ EcoreUtil.resolveAll(expectedContainer.getResourceSet());
+ } else {
+ EcoreUtil.resolveAll(expectedContainer);
+ }
+ if (rightToLeft) {
+ match.setLeft(expectedContainer.getEObject(sourceURI.fragment()));
+ } else {
+ match.setRight(expectedContainer.getEObject(sourceURI.fragment()));
+ }
+ return;
+ }
+
+ // We have the container, reference and value. We need to know the insertion index.
+ final Resource initialResource = sourceValue.eResource();
+ final List<EObject> sourceList = initialResource.getContents();
+ final List<EObject> targetList = expectedContainer.getContents();
+ final int insertionIndex = findInsertionIndex(comparison, sourceList, targetList, expectedValue);
+ addAt(targetList, expectedValue, insertionIndex);
+
+ // Copy XMI ID when applicable.
+ if (initialResource instanceof XMIResource && expectedContainer instanceof XMIResource) {
+ ((XMIResource)expectedContainer).setID(expectedValue, ((XMIResource)initialResource)
+ .getID(sourceValue));
+ }
+ }
+
+ /**
+ * This will try and locate the "target" resource of this merge in the current comparison. If we can't
+ * locate it, we assume that it needs to be created as we are in the process of adding a new element to
+ * it.
+ *
+ * @param match
+ * Match of the root which resource we need to find or create.
+ * @param rightToLeft
+ * Direction of the merge. This will tell us which side we are to look up for the target
+ * resource.
+ * @return The resource we could find in the current comparison if any. Otherwise, we'll return either a
+ * newly created resource that can serve as a target of this merge, or <code>null</code> if no
+ * valid target resource can be created.
+ */
+ protected Resource findOrCreateTargetResource(Match match, boolean rightToLeft) {
+ final Comparison comparison = match.getComparison();
+ final Resource sourceRes;
+ if (rightToLeft) {
+ sourceRes = match.getRight().eResource();
+ } else {
+ sourceRes = match.getLeft().eResource();
+ }
+
+ final MatchResource soughtMatch = getMatchResource(comparison, sourceRes);
+
+ // Is the resource already existing or do we need to create it?
+ final Resource target;
+ if (rightToLeft && soughtMatch.getLeft() != null) {
+ target = soughtMatch.getLeft();
+ } else if (!rightToLeft && soughtMatch.getRight() != null) {
+ target = soughtMatch.getRight();
+ } else {
+ // we need to create it.
+ final URI targetURI = computeTargetURI(match, rightToLeft);
+ // FIXME this will most likely fail with remote URIs : we'll need to make it local afterwards
+ if (targetURI == null) {
+ // We treat null as "no valid target". We'll cancel the merge operation.
+ return null;
+ }
+
+ final List<MatchResource> matchedResources = comparison.getMatchedResources();
+ final int size = matchedResources.size();
+ ResourceSet targetSet = null;
+ for (int i = 0; i < size && targetSet == null; i++) {
+ final MatchResource matchRes = matchedResources.get(i);
+ if (rightToLeft && matchRes.getLeft() != null) {
+ targetSet = matchRes.getLeft().getResourceSet();
+ } else if (!rightToLeft && matchRes.getRight() != null) {
+ targetSet = matchRes.getRight().getResourceSet();
+ }
+ }
+
+ if (targetSet == null) {
+ // Cannot create the target
+ throw new RuntimeException(EMFCompareMessages.getString(
+ "ResourceAttachmentChangeSpec.MissingRS", targetURI.lastSegment())); //$NON-NLS-1$
+ }
+
+ // This resource might already exists
+ if (targetSet.getURIConverter().exists(targetURI, Collections.emptyMap())) {
+ target = targetSet.getResource(targetURI, true);
+ } else {
+ target = targetSet.createResource(targetURI);
+ }
+
+ if (rightToLeft) {
+ soughtMatch.setLeft(target);
+ } else {
+ soughtMatch.setRight(target);
+ }
+
+ }
+
+ return target;
+ }
+
+ /**
+ * Computes the URI of the "target" resource. Will be used if we need to create or "find" it.
+ *
+ * @param match
+ * Match of the root for which we need a resource URI.
+ * @param rightToLeft
+ * Direction of the merge.
+ * @return The URI that is to be used for our target resource. <code>null</code> if we cannot compute a
+ * valid target URI.
+ */
+ protected URI computeTargetURI(Match match, boolean rightToLeft) {
+ final EObject sourceObject;
+ final EObject targetObject;
+ if (rightToLeft) {
+ sourceObject = match.getRight();
+ targetObject = match.getLeft();
+ } else {
+ sourceObject = match.getLeft();
+ targetObject = match.getRight();
+ }
+ final Resource sourceResource = sourceObject.eResource();
+ // This is the resource that will change through this merge.
+ // We will only use it to determine a relative path for the real target resource.
+ final Resource currentResource = targetObject.eResource();
+
+ final MatchResource matchCurrent = getMatchResource(match.getComparison(), currentResource);
+ final Resource currentFromSourceSide;
+ if (rightToLeft) {
+ currentFromSourceSide = matchCurrent.getRight();
+ } else {
+ currentFromSourceSide = matchCurrent.getLeft();
+ }
+
+ // Case of control/uncontrol
+ final URI relativeTargetURI = sourceResource.getURI().deresolve(currentFromSourceSide.getURI());
+
+ return relativeTargetURI.resolve(currentResource.getURI());
+ }
+
+ /**
+ * Returns the MatchResource corresponding to the given <code>resource</code>.
+ *
+ * @param comparison
+ * The current comparison.
+ * @param resource
+ * Resource for which we need a MatchResource.
+ * @return The MatchResource corresponding to the given <code>resource</code>.
+ */
+ protected MatchResource getMatchResource(Comparison comparison, Resource resource) {
+ final List<MatchResource> matchedResources = comparison.getMatchedResources();
+ final int size = matchedResources.size();
+ MatchResource soughtMatch = null;
+ for (int i = 0; i < size && soughtMatch == null; i++) {
+ final MatchResource matchRes = matchedResources.get(i);
+ if (matchRes.getRight() == resource || matchRes.getLeft() == resource
+ || matchRes.getOrigin() == resource) {
+ soughtMatch = matchRes;
+ }
+ }
+
+ if (soughtMatch == null) {
+ // This should never happen
+ throw new RuntimeException(EMFCompareMessages.getString(
+ "ResourceAttachmentChangeSpec.MissingMatch", resource.getURI().lastSegment())); //$NON-NLS-1$
+ }
+
+ return soughtMatch;
+ }
+
+ /**
+ * This will be called when we need to remove an element from the target side.
+ * <p>
+ * All necessary sanity checks have been made to ensure that the current operation is one that should
+ * delete an object. In other words, we are :
+ * <ul>
+ * <li>Copying from right to left and either
+ * <ul>
+ * <li>we are copying a deletion from the right side (we need to remove the same root from the left) or,</li>
+ * <li>we are copying an addition to the left side (we need to revert the addition).</li>
+ * </ul>
+ * </li>
+ * <li>Copying from left to right and either
+ * <ul>
+ * <li>we are copying an addition to the right side (we need to revert the addition), or.</li>
+ * <li>we are copying a deletion from the left side (we need to remove the same root from the right).</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param diff
+ * The difference we are to merge.
+ * @param rightToLeft
+ * Tells us whether we are to add an object on the left or right side.
+ */
+ protected void removeFromTarget(ResourceAttachmentChange diff, boolean rightToLeft) {
+ final Match valueMatch = diff.getMatch();
+ final EObject expectedValue;
+ if (rightToLeft) {
+ expectedValue = valueMatch.getLeft();
+ } else {
+ expectedValue = valueMatch.getRight();
+ }
+
+ // if this is a pseudo conflict, we have no value to remove
+ if (expectedValue != null) {
+ // We only wish to remove the element from its containing resource, not from its container.
+ // This will not affect the match.
+ final Resource resource = ((InternalEObject)expectedValue).eDirectResource();
+ resource.getContents().remove(expectedValue);
+ }
+ }
+
+ /**
+ * This will be used by the distinct merge actions in order to find the index at which a value should be
+ * inserted in its target list. See {@link DiffUtil#findInsertionIndex(Comparison, Diff, boolean)} for
+ * more on this.
+ * <p>
+ * Sub-classes can override this if the insertion order is irrelevant. A return value of {@code -1} will
+ * be considered as "no index" and the value will be inserted at the end of its target list.
+ * </p>
+ *
+ * @param comparison
+ * This will be used in order to retrieve the Match for EObjects when comparing them.
+ * @param source
+ * The List from which one element has to be added to the {@code target} list.
+ * @param target
+ * The List into which one element from {@code source} has to be added.
+ * @param newElement
+ * The element from {@code source} that needs to be added into {@code target}.
+ * @param <E>
+ * Type of the sequences content.
+ * @return The index at which the new value should be inserted into the 'target' list, as inferred from
+ * its position in {@code source}. {@code -1} if the value should be inserted at the end of its
+ * target list.
+ * @see DiffUtil#findInsertionIndex(Comparison, Diff, boolean)
+ */
+ protected <E> int findInsertionIndex(Comparison comparison, List<E> source, List<E> target, E newElement) {
+ return DiffUtil.findInsertionIndex(comparison, source, target, newElement);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/DiffUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/DiffUtil.java
index 97ee7a991..0b29d1f53 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/DiffUtil.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/DiffUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012 Obeo.
+ * 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
@@ -141,16 +141,25 @@ public final class DiffUtil {
*/
public static <E> List<E> longestCommonSubsequence(Comparison comparison, Iterable<E> ignoredElements,
List<E> sequence1, List<E> sequence2) {
+ // FIXME : merge the two "LCS" methods in one (only one line differs...)
+ final List<E> copy1 = Lists.newArrayList(sequence1);
+ final List<E> copy2 = Lists.newArrayList(sequence2);
+
+ // Reduce sets
+ final List<E> prefix = trimPrefix(comparison, ignoredElements, copy1, copy2);
+ final List<E> suffix = trimSuffix(comparison, ignoredElements, copy1, copy2);
+
final IEqualityHelper equalityHelper = comparison.getEqualityHelper();
- final int size1 = sequence1.size();
- final int size2 = sequence2.size();
+ final int size1 = copy1.size();
+ final int size2 = copy2.size();
+
final int[][] matrix = new int[size1 + 1][size2 + 1];
// Compute the LCS matrix
for (int i = 1; i <= size1; i++) {
+ final E first = copy1.get(i - 1);
for (int j = 1; j <= size2; j++) {
- final E first = sequence1.get(i - 1);
- final E second = sequence2.get(j - 1);
+ final E second = copy2.get(j - 1);
if (equalityHelper.matchingValues(first, second)
&& !contains(comparison, equalityHelper, ignoredElements, second)) {
matrix[i][j] = 1 + matrix[i - 1][j - 1];
@@ -160,38 +169,151 @@ public final class DiffUtil {
}
}
- // Shortcut evaluation if the lcs is the whole sequence
- final boolean lcsIs1 = matrix[size1][size2] == size1;
- final boolean lcsIs2 = matrix[size1][size2] == size2;
- if (lcsIs1 || lcsIs2) {
- final List<E> shortcut;
- if (lcsIs1) {
- shortcut = ImmutableList.copyOf(sequence1);
- } else {
- shortcut = ImmutableList.copyOf(sequence2);
- }
- return shortcut;
- }
-
+ // Traceback the matrix to create the final LCS
int current1 = size1;
int current2 = size2;
final List<E> result = Lists.newArrayList();
while (current1 > 0 && current2 > 0) {
- final E first = sequence1.get(current1 - 1);
- final E second = sequence2.get(current2 - 1);
- if (equalityHelper.matchingValues(first, second)
- && !contains(comparison, equalityHelper, ignoredElements, second)) {
- result.add(first);
+ final int currentLength = matrix[current1][current2];
+ final int nextLeft = matrix[current1][current2 - 1];
+ final int nextUp = matrix[current1 - 1][current2];
+ if (currentLength > nextLeft && currentLength > nextUp) {
+ result.add(copy1.get(current1 - 1));
current1--;
current2--;
- } else if (matrix[current1][current2 - 1] >= matrix[current1 - 1][current2]) {
+ } else if (nextLeft >= nextUp) {
current2--;
} else {
current1--;
}
}
- return Lists.reverse(result);
+
+ return ImmutableList.copyOf(Iterables.concat(prefix, Lists.reverse(result), suffix));
+ }
+
+ /**
+ * Trims and returns the common prefix of the two given sequences. All ignored elements within or after
+ * this common prefix will also be trimmed.
+ * <p>
+ * Note that the two given sequences will be modified in-place.
+ * </p>
+ *
+ * @param comparison
+ * This will be used in order to retrieve the Match for EObjects when comparing them.
+ * @param ignoredElements
+ * Specifies elements that should be excluded from the subsequences.
+ * @param sequence1
+ * First of the two sequences to consider.
+ * @param sequence2
+ * Second of the two sequences to consider.
+ * @param <E>
+ * Type of the sequences content.
+ * @return The common prefix of the two given sequences, less their ignored elements. As a side note, both
+ * {@code sequence1} and {@code sequence2} will have been trimmed of their prefix when this
+ * returns.
+ */
+ private static <E> List<E> trimPrefix(Comparison comparison, Iterable<E> ignoredElements,
+ List<E> sequence1, List<E> sequence2) {
+ final IEqualityHelper equalityHelper = comparison.getEqualityHelper();
+ final int size1 = sequence1.size();
+ final int size2 = sequence2.size();
+
+ final List<E> prefix = Lists.newArrayList();
+ int start1 = 1;
+ int start2 = 1;
+ boolean matching = true;
+ while (start1 <= size1 && start2 <= size2 && matching) {
+ final E first = sequence1.get(start1 - 1);
+ final E second = sequence2.get(start2 - 1);
+ if (equalityHelper.matchingValues(first, second)) {
+ prefix.add(first);
+ start1++;
+ start2++;
+ } else {
+ boolean ignore1 = contains(comparison, equalityHelper, ignoredElements, first);
+ boolean ignore2 = contains(comparison, equalityHelper, ignoredElements, second);
+ if (ignore1) {
+ start1++;
+ }
+ if (ignore2) {
+ start2++;
+ }
+ if (!ignore1 && !ignore2) {
+ matching = false;
+ }
+ }
+ }
+ for (int i = 1; i < start1; i++) {
+ sequence1.remove(0);
+ }
+ for (int i = 1; i < start2; i++) {
+ sequence2.remove(0);
+ }
+
+ return prefix;
+ }
+
+ /**
+ * Trims and returns the common suffix of the two given sequences. All ignored elements within or before
+ * this common suffix will also be trimmed.
+ * <p>
+ * Note that the two given sequences will be modified in-place.
+ * </p>
+ *
+ * @param comparison
+ * This will be used in order to retrieve the Match for EObjects when comparing them.
+ * @param ignoredElements
+ * Specifies elements that should be excluded from the subsequences.
+ * @param sequence1
+ * First of the two sequences to consider.
+ * @param sequence2
+ * Second of the two sequences to consider.
+ * @param <E>
+ * Type of the sequences content.
+ * @return The common suffix of the two given sequences, less their ignored elements. As a side note, both
+ * {@code sequence1} and {@code sequence2} will have been trimmed of their suffix when this
+ * returns.
+ */
+ private static <E> List<E> trimSuffix(Comparison comparison, Iterable<E> ignoredElements,
+ List<E> sequence1, List<E> sequence2) {
+ final IEqualityHelper equalityHelper = comparison.getEqualityHelper();
+ final int size1 = sequence1.size();
+ final int size2 = sequence2.size();
+
+ final List<E> suffix = Lists.newArrayList();
+ int end1 = size1;
+ int end2 = size2;
+ boolean matching = true;
+ while (end1 > 0 && end2 > 0 && matching) {
+ final E first = sequence1.get(end1 - 1);
+ final E second = sequence2.get(end2 - 1);
+ if (equalityHelper.matchingValues(first, second)) {
+ suffix.add(first);
+ end1--;
+ end2--;
+ } else {
+ boolean ignore1 = contains(comparison, equalityHelper, ignoredElements, first);
+ boolean ignore2 = contains(comparison, equalityHelper, ignoredElements, second);
+ if (ignore1) {
+ end1--;
+ }
+ if (ignore2) {
+ end2--;
+ }
+ if (!ignore1 && !ignore2) {
+ matching = false;
+ }
+ }
+ }
+ for (int i = size1; i > end1; i--) {
+ sequence1.remove(sequence1.size() - 1);
+ }
+ for (int i = size2; i > end2; i--) {
+ sequence2.remove(sequence2.size() - 1);
+ }
+
+ return Lists.reverse(suffix);
}
/**
@@ -234,56 +356,7 @@ public final class DiffUtil {
*/
public static <E> List<E> longestCommonSubsequence(Comparison comparison, List<E> sequence1,
List<E> sequence2) {
- final IEqualityHelper equalityHelper = comparison.getEqualityHelper();
- final int size1 = sequence1.size();
- final int size2 = sequence2.size();
-
- final int[][] matrix = new int[size1 + 1][size2 + 1];
-
- // Compute the LCS matrix
- for (int i = 1; i <= size1; i++) {
- final E first = sequence1.get(i - 1);
- for (int j = 1; j <= size2; j++) {
- final E second = sequence2.get(j - 1);
- if (equalityHelper.matchingValues(first, second)) {
- matrix[i][j] = 1 + matrix[i - 1][j - 1];
- } else {
- matrix[i][j] = Math.max(matrix[i - 1][j], matrix[i][j - 1]);
- }
- }
- }
-
- // Shortcut evaluation if the lcs is the whole sequence
- final boolean lcsIs1 = matrix[size1][size2] == size1;
- final boolean lcsIs2 = matrix[size1][size2] == size2;
- if (lcsIs1 || lcsIs2) {
- final List<E> shortcut;
- if (lcsIs1) {
- shortcut = ImmutableList.copyOf(sequence1);
- } else {
- shortcut = ImmutableList.copyOf(sequence2);
- }
- return shortcut;
- }
-
- int current1 = size1;
- int current2 = size2;
- final List<E> result = Lists.newArrayList();
-
- while (current1 > 0 && current2 > 0) {
- final E first = sequence1.get(current1 - 1);
- final E second = sequence2.get(current2 - 1);
- if (equalityHelper.matchingValues(first, second)) {
- result.add(first);
- current1--;
- current2--;
- } else if (matrix[current1][current2 - 1] >= matrix[current1 - 1][current2]) {
- current2--;
- } else {
- current1--;
- }
- }
- return Lists.reverse(result);
+ return longestCommonSubsequence(comparison, Collections.<E> emptyList(), sequence1, sequence2);
}
/*
@@ -586,7 +659,7 @@ public final class DiffUtil {
* right model as the source and the left as the target.
* @return The index at which this {@code diff}'s value should be inserted into the 'target' list, as
* inferred from {@code rightToLeft}.
- * @see #findInsertionIndex(Comparison, EqualityHelper, Iterable, List, List, Object)
+ * @see #findInsertionIndex(Comparison, Iterable, List, List, Object)
*/
@SuppressWarnings("unchecked")
public static int findInsertionIndex(Comparison comparison, Diff diff, boolean rightToLeft) {
@@ -655,8 +728,10 @@ public final class DiffUtil {
targetList = ImmutableList.of();
}
- final Iterable<Object> ignoredElements = Iterables.concat(computeIgnoredElements(targetList, diff),
+ Iterable<Object> ignoredElements = Iterables.concat(computeIgnoredElements(targetList, diff),
Collections.singleton(value));
+ // We know we'll have to iterate quite a number of times on this one.
+ ignoredElements = Lists.newArrayList(ignoredElements);
return DiffUtil.findInsertionIndex(comparison, ignoredElements, sourceList, targetList, value);
}
@@ -766,23 +841,32 @@ public final class DiffUtil {
* element in {@code candidates}.
*/
private static <E> Iterable<E> computeIgnoredElements(Iterable<E> candidates, final Diff diff) {
- return Iterables.filter(candidates, new Predicate<Object>() {
- public boolean apply(final Object element) {
- final Match match = diff.getMatch();
- final EStructuralFeature feature;
- if (diff instanceof AttributeChange) {
- feature = ((AttributeChange)diff).getAttribute();
- } else if (diff instanceof ReferenceChange) {
- feature = ((ReferenceChange)diff).getReference();
- } else {
- return false;
- }
+ final Match match = diff.getMatch();
+ final Iterable<? extends Diff> filteredCandidates = Lists.newArrayList(match.getDifferences());
+ final EStructuralFeature feature;
+ if (diff instanceof AttributeChange) {
+ feature = ((AttributeChange)diff).getAttribute();
+ } else if (diff instanceof ReferenceChange) {
+ feature = ((ReferenceChange)diff).getReference();
+ } else {
+ return Collections.emptyList();
+ }
- final Iterable<? extends Diff> filteredCandidates = Iterables.filter(match.getDifferences(),
- diff.getClass());
- return Iterables.any(filteredCandidates, new UnresolvedDiffMatching(feature, element));
+ final Set<E> ignored = Sets.newLinkedHashSet();
+ for (E candidate : candidates) {
+ if (candidate instanceof EObject) {
+ final Iterable<? extends Diff> differences = match.getComparison().getDifferences(
+ (EObject)candidate);
+ if (Iterables.any(differences, new UnresolvedDiffMatching(feature, candidate))) {
+ ignored.add(candidate);
+ }
+ } else {
+ if (Iterables.any(filteredCandidates, new UnresolvedDiffMatching(feature, candidate))) {
+ ignored.add(candidate);
+ }
}
- });
+ }
+ return ignored;
}
/**

Back to the top