Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Redor2014-03-03 14:14:59 +0000
committerLaurent Redor2014-03-03 15:17:47 +0000
commit092d76dae498abb31813f886e7d8da54a770f4b0 (patch)
tree65eb24a4b36668827154a20fef38ff5c7b8ff9c8 /plugins
parentafa9b6af2afd8e18275e873deeb26d40ddb1eb45 (diff)
parent9efe3b1caf049d01fd1e464d4bb80248609fdd35 (diff)
downloadorg.eclipse.sirius-092d76dae498abb31813f886e7d8da54a770f4b0.tar.gz
org.eclipse.sirius-092d76dae498abb31813f886e7d8da54a770f4b0.tar.xz
org.eclipse.sirius-092d76dae498abb31813f886e7d8da54a770f4b0.zip
Merge branch 'master' into bug/427803_moveDiagramEcoreInItsOwnPlugin
Conflicts: plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF plugins/org.eclipse.sirius.diagram/src/org/eclipse/sirius/diagram/internal/refresh/listeners/GMFDiagramUpdater.java plugins/org.eclipse.sirius.doc/doc/Release Notes.html plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF plugins/org.eclipse.sirius/model/viewpoint.genmodel plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/display/VisibilityPropagatorAdapter.java plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java Change-Id: I7178ed1a9fcbd84295e02eb258710c8fbdcb5531 Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.mtl.ide/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.mtl/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.common.ui/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.common/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.sirius.diagram.sequence.ui/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/operation/RefreshGraphicalOrderingOperation.java29
-rw-r--r--plugins/org.eclipse.sirius.diagram.ui/src2/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/GMFDiagramUpdater.java7
-rw-r--r--plugins/org.eclipse.sirius.diagram/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/helper/display/VisibilityPropagatorAdapter.java21
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.html16
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release Notes.textile8
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html2
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile2
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.html5
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.textile2
-rw-r--r--plugins/org.eclipse.sirius.ecore.extender/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.editor.diagram/src-gen/org/eclipse/sirius/diagram/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java2
-rw-r--r--plugins/org.eclipse.sirius.editor.tree/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.ext.base/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.sirius.ext.draw2d/src/org/eclipse/sirius/ext/draw2d/figure/ActionTriggerImageFigure.java.orig198
-rw-r--r--plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.synchronizer/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.table.ui/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java13
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentProvider.java26
-rw-r--r--plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/TableUIUpdater.java (renamed from plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentAdapter.java)17
-rw-r--r--plugins/org.eclipse.sirius.table/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.checkstyle12
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.classpath12
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.project34
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.runtime.prefs3
-rw-r--r--plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--plugins/org.eclipse.sirius.tests.support/META-INF/MANIFEST.MF26
-rw-r--r--plugins/org.eclipse.sirius.tests.support/build.properties16
-rw-r--r--plugins/org.eclipse.sirius.tests.support/plugin.properties12
-rw-r--r--plugins/org.eclipse.sirius.tests.support/pom.xml27
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractColorReferenceTestCase.java136
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractInterpretedExpressionTestCase.java135
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractItemProviderAdapterFactoryRegistryTestCase.java154
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/DiagramComponentizationTestSupport.java182
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EclipseTestsSupportHelper.java142
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsHashCodeTestCase.java47
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsTestCase.java181
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/GraphicTestsSupportHelp.java106
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ICondition.java41
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEquality.java47
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEqualityAsserter.java55
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/PluginVersionCompatibility.java80
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusAssert.java111
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusDiagramTestCase.java1392
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusTestCase.java1675
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestCaseCleaner.java76
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestsUtil.java234
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TreeItemImageQuery.java48
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteAttachmentRecordingCommand.java54
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteRecordingCommand.java51
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/SiriusTestsSupportPlugin.java49
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/EclipseTestsSupportHelperImpl.java247
-rw-r--r--plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/ModelInitializer.java294
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/.checkstyle12
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/.classpath12
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/.project34
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/.settings/org.eclipse.jdt.core.prefs24
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/META-INF/MANIFEST.MF69
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/build.properties15
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/plugin.properties12
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/pom.xml27
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java1555
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/SWTDesignerBot.java40
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/AbstractOdesignTreeItemBot.java45
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/DiagramDescriptionBot.java41
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/GroupBot.java40
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/SiriusBot.java52
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/AbstractUIRepresentation.java120
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/ExistingSemanticResourceWizardUIWrapper.java36
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/SemanticResourceFromSratchWizardUIWrapper.java120
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIAddLocalSemanticResourceWizardUIWrapper.java77
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIDiagramRepresentation.java234
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UILocalSession.java625
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilder.java174
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilderFlow.java102
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIPerspective.java367
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIProject.java223
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIResource.java193
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UISessionCreationWizardFlow.java155
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITableRepresentation.java88
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITreeRepresentation.java88
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithNextTreeItem.java47
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithTreeItem.java42
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSCategoryBrowser.java43
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSRepresentationBrowser.java85
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSResourceBrowser.java35
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSViewpointBrowser.java43
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILocalSessionBrowser.java87
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/AbstractOperationCondition.java67
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckBoundsCondition.java126
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckContextMenuAvailableCondition.java58
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckDiagramSelected.java59
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEdgeLabelVisibility.java65
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsDisplayed.java62
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsNotDisplayed.java63
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartMoved.java106
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartResized.java56
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEmptySelection.java59
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckNbVisibleElementsInTree.java82
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckSelectedCondition.java118
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckToolIsActivated.java56
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckTreeItemEnabled.java52
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DiagramWithChildrensCondition.java53
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DragAndDropCondition.java80
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/EditorHasFocusCondition.java56
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ItemEnabledCondition.java55
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NotifiedFromLockOperationCondition.java99
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NumberOfOpenedEditorsCondition.java55
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OpenedSessionCondition.java50
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationDoneCondition.java35
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationRedoneCondition.java35
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationUndoneCondition.java35
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PaletteToolsAvailabilityCondition.java72
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PerspectiveActivatedCondition.java50
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ProjectDependenciesItemDisplayed.java55
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionClosedCondition.java46
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionCondition.java72
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionSavedCondition.java45
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TableHasRowCondition.java44
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TextWidgetCondition.java51
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TransactionClosedCondition.java64
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemAvailableCondition.java84
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemChildrenNumberCondition.java71
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemContainsAtLeastOneChild.java59
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemExpanded.java63
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemSelected.java57
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemTextCondition.java50
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ViewpointSelectionCondition.java56
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsDisabledCondition.java45
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsEnabledCondition.java46
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ExportAsImageHelper.java91
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ViewpointSelectionDialog.java129
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerEditor.java1572
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerGefViewer.java301
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerHelper.java396
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMEditor.java116
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMHelper.java76
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/AbstractDecoratorMatcher.java70
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/DeletedDecoratorMatcher.java34
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/NoteEditPartMatcher.java38
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithDRepresentationElementType.java65
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithSemantic.java78
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/PointAround.java95
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/RectangleAround.java86
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/perspective/DesignerPerspectives.java66
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractMMEcoreBasedScenarioTestCase.java50
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractScenarioTestCase.java52
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/DesignerViews.java154
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusOutlineView.java101
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusPropertiesView.java70
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/BackgroundColorFigureGetter.java49
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/ContextualMenuItemGetter.java86
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/NodeFigureGradientDataGetter.java52
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotShellForTabbar.java126
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotSiriusFigureCanvas.java146
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemBackgroundColorQuery.java69
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpandedQuery.java48
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpander.java54
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelColorQuery.java67
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelFontFormatQuery.java84
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelSizeQuery.java70
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/WrappedSWTBotRadio.java90
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/DesignerSWTBotTestsSupportPlugin.java50
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/business/UISessionCreationWizard.java296
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotCommonHelper.java233
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotSplitEditor.java177
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotUtils.java429
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SiriusContextMenuFinder.java142
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/business/UIRepresentationUtils.java64
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/dnd/DndUtil.java346
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/FirstContextMenuFinder.java117
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/SWTBotContextMenu.java130
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/tree/TreeUtils.java789
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java8
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java24
-rw-r--r--plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreeUIUpdater.java (renamed from plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java)27
-rw-r--r--plugins/org.eclipse.sirius.tree/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.ui/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/business/api/session/SessionHelper.java4
-rw-r--r--plugins/org.eclipse.sirius/META-INF/MANIFEST.MF2
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/componentization/ViewpointRegistryImpl.java23
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/RepresentationDescriptionQuery.java6
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/repair/SiriusRepairProcess.java2
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/contribution/RepresentationExtensionsFinder.java2
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/MaskingPolicy.java23
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java2
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/SessionTransientAttachment.java3
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java12
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java2
198 files changed, 20802 insertions, 340 deletions
diff --git a/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/META-INF/MANIFEST.MF
index b9c7449580..728193fa26 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.common.acceleo.mtl.ide/META-INF/MANIFEST.MF
@@ -15,7 +15,7 @@ Require-Bundle: org.eclipse.sirius.common.acceleo.mtl;bundle-version="1.0.0",
org.eclipse.jface.text;bundle-version="3.5.0",
org.eclipse.acceleo.ide.ui;bundle-version="3.2.1",
org.eclipse.acceleo.parser;bundle-version="3.2.1",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.core.filebuffers;bundle-version="3.5.200"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/plugins/org.eclipse.sirius.common.acceleo.mtl/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.common.acceleo.mtl/META-INF/MANIFEST.MF
index 557728f9f5..0fc136cf8e 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.mtl/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.common.acceleo.mtl/META-INF/MANIFEST.MF
@@ -10,7 +10,7 @@ Require-Bundle: org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.acceleo.parser;bundle-version="3.2.1",
org.eclipse.core.resources;bundle-version="3.4.0",
org.eclipse.core.runtime;bundle-version="3.4.0",
- com.google.guava;bundle-version="11.0.0"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.sirius.common.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.common.ui/META-INF/MANIFEST.MF
index 02a61e94a7..00cc293465 100644
--- a/plugins/org.eclipse.sirius.common.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.common.ui/META-INF/MANIFEST.MF
@@ -8,7 +8,7 @@ Require-Bundle: org.eclipse.emf.edit.ui;bundle-version="2.8.0",
org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.ui.ide;bundle-version="3.8.2",
org.eclipse.emf.workspace;bundle-version="1.5.1",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.core.expressions;bundle-version="3.3.0",
org.eclipse.sirius.ecore.extender;bundle-version="1.0.0"
Export-Package: org.eclipse.sirius.common.ui;version="1.0.0",
diff --git a/plugins/org.eclipse.sirius.common/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.common/META-INF/MANIFEST.MF
index 7a3024d347..bed3004f6d 100644
--- a/plugins/org.eclipse.sirius.common/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.common/META-INF/MANIFEST.MF
@@ -6,7 +6,7 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.sirius.ecore.extender;bundle-version="1.0.0",
org.eclipse.emf.workspace;bundle-version="1.5.1",
- com.google.guava;bundle-version="[11.0.0,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Export-Package: org.eclipse.sirius.common.tools;version="1.0.0",
org.eclipse.sirius.common.tools.api.constant;version="1.0.0",
org.eclipse.sirius.common.tools.api.contentassist;version="1.0.0",
@@ -31,4 +31,3 @@ Bundle-Localization: plugin
Import-Package: org.eclipse.sirius.ext.base;version="1.0.0",
org.eclipse.sirius.ext.base.cache;version="1.0.0",
org.eclipse.sirius.ext.base.collect;version="1.0.0"
-
diff --git a/plugins/org.eclipse.sirius.diagram.sequence.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.diagram.sequence.ui/META-INF/MANIFEST.MF
index 6144bda471..c2ec9263f8 100644
--- a/plugins/org.eclipse.sirius.diagram.sequence.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.diagram.sequence.ui/META-INF/MANIFEST.MF
@@ -5,7 +5,7 @@ Bundle-SymbolicName: org.eclipse.sirius.diagram.sequence.ui;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.sirius.diagram.sequence.ui.SequenceDiagramPlugin
Bundle-Vendor: %providerName
-Require-Bundle: com.google.guava;bundle-version="[11.0.0,12.0.0)",
+Require-Bundle: com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.sirius.diagram.sequence.edit;bundle-version="1.0.0",
org.eclipse.gmf.runtime.diagram.ui;bundle-version="1.6.0",
diff --git a/plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF
index 323bf6aa70..23ff0695ae 100644
--- a/plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.diagram.sequence/META-INF/MANIFEST.MF
@@ -43,7 +43,7 @@ Export-Package: org.eclipse.sirius.diagram.sequence;version="1.0.0",
org.eclipse.sirius.diagram.sequence.util;version="1.0.0"
Require-Bundle: org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.sirius.ecore.extender;bundle-version="1.0.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.gmf.runtime.notation;bundle-version="1.5.0",
org.eclipse.gmf.runtime.draw2d.ui;bundle-version="1.0.101",
org.eclipse.draw2d;bundle-version="3.9.0",
diff --git a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/operation/RefreshGraphicalOrderingOperation.java b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/operation/RefreshGraphicalOrderingOperation.java
index a996d7c936..2f69c30331 100644
--- a/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/operation/RefreshGraphicalOrderingOperation.java
+++ b/plugins/org.eclipse.sirius.diagram.sequence/src/org/eclipse/sirius/diagram/sequence/business/internal/operation/RefreshGraphicalOrderingOperation.java
@@ -12,7 +12,7 @@ package org.eclipse.sirius.diagram.sequence.business.internal.operation;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
+import java.util.concurrent.ExecutionException;
import org.eclipse.sirius.diagram.sequence.SequenceDDiagram;
import org.eclipse.sirius.diagram.sequence.business.internal.VerticalPositionFunction;
@@ -23,11 +23,13 @@ import org.eclipse.sirius.diagram.sequence.ordering.EventEndsOrdering;
import org.eclipse.sirius.diagram.sequence.ordering.SingleEventEnd;
import org.eclipse.sirius.diagram.ui.business.internal.operation.AbstractModelChangeOperation;
-import com.google.common.base.Functions;
+import com.google.common.base.Function;
import com.google.common.base.Predicate;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
import com.google.common.collect.Ordering;
/**
@@ -84,15 +86,28 @@ public class RefreshGraphicalOrderingOperation extends AbstractModelChangeOperat
* event ends.
*/
private void refreshGlobalOrdering(EventEndsOrdering graphicalOrdering, VerticalPositionFunction verticalPosition) {
- final Map<EventEnd, Integer> positions = new MapMaker().makeComputingMap(verticalPosition);
+ final LoadingCache<EventEnd, Integer> positions = CacheBuilder.newBuilder().build(CacheLoader.from(verticalPosition));
Predicate<EventEnd> isValidEnd = new Predicate<EventEnd>() {
public boolean apply(EventEnd input) {
- Integer pos = positions.get(input);
- return pos != VerticalPositionFunction.INVALID_POSITION && pos != -VerticalPositionFunction.INVALID_POSITION;
+ try {
+ Integer pos = positions.get(input);
+ return pos != VerticalPositionFunction.INVALID_POSITION && pos != -VerticalPositionFunction.INVALID_POSITION;
+ } catch (ExecutionException e) {
+ return false;
+ }
}
};
List<EventEnd> allEnds = Lists.newArrayList(Iterables.filter(RefreshOrderingHelper.getAllEventEnds(sequenceDiagram), isValidEnd));
- Collections.sort(allEnds, Ordering.natural().onResultOf(Functions.forMap(positions)));
+ Collections.sort(allEnds, Ordering.natural().onResultOf(new Function<EventEnd, Integer>() {
+ @Override
+ public Integer apply(EventEnd input) {
+ try {
+ return positions.get(input);
+ } catch (ExecutionException e) {
+ return VerticalPositionFunction.INVALID_POSITION;
+ }
+ }
+ }));
RefreshOrderingHelper.updateIfNeeded(graphicalOrdering.getEventEnds(), allEnds);
}
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src2/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/GMFDiagramUpdater.java b/plugins/org.eclipse.sirius.diagram.ui/src2/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/GMFDiagramUpdater.java
index 8ccdf97619..7241e9c130 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src2/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/GMFDiagramUpdater.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src2/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/GMFDiagramUpdater.java
@@ -14,6 +14,7 @@ import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionEventBroker;
import org.eclipse.sirius.diagram.DDiagram;
+import org.eclipse.sirius.diagram.business.internal.helper.display.VisibilityPropagatorAdapter;
/**
* Register all gmf diagram updaters.
@@ -37,9 +38,11 @@ public class GMFDiagramUpdater {
private ComputedStyleDescriptionCacheCleaner computedStyleDescriptionCacheCleaner;
private EdgeStyleUpdater edgeStyleUpdater;
-
+
private SessionEventBroker eventBroker;
+ private VisibilityPropagatorAdapter visibilityPropagator;
+
/**
* Default constructor.
*
@@ -60,6 +63,7 @@ public class GMFDiagramUpdater {
gmfBoundsUpdater = new GMFBoundsUpdater(domain, dDiagram);
visibilityUpdater = new VisibilityUpdater(domain, dDiagram);
dDiagramHiddenElementsUpdater = new DDiagramHiddenElementsUpdater(domain, dDiagram);
+ visibilityPropagator = new VisibilityPropagatorAdapter(session, dDiagram);
computedStyleDescriptionCacheCleaner = new ComputedStyleDescriptionCacheCleaner(domain, dDiagram);
edgeStyleUpdater = new EdgeStyleUpdater(domain, session.getSemanticCrossReferencer());
@@ -69,6 +73,7 @@ public class GMFDiagramUpdater {
* Dispose the gmf diagram updaters.
*/
public void dispose() {
+ visibilityPropagator.dispose();
notationVisibilityUpdater.dispose();
viewFontChangesRefactorer.dispose();
gmfBoundsUpdater.dispose();
diff --git a/plugins/org.eclipse.sirius.diagram/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.diagram/META-INF/MANIFEST.MF
index 6dadcae42e..c21a0fb2fe 100644
--- a/plugins/org.eclipse.sirius.diagram/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.diagram/META-INF/MANIFEST.MF
@@ -31,7 +31,7 @@ Require-Bundle: org.eclipse.core.expressions;bundle-version="3.4.400",
org.w3c.dom.svg;bundle-version="1.1.0",
org.apache.batik.transcoder;bundle-version="[1.6.0,1.7.0)",
org.apache.batik.css;bundle-version="[1.6.0,1.7.0)",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
com.ibm.icu;bundle-version="4.4.2",
org.eclipse.core.databinding;bundle-version="1.4.1",
org.eclipse.core.databinding.observable;bundle-version="1.4.1",
diff --git a/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/helper/display/VisibilityPropagatorAdapter.java b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/helper/display/VisibilityPropagatorAdapter.java
index e43ba4b3a3..8962f7508d 100644
--- a/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/helper/display/VisibilityPropagatorAdapter.java
+++ b/plugins/org.eclipse.sirius.diagram/src-core/org/eclipse/sirius/diagram/business/internal/helper/display/VisibilityPropagatorAdapter.java
@@ -28,7 +28,6 @@ import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManager;
import org.eclipse.sirius.diagram.business.api.componentization.DiagramMappingsManagerRegistry;
import org.eclipse.sirius.diagram.business.api.helper.display.DisplayServiceManager;
-import org.eclipse.sirius.viewpoint.DView;
import com.google.common.collect.Iterables;
@@ -48,14 +47,20 @@ public class VisibilityPropagatorAdapter extends EContentAdapter implements Noti
private Session session;
+ private DDiagram diagram;
+
/**
* Create a new adapter.
*
* @param session
* the current session.
+ * @param diagram
+ * the current diagram.
*/
- public VisibilityPropagatorAdapter(Session session) {
+ public VisibilityPropagatorAdapter(Session session, DDiagram diagram) {
this.session = session;
+ this.diagram = diagram;
+ this.diagram.eAdapters().add(this);
}
/**
@@ -153,7 +158,7 @@ public class VisibilityPropagatorAdapter extends EContentAdapter implements Noti
@Override
protected void addAdapter(Notifier notifier) {
- if (notifier instanceof DView || notifier instanceof DSemanticDiagram || notifier instanceof DDiagramElement) {
+ if (notifier instanceof DSemanticDiagram || notifier instanceof DDiagramElement) {
super.addAdapter(notifier);
}
}
@@ -193,4 +198,14 @@ public class VisibilityPropagatorAdapter extends EContentAdapter implements Noti
return DisplayServiceManager.INSTANCE.getDisplayService().computeVisibility(mappingManager, parentDiagram, element);
}
+ /**
+ * Dispose the current content adapter: remove it from the diagram.
+ */
+ public void dispose() {
+ if (diagram != null) {
+ diagram.eAdapters().remove(this);
+ }
+ diagram = null;
+ session = null;
+ }
}
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
index 723164a3a2..e6b664cb3f 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.html
@@ -76,7 +76,8 @@
<li>
<code>IDiagramDescriptionProvider</code>
<ul>
- <li> <code>completeToolTipText(String, EObject)</code> allows the diagram type to customize the tooltip displayed in a property section of a given VSM element.
+ <li>
+ <code>completeToolTipText(String, EObject)</code> allows the diagram type to customize the tooltip displayed in a property section of a given VSM element.
<code>SequenceDiagramTypeProvider</code> implements this method to mention some Sequence specific variable available in core and diagram tool preconditions in the context of a Sequence diagram.
</li>
</ul>
@@ -86,6 +87,19 @@
</ul>
<h2 id="sirius1.0M6">Changes in Sirius 1.0.0M6 (from Sirius 1.0M5)</h2>
<h3 id="APIChanges2">API Changes</h3>
+ <h4 id="tests">High-level API for Automated Tests Using JUnit and SWTBot</h4>
+ <p>Starting from version 1.0.0M6, Sirius includes high-level APIs to help creating automated tests using JUnit and/or SWTBot. These can be used either to test Sirius itself or to test Sirius-based modelers. These APIs are provided by two plug-ins:</p>
+ <ul>
+ <li>
+ <code>org.eclipse.sirius.tests.support</code>: support code for JUnit (plug-in) tests using Sirius.
+ </li>
+ <li>
+ <code>org.eclipse.sirius.tests.swtbot.support</code>: support code for SWTBot tests using Sirius.
+ </li>
+ </ul>
+ <p>Both plug-ins are only available if you install the new
+ <code>org.eclipse.sirius.tests</code> feature.
+ </p>
<h4 id="separationOfDiagramSpecificConcept-step2">Move diagram-specific EPackages into their own diagram.ecore model</h4>
<p>This milestone (Sirius 1.0M6) includes the second step towards a full separation of the diagram-specific stuff out of the core of Sirius (see
<a href="#separationOfDiagramSpecificConcept-step1">Step1</a> for more details).
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
index 42a482053a..810ea24613 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release Notes.textile
@@ -28,6 +28,14 @@ h2(#sirius1.0M6). Changes in Sirius 1.0.0M6 (from Sirius 1.0M5)
h3. API Changes
+h4(#tests). High-level API for Automated Tests Using JUnit and SWTBot
+
+Starting from version 1.0.0M6, Sirius includes high-level APIs to help creating automated tests using JUnit and/or SWTBot. These can be used either to test Sirius itself or to test Sirius-based modelers. These APIs are provided by two plug-ins:
+* @org.eclipse.sirius.tests.support@: support code for JUnit (plug-in) tests using Sirius.
+* @org.eclipse.sirius.tests.swtbot.support@: support code for SWTBot tests using Sirius.
+
+Both plug-ins are only available if you install the new @org.eclipse.sirius.tests@ feature.
+
h4(#separationOfDiagramSpecificConcept-step2). Move diagram-specific EPackages into their own diagram.ecore model
This milestone (Sirius 1.0M6) includes the second step towards a full separation of the diagram-specific stuff out of the core of Sirius (see "Step1":#separationOfDiagramSpecificConcept-step1 for more details).
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
index c3138c793b..5ee96a66af 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
@@ -310,7 +310,7 @@
</p>
<p>You can easily identify
<em>Interpreted Expressions</em> by their yellow background in the
- <em>Prorperties</em> sheet of an element. For all such field, you can use any of the supported languages to write the expression. Refer to the
+ <em>Properties</em> sheet of an element. For all such field, you can use any of the supported languages to write the expression. Refer to the
<a href="Writing_Queries.html">queries documentation</a> for more details.
</p>
<p>
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
index 3d76a0a75e..e24f50e668 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
@@ -104,7 +104,7 @@ h3(#interpreted_expressions). Interpreted Expressions
Many _VSM_ elements require you to specify _Interpreted Expressions_ to configure them. These can be queries to select elements (as in mappings for example), or more general expressions to compute value (like the text to use for the elements' labels).
-You can easily identify _Interpreted Expressions_ by their yellow background in the _Prorperties_ sheet of an element. For all such field, you can use any of the supported languages to write the expression. Refer to the "queries documentation":Writing_Queries.html for more details.
+You can easily identify _Interpreted Expressions_ by their yellow background in the _Properties_ sheet of an element. For all such field, you can use any of the supported languages to write the expression. Refer to the "queries documentation":Writing_Queries.html for more details.
!images/interpreted_expressions.png!
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.html b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.html
index 240a3bb456..47c6c950eb 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.html
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.html
@@ -208,6 +208,11 @@
<a href="http://www.obeonetwork.com/page/building-an-acceleo-generator">http://www.obeonetwork.com/page/building-an-acceleo-generator</a> to ensure the project is built correctly, or the queries defined in the
<code>.mtl</code> files may not be available when the project is deployed as a plug-in.
</p>
+ <p>
+ <em>Note:</em> due to an incompatible change in serialization format in EMF 2.9, if you use external
+ <code>.mtl</code> files in your modeler definitions and build your modeler plug-ins using EMF 2.9 or later, the resulting modeler will not work with previous versions of EMF (as the resulting
+ <code>.emtl</code> files will not load correctly with EMF 2.8 and earlier). For reference, EMF 2.9 corresponds to Eclipse 4.3 (Kepler).
+ </p>
<p>Acceleo is more precise than the legacy language, but also more demanding, about the types of elements your queries are executed on. This generally means you get better auto-completion and more useful validation and diagnostics. However sometimes Sirius is not able to statically determine the precise type of the model elements on which an expression will be evaluated. In that case, it assumes a plain
<em>EObject</em>. If you know the actual type which will be used, prefix your expression with
<code>filter(ExpectedType)</code> to help Sirius. Note that if the actual type at runtime is not compatible with
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.textile b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.textile
index 6d46c04e1a..da4b8ad8b0 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Writing_Queries.textile
@@ -69,6 +69,8 @@ Note that currently Acceleo expressions used inside VSMs *must* be enclosed insi
Acceleo expressions can transparently invoke methods from Java classes which follow the "service methods":#service_methods conventions and have been properly declared in the VSM. Note that currently this only works if the Java service class is in the same project as the _VSM_. You can also invoke Acceleo _queries_ defined in @.mtl@ files in your Viewpoint Specification Project. For this to work, your Viewpoint Specification Project should be an Acceleo Generator project. This is the default for projects created with the wizard. If you want to use queries from @.mtl@ files in you Sirius project, the parent _Viewpoint_ element must have a _Java Extension_ element which references the MTL file, using the @com::example::domain::design::module@ syntax. Also make sure to read "http://www.obeonetwork.com/page/building-an-acceleo-generator":http://www.obeonetwork.com/page/building-an-acceleo-generator to ensure the project is built correctly, or the queries defined in the @.mtl@ files may not be available when the project is deployed as a plug-in.
+_Note:_ due to an incompatible change in serialization format in EMF 2.9, if you use external @.mtl@ files in your modeler definitions and build your modeler plug-ins using EMF 2.9 or later, the resulting modeler will not work with previous versions of EMF (as the resulting @.emtl@ files will not load correctly with EMF 2.8 and earlier). For reference, EMF 2.9 corresponds to Eclipse 4.3 (Kepler).
+
Acceleo is more precise than the legacy language, but also more demanding, about the types of elements your queries are executed on. This generally means you get better auto-completion and more useful validation and diagnostics. However sometimes Sirius is not able to statically determine the precise type of the model elements on which an expression will be evaluated. In that case, it assumes a plain _EObject_. If you know the actual type which will be used, prefix your expression with @filter(ExpectedType)@ to help Sirius. Note that if the actual type at runtime is not compatible with @ExpectedType@, the rest of your expression will silently be ignored.
In the context of Sirius, you have access to a special feature which can be used to follow "back-links" or "cross-references". From a given model element, this allows you to easily (and efficiently) find all the elements which refer to it in the scope of the models and representations in the same modeling project. This feature is available through the @eInverse()@ method, which can be used on any model element inside an Acceleo expression.
diff --git a/plugins/org.eclipse.sirius.ecore.extender/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.ecore.extender/META-INF/MANIFEST.MF
index 73d85d5c86..c4575468cf 100644
--- a/plugins/org.eclipse.sirius.ecore.extender/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.ecore.extender/META-INF/MANIFEST.MF
@@ -7,7 +7,7 @@ Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.emf.ecore.xmi;bundle-version="2.8.1",
org.eclipse.emf.edit;bundle-version="2.8.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)";visibility:=reexport
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Export-Package: org.eclipse.sirius.ecore.extender.business.api.accessor;version="1.0.0",
org.eclipse.sirius.ecore.extender.business.api.accessor.exception;version="1.0.0",
org.eclipse.sirius.ecore.extender.business.api.permission;version="1.0.0",
diff --git a/plugins/org.eclipse.sirius.editor.diagram/src-gen/org/eclipse/sirius/diagram/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java b/plugins/org.eclipse.sirius.editor.diagram/src-gen/org/eclipse/sirius/diagram/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java
index a0870a9a1e..655df3f99e 100644
--- a/plugins/org.eclipse.sirius.editor.diagram/src-gen/org/eclipse/sirius/diagram/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java
+++ b/plugins/org.eclipse.sirius.editor.diagram/src-gen/org/eclipse/sirius/diagram/editor/properties/sections/tool/deletehook/DeleteHookIdPropertySection.java
@@ -112,7 +112,7 @@ public class DeleteHookIdPropertySection extends AbstractTextPropertySection {
* {@inheritDoc}
*/
protected String getPropertyDescription() {
- return "An id of an extension to org.eclipse.sirius.deleteHook extension point. It may be used to add a confirmation dialog before deletion";
+ return "An id of an extension to org.eclipse.sirius.deleteHook extension point. It may be used to add a confirmation dialog before deletion";
}
// Start of user code user operations
diff --git a/plugins/org.eclipse.sirius.editor.tree/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.editor.tree/META-INF/MANIFEST.MF
index c288f1ab22..8e60f455bd 100644
--- a/plugins/org.eclipse.sirius.editor.tree/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.editor.tree/META-INF/MANIFEST.MF
@@ -11,7 +11,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.300",
org.eclipse.emf.edit.ui;bundle-version="2.3.1",
org.eclipse.sirius.common;bundle-version="1.0.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.ui.workbench.texteditor;bundle-version="3.8.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Eclipse-LazyStart: true
diff --git a/plugins/org.eclipse.sirius.ext.base/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.ext.base/META-INF/MANIFEST.MF
index 2186b040af..ebbf4f0b7f 100644
--- a/plugins/org.eclipse.sirius.ext.base/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.ext.base/META-INF/MANIFEST.MF
@@ -6,8 +6,8 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Localization: plugin
-Import-Package: com.google.common.base;version="[11.0.2,12.0.0)",
- com.google.common.collect;version="[11.0.2,12.0.0)"
+Import-Package: com.google.common.base;version="[11.0.2,16.0)",
+ com.google.common.collect;version="[11.0.2,16.0)"
Export-Package: org.eclipse.sirius.ext.base;version="1.0.0",
org.eclipse.sirius.ext.base.cache;version="1.0.0",
org.eclipse.sirius.ext.base.collect;version="1.0.0",
diff --git a/plugins/org.eclipse.sirius.ext.draw2d/src/org/eclipse/sirius/ext/draw2d/figure/ActionTriggerImageFigure.java.orig b/plugins/org.eclipse.sirius.ext.draw2d/src/org/eclipse/sirius/ext/draw2d/figure/ActionTriggerImageFigure.java.orig
deleted file mode 100644
index daff99460c..0000000000
--- a/plugins/org.eclipse.sirius.ext.draw2d/src/org/eclipse/sirius/ext/draw2d/figure/ActionTriggerImageFigure.java.orig
+++ /dev/null
@@ -1,198 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2009 THALES GLOBAL SERVICES.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms 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.sirius.ext.draw2d.figure;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.draw2d.MouseEvent;
-import org.eclipse.draw2d.MouseListener;
-<<<<<<< HEAD:plugins/org.eclipse.sirius.diagram/src/org/eclipse/sirius/diagram/ui/tools/api/figure/ActionTriggerImageFigure.java
-import org.eclipse.sirius.common.ui.tools.api.util.ISimpleAction;
-import org.eclipse.swt.graphics.Image;
-
-||||||| merged common ancestors
-import org.eclipse.swt.graphics.Image;
-
-import org.eclipse.sirius.common.ui.tools.api.util.ISimpleAction;
-
-=======
-import org.eclipse.swt.graphics.Image;
-
->>>>>>> master:plugins/org.eclipse.sirius.ext.draw2d/src/org/eclipse/sirius/ext/draw2d/figure/ActionTriggerImageFigure.java
-/**
- * A figure that triggers actions when the user clicks on the image.
- *
- *
- * @author ymortier
- */
-public class ActionTriggerImageFigure extends MouseAwareImageFigure {
-
- /** The image that is shown when the user clicks on the figure. */
- protected Image clickedImage;
-
- /**
- * Actions to triggers when the image is clicked.
- */
- private List<Runnable> actions;
-
- /**
- * the action trigger mandatory to simulate click
- */
- private ActionTrigger actionTrigger;
-
- /**
- * Create a new {@link ActionTriggerImageFigure}.
- */
- public ActionTriggerImageFigure() {
- super();
- this.init();
- }
-
- /**
- * Create a new {@link ActionTriggerImageFigure}.
- *
- * @param imageWOFocus
- * the image that is shown when the mouse is not on the figure.
- * @param imageWFocus
- * the image that is shown when the mouse is on the figure.
- */
- public ActionTriggerImageFigure(final Image imageWOFocus, final Image imageWFocus) {
- super(imageWOFocus, imageWFocus);
- this.init();
- }
-
- /**
- * Create a new {@link ActionTriggerImageFigure}.
- *
- * @param imageWOFocus
- * the image that is shown when the mouse is not on the figure.
- */
- public ActionTriggerImageFigure(final Image imageWOFocus) {
- super(imageWOFocus);
- this.init();
- }
-
- /**
- * Initialize the figure.
- */
- private void init() {
- this.actions = new LinkedList<Runnable>();
- this.actionTrigger = new ActionTrigger();
- this.addMouseListener(this.actionTrigger);
- }
-
- /**
- * This class has the responsability to trigger actions when the figure is
- * clicked.
- *
- * @author ymortier
- */
- private class ActionTrigger implements MouseListener {
-
- /**
- * @see MouseListener#mouseDoubleClicked(MouseEvent)
- */
- public void mouseDoubleClicked(final MouseEvent me) {
- // do nothing.
- }
-
- /**
- * @see MouseListener#mousePressed(MouseEvent)
- */
- public void mousePressed(final MouseEvent me) {
- if (clickedImage != null) {
- ActionTriggerImageFigure.this.setImage(clickedImage);
- }
- trigger();
- me.consume();
- }
-
- /**
- * @see MouseListener#mouseReleased(MouseEvent)
- */
- public void mouseReleased(final MouseEvent me) {
- if (getImage() == clickedImage) {
- setImage(imageWFocus);
- }
- }
-
- }
-
- /**
- * Trigger all actions.
- */
- public void trigger() {
- for (Runnable action : actions) {
- action.run();
- }
- }
-
- /**
- * Add an action.
- *
- * @param simpleAction
- * the action to add.
- */
- public void addAction(Runnable simpleAction) {
- this.actions.add(simpleAction);
- }
-
- /**
- * Add an action at the specified index.
- *
- * @param simpleAction
- * the action to add.
- * @param index
- * index at which the specified element is to be inserted
- */
- public void addAction(Runnable simpleAction, final int index) {
- this.actions.add(index, simpleAction);
- }
-
- /**
- * Remove all actions.
- */
- public void clearActions() {
- this.actions.clear();
- }
-
- /**
- * Remove an action.
- *
- * @param simpleAction
- * the action to remove.
- */
- public void removeAction(Runnable simpleAction) {
- this.actions.remove(simpleAction);
- }
-
- /**
- * Return an iterator that iterates on actions.
- *
- * @return an iterator that iterates on actions.
- */
- public Iterator<Runnable> iterActions() {
- return this.actions.iterator();
- }
-
- /**
- * Define the image that is shown when the user clicks on the figure.
- *
- * @param clickedImage
- * the image that is shown when the user clicks on the figure.
- */
- public void setClickedImage(final Image clickedImage) {
- this.clickedImage = clickedImage;
- }
-
-}
diff --git a/plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF
index bd4ccef9de..aac33b58be 100644
--- a/plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.sample.ecore.design/META-INF/MANIFEST.MF
@@ -21,7 +21,7 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.8.2",
org.eclipse.gmf.runtime.diagram.ui;bundle-version="1.6.0",
org.eclipse.gmf.runtime.diagram.ui.resources.editor;bundle-version="1.4.1",
org.eclipse.ui.navigator;bundle-version="3.5.200",
- com.google.guava;bundle-version="11.0.0",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.sirius.diagram.ui;bundle-version="1.0.0"
Bundle-ManifestVersion: 2
Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.sirius.synchronizer/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.synchronizer/META-INF/MANIFEST.MF
index 3a7810ace2..b0a21fd73c 100644
--- a/plugins/org.eclipse.sirius.synchronizer/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.synchronizer/META-INF/MANIFEST.MF
@@ -9,4 +9,4 @@ Bundle-Localization: plugin
Export-Package: org.eclipse.sirius.synchronizer;version="1.0.0",
org.eclipse.sirius.synchronizer.internal;x-internal:=true;version="1.0.0"
Require-Bundle: org.eclipse.emf.ecore;bundle-version="2.8.3",
- com.google.guava;bundle-version="[11.0.0,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
diff --git a/plugins/org.eclipse.sirius.table.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.table.ui/META-INF/MANIFEST.MF
index 0eef52bd4b..218e25d53b 100644
--- a/plugins/org.eclipse.sirius.table.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.table.ui/META-INF/MANIFEST.MF
@@ -42,7 +42,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.300",
org.eclipse.emf.edit.ui;bundle-version="2.8.0",
org.eclipse.emf.workspace;bundle-version="1.5.1",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.sirius.common.ui;bundle-version="1.0.0",
org.eclipse.nebula.paperclips.core;bundle-version="2.0.0"
Eclipse-LazyStart: true
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
index 5454521596..2bbcf58e1f 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/DTableViewerManager.java
@@ -67,6 +67,7 @@ import org.eclipse.sirius.table.ui.tools.internal.editor.provider.DTableContentP
import org.eclipse.sirius.table.ui.tools.internal.editor.provider.DTableDecoratingLabelProvider;
import org.eclipse.sirius.table.ui.tools.internal.editor.provider.DTableLineLabelProvider;
import org.eclipse.sirius.table.ui.tools.internal.editor.provider.DTargetColumnEditingSupport;
+import org.eclipse.sirius.table.ui.tools.internal.editor.provider.TableUIUpdater;
import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTableViewerManager;
import org.eclipse.sirius.ui.tools.internal.editor.DTableColumnViewerEditorActivationStrategy;
@@ -179,6 +180,8 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
private EditorCreateTargetColumnMenuAction createTargetColumnMenu = new EditorCreateTargetColumnMenuAction();
+ private TableUIUpdater tableUIUpdater;
+
private DTableContentProvider dTableContentProvider;
private DTableMenuListener actualMenuListener;
@@ -290,13 +293,13 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
// Next columns
int index = 1;
-
for (final DColumn column : ((DTable) dRepresentation).getColumns()) {
addNewColumn(column, index++);
}
treeViewer.setUseHashlookup(true);
- dTableContentProvider = new DTableContentProvider(getSession(), this);
+ tableUIUpdater = new TableUIUpdater(this);
+ dTableContentProvider = new DTableContentProvider();
treeViewer.setContentProvider(dTableContentProvider);
// The input for the table viewer is the instance of DTable
treeViewer.setInput(dRepresentation);
@@ -327,8 +330,8 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
// Create a TreeViewerEditor with focusable cell
TreeViewerEditor.create(treeViewer, focusCellManager, new DTableColumnViewerEditorActivationStrategy(treeViewer), ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
-
- // Set after the setInput to avoid layout call it several time for nothing at opening
+ // Set after the setInput to avoid layout call it several time for
+ // nothing at opening
headerTreeColumn.getColumn().addControlListener(tableViewerListener);
}
@@ -816,6 +819,8 @@ public class DTableViewerManager extends AbstractDTableViewerManager {
public void dispose() {
treeViewer.removeTreeListener(tableViewerListener);
tableViewerListener = null;
+ tableUIUpdater.dispose();
+ tableUIUpdater = null;
dTableContentProvider.dispose();
dTableContentProvider = null;
super.dispose();
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentProvider.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentProvider.java
index 605d5908c4..4b84a1f0bf 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentProvider.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentProvider.java
@@ -15,12 +15,9 @@ import java.util.List;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
-
-import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.table.metamodel.table.DLine;
import org.eclipse.sirius.table.metamodel.table.DTable;
import org.eclipse.sirius.table.metamodel.table.LineContainer;
-import org.eclipse.sirius.table.ui.tools.internal.editor.DTableViewerManager;
/**
* The provider for the content of the table.
@@ -29,27 +26,6 @@ import org.eclipse.sirius.table.ui.tools.internal.editor.DTableViewerManager;
*/
public class DTableContentProvider implements ITreeContentProvider {
- private Session session;
-
- /** The EMF adapter */
- private DTableContentAdapter dTableContentAdapter;
-
- /**
- * Creates a table content provider.
- *
- * @param session
- * the {@link Session} on which this
- * {@link DTableContentProvider} is used.
- * @param dTableViewerManager
- * the {@link DTableViewerManager} managing the DTableViewer for
- * which provide a content
- */
- public DTableContentProvider(Session session, DTableViewerManager dTableViewerManager) {
- this.session = session;
- this.dTableContentAdapter = new DTableContentAdapter(dTableViewerManager);
- this.session.getTransactionalEditingDomain().addResourceSetListener(dTableContentAdapter);
- }
-
/**
* Returns the elements to display in the viewer (only the visible one).
*
@@ -141,7 +117,5 @@ public class DTableContentProvider implements ITreeContentProvider {
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
- session.getTransactionalEditingDomain().removeResourceSetListener(dTableContentAdapter);
- dTableContentAdapter = null;
}
}
diff --git a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentAdapter.java b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/TableUIUpdater.java
index 649e8168f8..d7b495f917 100644
--- a/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/DTableContentAdapter.java
+++ b/plugins/org.eclipse.sirius.table.ui/src/org/eclipse/sirius/table/ui/tools/internal/editor/provider/TableUIUpdater.java
@@ -46,12 +46,11 @@ import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.PlatformUI;
/**
- * This class is an EMF Adapter which listen change in the model to update a
- * {@link DTableTreeViewer}.
+ * A class responsible to update the UI part of a {@link DTable}.
*
* @author lredor
*/
-public class DTableContentAdapter extends ResourceSetListenerImpl {
+public class TableUIUpdater extends ResourceSetListenerImpl {
private DTableViewerManager dTableViewerManager;
@@ -66,9 +65,10 @@ public class DTableContentAdapter extends ResourceSetListenerImpl {
* {@link DTableTreeViewer} to update according to {@link DTable}
* model changes.
*/
- public DTableContentAdapter(DTableViewerManager dTableViewerManager) {
+ public TableUIUpdater(DTableViewerManager dTableViewerManager) {
this.dTableViewerManager = dTableViewerManager;
this.dTableTreeViewer = (DTableTreeViewer) dTableViewerManager.getTreeViewer();
+ dTableViewerManager.getEditingDomain().addResourceSetListener(this);
}
/**
@@ -564,4 +564,13 @@ public class DTableContentAdapter extends ResourceSetListenerImpl {
}
}
+ /**
+ * Dispose this {@link TableUIUpdater}.
+ */
+ public void dispose() {
+ if (getTarget() != null) {
+ getTarget().removeResourceSetListener(this);
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.table/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.table/META-INF/MANIFEST.MF
index 9d9f776845..6273829efc 100644
--- a/plugins/org.eclipse.sirius.table/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.table/META-INF/MANIFEST.MF
@@ -41,7 +41,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.emf.ecore.xmi;bundle-version="2.8.1",
org.eclipse.emf.transaction;bundle-version="1.4.0",
org.eclipse.jface;bundle-version="3.8.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Eclipse-LazyStart: true
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.sirius.table.tools.internal.TablePlugin
diff --git a/plugins/org.eclipse.sirius.tests.support/.checkstyle b/plugins/org.eclipse.sirius.tests.support/.checkstyle
new file mode 100644
index 0000000000..de41933953
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.checkstyle
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <local-check-config name="Sirius Checks" location="/org.eclipse.sirius.settings/CheckstyleConfiguration.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="all" enabled="true" check-config-name="Sirius Checks" local="true">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+ <filter name="FilesFromPackage" enabled="true">
+ <filter-data value="src-gen"/>
+ </filter>
+</fileset-config>
diff --git a/plugins/org.eclipse.sirius.tests.support/.classpath b/plugins/org.eclipse.sirius.tests.support/.classpath
new file mode 100644
index 0000000000..39819a3af8
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/sirius/**"/>
+ <accessrule kind="nonaccessible" pattern="junit/framework/Assert"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.sirius.tests.support/.project b/plugins/org.eclipse.sirius.tests.support/.project
new file mode 100644
index 0000000000..bf2ec7e95b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.sirius.tests.support</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.resources.prefs b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..a04232be36
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Wed May 11 10:02:49 CEST 2011
+eclipse.preferences.version=1
+encoding/<project>=US-ASCII
diff --git a/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.runtime.prefs b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000000..923e76452c
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Wed May 11 10:02:49 CEST 2011
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..c537b63063
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.sirius.tests.support/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tests.support/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..4447bcbebd
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.sirius.tests.support;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.sirius.tests.support.internal.SiriusTestsSupportPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.junit;bundle-version="[4.0.0,5.0.0)",
+ org.eclipse.sirius.common,
+ org.eclipse.sirius.common.ui,
+ org.eclipse.sirius.diagram,
+ org.eclipse.sirius.ecore.extender,
+ org.eclipse.gmf.runtime.diagram.ui,
+ org.eclipse.core.filebuffers,
+ com.google.guava;bundle-version="[11.0.2,16.0)",
+ org.eclipse.emf.common.ui;bundle-version="2.3.1",
+ org.eclipse.ui.ide,
+ org.eclipse.sirius.diagram.ui
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-Localization: plugin
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.sirius.tests.support.api,
+ org.eclipse.sirius.tests.support.command,
+ org.eclipse.sirius.tests.support.internal;x-internal:=true,
+ org.eclipse.sirius.tests.support.internal.helper;x-friends:="org.eclipse.sirius.tree.tests"
+Import-Package: org.eclipse.sirius.ext.base;version="1.0.0"
diff --git a/plugins/org.eclipse.sirius.tests.support/build.properties b/plugins/org.eclipse.sirius.tests.support/build.properties
new file mode 100644
index 0000000000..62abd569f1
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/build.properties
@@ -0,0 +1,16 @@
+# ====================================================================
+# Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms 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
+# ====================================================================
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties
+additional.bundles = org.eclipse.ui.ide
diff --git a/plugins/org.eclipse.sirius.tests.support/plugin.properties b/plugins/org.eclipse.sirius.tests.support/plugin.properties
new file mode 100644
index 0000000000..a2a7aaa851
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/plugin.properties
@@ -0,0 +1,12 @@
+# ====================================================================
+# Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms 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 = Sirius JUnit Tests Support (Incubation)
+providerName = Eclipse.org
diff --git a/plugins/org.eclipse.sirius.tests.support/pom.xml b/plugins/org.eclipse.sirius.tests.support/pom.xml
new file mode 100644
index 0000000000..5364cb8b28
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.sirius</groupId>
+ <artifactId>sirius-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../packaging/org.eclipse.sirius.parent</relativePath>
+ </parent>
+
+ <artifactId>org.eclipse.sirius.tests.support</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+</project>
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractColorReferenceTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractColorReferenceTestCase.java
new file mode 100644
index 0000000000..a3a83709ed
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractColorReferenceTestCase.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
+import org.junit.Assert;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Test cardinality and initialization of Color references.
+ *
+ * @author mporhel
+ */
+public abstract class AbstractColorReferenceTestCase extends TestCase {
+
+ private Collection<EReference> colorReferences;
+
+ private Collection<EClass> classesWithColorReferences;
+
+ private EPackage basePackage;
+
+ private final Predicate<EReference> isColorReference = new Predicate<EReference>() {
+ @Override
+ public boolean apply(EReference input) {
+ return !input.isContainment() && DescriptionPackage.eINSTANCE.getColorDescription().isSuperTypeOf(input.getEReferenceType());
+ }
+ };
+
+ public EPackage getBasePackage() {
+ return basePackage;
+ }
+
+ public void setBasePackage(EPackage basePackage) {
+ this.basePackage = basePackage;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ colorReferences = Sets.newLinkedHashSet();
+ classesWithColorReferences = Sets.newLinkedHashSet();
+ Assert.assertNotNull("Base package should not be null.", basePackage);
+ lookForColorReferences(basePackage);
+ }
+
+ private void lookForColorReferences(EPackage pkg) {
+ for (EClass eclass : Iterables.filter(pkg.getEClassifiers(), EClass.class)) {
+ lookForColorReferences(eclass);
+ }
+ for (EPackage subPkg : pkg.getESubpackages()) {
+ lookForColorReferences(subPkg);
+ }
+ }
+
+ private void lookForColorReferences(EClass eclass) {
+ Iterable<EReference> allColorReferences = Iterables.filter(eclass.getEAllReferences(), isColorReference);
+ Iterables.addAll(colorReferences, allColorReferences);
+ if (!Iterables.isEmpty(allColorReferences) && !eclass.isAbstract() && !eclass.isInterface()) {
+ classesWithColorReferences.add(eclass);
+ }
+ }
+
+ /**
+ * Test that all color references are required.
+ */
+ public void testColorReferencesCardinality() {
+ List<EReference> referencesWithWrongCardinality = Lists.newArrayList();
+
+ Predicate<EReference> shouldBeRequired = new Predicate<EReference>() {
+ @Override
+ public boolean apply(EReference input) {
+ return !input.isRequired();
+ }
+ };
+
+ Iterables.addAll(referencesWithWrongCardinality, Iterables.filter(colorReferences, shouldBeRequired));
+ Assert.assertTrue(getMessage(referencesWithWrongCardinality), referencesWithWrongCardinality.isEmpty());
+ }
+
+ /**
+ * Test that all color references are set by the factory.
+ */
+ public void testColorReferencesInitialization() {
+ StringBuilder sb = new StringBuilder();
+ for (EClass clazz : classesWithColorReferences) {
+ EObject created = EcoreUtil.create(clazz);
+ for (EReference colorRef : Iterables.filter(clazz.getEAllReferences(), isColorReference)) {
+ if (!created.eIsSet(colorRef) || created.eGet(colorRef) == null) {
+ sb.append(" . " + clazz.getName() + "#" + colorRef.getName() + "\n");
+ }
+ }
+ }
+ TestCase.assertTrue("Some color references need initialization:\n" + sb.toString(), sb.length() == 0);
+ }
+
+ private String getMessage(List<EReference> referencesWithWrongCardinality) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(referencesWithWrongCardinality.size());
+ sb.append(" color references should be required, please modify their cardinality:");
+ for (EReference ref : referencesWithWrongCardinality) {
+ sb.append("\n . ");
+ sb.append(ref.eResource().getURIFragment(ref));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ basePackage = null;
+ colorReferences.clear();
+ classesWithColorReferences.clear();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractInterpretedExpressionTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractInterpretedExpressionTestCase.java
new file mode 100644
index 0000000000..2294786082
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractInterpretedExpressionTestCase.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
+import org.junit.Assert;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Test documentation of interpreted expressions.
+ *
+ * @author mporhel
+ */
+public abstract class AbstractInterpretedExpressionTestCase extends TestCase {
+
+ private static final String RETURN_TYPE = "http://www.eclipse.org/sirius/interpreted/expression/returnType";
+
+ private static final String VARIABLES = "http://www.eclipse.org/sirius/interpreted/expression/variables";
+
+ private Collection<EAttribute> interpretedExpressions;
+
+ private EPackage basePackage;
+
+ private final Predicate<EAttribute> isInterpretedExpression = new Predicate<EAttribute>() {
+ @Override
+ public boolean apply(EAttribute input) {
+ return DescriptionPackage.eINSTANCE.getInterpretedExpression().equals(input.getEAttributeType());
+ }
+ };
+
+ public EPackage getBasePackage() {
+ return basePackage;
+ }
+
+ public void setBasePackage(EPackage basePackage) {
+ this.basePackage = basePackage;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ interpretedExpressions = Sets.newLinkedHashSet();
+ Assert.assertNotNull("Base package should not be null.", basePackage);
+ handleEPackage(basePackage);
+ }
+
+ private void handleEPackage(EPackage pkg) {
+ for (EClass eclass : Iterables.filter(pkg.getEClassifiers(), EClass.class)) {
+ handleEClass(eclass);
+ }
+ for (EPackage subPkg : pkg.getESubpackages()) {
+ handleEPackage(subPkg);
+ }
+ }
+
+ private void handleEClass(EClass eclass) {
+ Iterables.addAll(interpretedExpressions, Iterables.filter(eclass.getEAttributes(), isInterpretedExpression));
+ }
+
+ /**
+ * Test that all interpreted expression has a variable documentation.
+ */
+ public void testVariablesInterpretedExpressionEAnnotation() {
+ List<EAttribute> nonDocumented = Lists.newArrayList();
+
+ Predicate<EAttribute> needsDocumentation = new Predicate<EAttribute>() {
+ @Override
+ public boolean apply(EAttribute input) {
+ EAnnotation eAnnotation = input.getEAnnotation(AbstractInterpretedExpressionTestCase.VARIABLES);
+ return eAnnotation == null;
+ }
+ };
+
+ Iterables.addAll(nonDocumented, Iterables.filter(interpretedExpressions, needsDocumentation));
+ Assert.assertTrue(getMessage(nonDocumented, AbstractInterpretedExpressionTestCase.VARIABLES), nonDocumented.isEmpty());
+ }
+
+ /**
+ * Test that all interpreted expression has a result type documentation.
+ */
+ public void testReturnTypeInterpretedExpressionEAnnotation() {
+ List<EAttribute> nonDocumented = Lists.newArrayList();
+
+ Predicate<EAttribute> needsReturnType = new Predicate<EAttribute>() {
+ @Override
+ public boolean apply(EAttribute input) {
+ EAnnotation eAnnotation = input.getEAnnotation(AbstractInterpretedExpressionTestCase.RETURN_TYPE);
+ return eAnnotation == null || eAnnotation.getDetails().isEmpty();
+ }
+ };
+
+ Iterables.addAll(nonDocumented, Iterables.filter(interpretedExpressions, needsReturnType));
+ Assert.assertTrue(getMessage(nonDocumented, AbstractInterpretedExpressionTestCase.RETURN_TYPE), nonDocumented.isEmpty());
+ }
+
+ private String getMessage(List<EAttribute> nonDocumented, String source) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(nonDocumented.size());
+ sb.append(" interpreted expression(s) needs variable EAnnotation ");
+ sb.append(source);
+ sb.append(": ");
+ for (EAttribute attr : nonDocumented) {
+ sb.append("\n . ");
+ sb.append(attr.eResource().getURIFragment(attr));
+ }
+ return sb.toString();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ interpretedExpressions.clear();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractItemProviderAdapterFactoryRegistryTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractItemProviderAdapterFactoryRegistryTestCase.java
new file mode 100644
index 0000000000..c1d6895c1e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/AbstractItemProviderAdapterFactoryRegistryTestCase.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory.Descriptor;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory.Descriptor.Registry;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Test exposure of item provider adapter factories.
+ *
+ * @author mporhel
+ */
+public abstract class AbstractItemProviderAdapterFactoryRegistryTestCase extends TestCase {
+
+ private static final String THE_ITEM_PROVIDER_ADAPTER_FACTORY_OF_THE_PACKAGE = "The item provider adapter factory of the package ";
+
+ private final Registry registry = ComposedAdapterFactory.Descriptor.Registry.INSTANCE;
+
+ private final Collection<EPackage> exposedItemProvidersAdapterFactories = Sets.newLinkedHashSet();
+
+ private final Collection<EPackage> nonExposedItemProvidersAdapterFactories = Sets.newLinkedHashSet();
+
+ private EPackage basePackage;
+
+ private final Predicate<EPackage> shouldBeExposed = new Predicate<EPackage>() {
+ @Override
+ public boolean apply(EPackage input) {
+ return exposedItemProvidersAdapterFactories.contains(input);
+ }
+ };
+
+ private final Predicate<EPackage> shouldNotBeExposed = new Predicate<EPackage>() {
+ @Override
+ public boolean apply(EPackage input) {
+ return nonExposedItemProvidersAdapterFactories.contains(input);
+ }
+ };
+
+ private final Function<EPackage, Collection<?>> getKey = new Function<EPackage, Collection<?>>() {
+ @Override
+ public Collection<?> apply(EPackage from) {
+ Collection<Object> key = Lists.newArrayList();
+ key.add(from);
+ key.add(IItemLabelProvider.class);
+ return key;
+ };
+ };
+
+ public EPackage getBasePackage() {
+ return basePackage;
+ }
+
+ public void setBasePackage(EPackage basePackage) {
+ this.basePackage = basePackage;
+ }
+
+ /**
+ * Set packages that should have their item provider adapter factory
+ * exposed.
+ *
+ * @param packages
+ * packages with exposed item provider adapter factory.
+ */
+ public void setPackagesWithExposedAdapterFactory(Collection<EPackage> packages) {
+ exposedItemProvidersAdapterFactories.addAll(packages);
+ }
+
+ /**
+ * Set packages that should have their item provider adapter factory
+ * exposed.
+ *
+ * @param packages
+ * packages with exposed item provider adapter factory.
+ */
+ public void setPackagesWithNonExposedAdapterFactory(Collection<EPackage> packages) {
+ nonExposedItemProvidersAdapterFactories.addAll(packages);
+ }
+
+ /**
+ * Allow to declare base package and registered item provider adapter
+ * factories.
+ */
+ public abstract void initPackages();
+
+ @Override
+ protected void setUp() throws Exception {
+ initPackages();
+ super.setUp();
+ TestCase.assertNotNull("Base package should not be null.", basePackage);
+ }
+
+ /**
+ * Test that all interpreted expression has a variable documentation.
+ */
+ public void testExposedAdapterFactories() {
+ testEPackageExposed(basePackage);
+ }
+
+ private void testEPackageExposed(EPackage pkg) {
+
+ Descriptor descriptor = registry.getDescriptor(getKey.apply(pkg));
+ String label = pkg.getName() + " (" + pkg.getNsURI() + ") ";
+
+ boolean exposedExpected = shouldBeExposed.apply(pkg);
+ if (exposedExpected) {
+ TestCase.assertNotNull(AbstractItemProviderAdapterFactoryRegistryTestCase.THE_ITEM_PROVIDER_ADAPTER_FACTORY_OF_THE_PACKAGE + label + "should be exposed.", descriptor);
+
+ AdapterFactory adapterFactory = descriptor.createAdapterFactory();
+ TestCase.assertNotNull("Error creating while creating the item provider adapter factory of the package " + label, adapterFactory);
+ }
+
+ boolean notExposedExpected = shouldNotBeExposed.apply(pkg);
+ if (notExposedExpected) {
+ TestCase.assertNull(AbstractItemProviderAdapterFactoryRegistryTestCase.THE_ITEM_PROVIDER_ADAPTER_FACTORY_OF_THE_PACKAGE + label + "should not be exposed.", descriptor);
+ }
+
+ if (exposedExpected && notExposedExpected || !exposedExpected && !notExposedExpected) {
+ TestCase.fail(AbstractItemProviderAdapterFactoryRegistryTestCase.THE_ITEM_PROVIDER_ADAPTER_FACTORY_OF_THE_PACKAGE + label
+ + "is not known or invalid for the current test. Please check with the team if it should be exposed or not and then complete the test.");
+ }
+
+ for (EPackage subPkg : pkg.getESubpackages()) {
+ testEPackageExposed(subPkg);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ exposedItemProvidersAdapterFactories.clear();
+ basePackage = null;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/DiagramComponentizationTestSupport.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/DiagramComponentizationTestSupport.java
new file mode 100644
index 0000000000..87b18ab48e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/DiagramComponentizationTestSupport.java
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.util.List;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.diagram.business.api.componentization.DiagramComponentizationManager;
+import org.eclipse.sirius.diagram.description.ContainerMapping;
+import org.eclipse.sirius.diagram.description.DiagramDescription;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
+import org.eclipse.sirius.diagram.description.Layer;
+import org.eclipse.sirius.diagram.description.tool.ToolGroup;
+import org.eclipse.sirius.diagram.description.tool.ToolSection;
+import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
+import org.eclipse.sirius.viewpoint.description.tool.ToolEntry;
+
+/**
+ *
+ * This class is a workaround to avoid adapting many tests which don't have a
+ * Session yet used to retrieve the list of enabled layers or tools. Previously
+ * the session itself was passed and the DiagramComponentizationManager would
+ * "fail gracefully" when trying to retrieve the enabled viewpoints. Now the
+ * DiagramComponentizationManager api requires the list of selected viewpoints
+ * and not the session itself and the tests would just fail with a NPE without
+ * this extra indirection.
+ *
+ * @author Cedric Brun <cedric.brun@obeo.fr>
+ *
+ */
+public final class DiagramComponentizationTestSupport {
+
+ private DiagramComponentizationTestSupport() {
+
+ }
+
+ /**
+ * Get all the layers of a diagram description.
+ *
+ * @param session
+ * the session
+ * @param diagram
+ * the diagram description
+ * @return all the available layers
+ */
+ public static List<Layer> getAllLayers(Session session, final DiagramDescription diagram) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getAllLayers(session.getSelectedViewpoints(false), diagram);
+ } else {
+ return new DiagramComponentizationManager().getAllLayers(null, diagram);
+ }
+ }
+
+ /**
+ * Get all the edge mappings available for a diagram description.
+ *
+ * @param session
+ * the session
+ * @param diagram
+ * the diagram description
+ * @return all the available edge mappings
+ */
+ public static List<AbstractToolDescription> getAllTools(Session session, final DiagramDescription diagram) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getAllTools(session.getSelectedViewpoints(false), diagram);
+ } else {
+ return new DiagramComponentizationManager().getAllTools(null, diagram);
+ }
+ }
+
+ /**
+ * Get the tool entries available for a section.
+ *
+ * @param session
+ * the session.
+ * @param section
+ * the section
+ * @return all the available tools
+ */
+ public static List<ToolEntry> getToolEntries(Session session, ToolSection section) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getToolEntries(session.getSelectedViewpoints(false), section);
+ } else {
+ return new DiagramComponentizationManager().getToolEntries(null, section);
+ }
+ }
+
+ /**
+ * Get all the container mappings available for a diagram description.
+ *
+ * @param session
+ * the session
+ * @param diagram
+ * the diagram description
+ * @return all the available node mappings
+ */
+ public static List<ContainerMapping> getAllContainerMappings(Session session, DiagramDescription diagram) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getAllContainerMappings(session.getSelectedViewpoints(false), diagram);
+ } else {
+ return new DiagramComponentizationManager().getAllContainerMappings(null, diagram);
+ }
+ }
+
+ /**
+ * Get all the edge mappings available for a diagram description.
+ *
+ * @param session
+ * the session
+ * @param description
+ * the diagram description
+ * @return all the available edge mappings
+ */
+ public static List<EdgeMapping> getAllEdgeMappings(Session session, DiagramDescription description) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getAllEdgeMappings(session.getSelectedViewpoints(false), description);
+ } else {
+ return new DiagramComponentizationManager().getAllEdgeMappings(null, description);
+ }
+ }
+
+ /**
+ * Get all the sections available for a diagram description.
+ *
+ * @param session
+ * the session
+ * @param diagram
+ * the diagram description
+ * @return all the available sections
+ */
+ public static List<ToolSection> getRootPaletteSections(Session session, DiagramDescription diagram) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getRootPaletteSections(session.getSelectedViewpoints(false), diagram);
+ } else {
+ return new DiagramComponentizationManager().getRootPaletteSections(null, diagram);
+ }
+ }
+
+ /**
+ * Get all the tool entries available for a section. The function will check
+ * direct and indirect children.
+ *
+ * @param session
+ * the viewpoints to consider.
+ * @param section
+ * the section
+ * @return all the available tools
+ */
+ public static List<ToolEntry> getAllToolEntries(Session session, ToolSection section) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getAllToolEntries(session.getSelectedViewpoints(false), section);
+ } else {
+ return new DiagramComponentizationManager().getAllToolEntries(null, section);
+ }
+ }
+
+ /**
+ * Get the tools available for a tool group.
+ *
+ * @param session
+ * the viewpoints to consider.
+ * @param toolGroup
+ * the group of tools
+ * @return the available tools
+ */
+ public static List<AbstractToolDescription> getTools(Session session, ToolGroup toolGroup) {
+ if (session != null) {
+ return new DiagramComponentizationManager().getTools(session.getSelectedViewpoints(false), toolGroup);
+ } else {
+ return new DiagramComponentizationManager().getTools(null, toolGroup);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EclipseTestsSupportHelper.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EclipseTestsSupportHelper.java
new file mode 100644
index 0000000000..aff45af01e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EclipseTestsSupportHelper.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.tests.support.internal.helper.EclipseTestsSupportHelperImpl;
+
+/**
+ * Instance managing the EclipseTestsSupportHelper.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public interface EclipseTestsSupportHelper {
+ /**
+ * Singleton instance of the eclipse tests support.
+ */
+ EclipseTestsSupportHelper INSTANCE = EclipseTestsSupportHelperImpl.INSTANCE;
+
+ /**
+ * Create a project.
+ *
+ * @param projectName
+ * name of the created project
+ *
+ * @return a new created Project
+ */
+ IProject createProject(final String projectName);
+
+ /**
+ * Create a project.
+ *
+ * @param projectName
+ * name of the created project
+ * @param createAndOpenBlankRepresentationsFile
+ * true if a blank representations file must be created and open,
+ * false otherwise
+ *
+ * @return a new created Project
+ */
+ IProject createModelingProject(final String projectName, final boolean createAndOpenBlankRepresentationsFile);
+
+ /**
+ * Create a resource in a project.
+ *
+ * @param set
+ * the resource set
+ * @param projectName
+ * name of the project
+ * @param fileName
+ * name of the file to create
+ * @return the created resource
+ */
+ Resource createResourceInProject(final ResourceSet set, final String projectName, final String fileName);
+
+ /**
+ * Delete the project.
+ *
+ * @param projectName
+ * name of the project to delete.
+ */
+ void deleteProject(final String projectName);
+
+ /**
+ * Copy a file from a plug-in in the workspace.
+ *
+ * @param bundleID
+ * The ID of the bundle or project containing the source file
+ * @param projectRelativePath
+ * The project relative path of the source file
+ * @param destinationWorkspaceRelativePath
+ * the destination path
+ */
+ void copyFile(final String bundleID, final String projectRelativePath, final String destinationWorkspaceRelativePath);
+
+ /**
+ * Copy a file from a plug-in in the workspace.
+ *
+ * @param bundleID
+ * The ID of the bundle or project containing the source file
+ * @param projectRelativePath
+ * The project relative path of the source file
+ * @param destinationWorkspaceRelativePath
+ * the destination path
+ * @param refreshAfterCopy
+ * should refresh destination file after copy
+ */
+ void copyFile(final String bundleID, final String projectRelativePath, final String destinationWorkspaceRelativePath, final boolean refreshAfterCopy);
+
+ /**
+ * Copy a file from a plug-in in the workspace.
+ *
+ * @param relativePath
+ * The relative path of the source file
+ * @param destinationWorkspaceRelativePath
+ * the destination path
+ */
+ void copyFile(final String relativePath, final String destinationWorkspaceRelativePath);
+
+ /**
+ * Copy a file to another one.
+ *
+ * @param sourceFile
+ * The source file
+ * @param destFile
+ * The destination file
+ * @throws IOException
+ * In case of problem
+ */
+ void copyFile(final File sourceFile, final File destFile) throws IOException;
+
+ /**
+ * Copy a file from a plug-in in the workspace.
+ *
+ * @param destinationWorkspaceRelativePath
+ * the destination path, relative to workspace
+ * @param readOnly
+ * <code>true</code> if specified file must be read-only,
+ * <code>false</code> otherwise.
+ */
+ void changeFileReadOnlyAttribute(final String destinationWorkspaceRelativePath, boolean readOnly);
+
+ /**
+ * Delete this file (launch in a WorkspaceModifyOperation).
+ *
+ * @param workspaceRelativePath
+ * The path of the file to delete, relative to the workspace.
+ */
+ void deleteFile(String workspaceRelativePath);
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsHashCodeTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsHashCodeTestCase.java
new file mode 100644
index 0000000000..fbad64c1eb
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsHashCodeTestCase.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.junit.Assert;
+
+/**
+ * Base class for equality tests.
+ *
+ * @author dlecan
+ */
+public abstract class EqualsHashCodeTestCase extends EqualsTestCase {
+
+ /**
+ * Tests the <code>hashCode</code> contract.
+ */
+ public final void testHashCodeContract() {
+ Assert.assertEquals("1st vs. 2nd", eq1.hashCode(), eq2.hashCode());
+ Assert.assertEquals("1st vs. 3rd", eq1.hashCode(), eq3.hashCode());
+ Assert.assertEquals("2nd vs. 3rd", eq2.hashCode(), eq3.hashCode());
+ }
+
+ /**
+ * Tests the consistency of <code>hashCode</code>.
+ */
+ public final void testHashCodeIsConsistentAcrossInvocations() {
+ final int eq1Hash = eq1.hashCode();
+ final int eq2Hash = eq2.hashCode();
+ final int eq3Hash = eq3.hashCode();
+ final int neqHash = neq.hashCode();
+
+ for (int i = 0; i < EqualsTestCase.NUM_ITERATIONS; ++i) {
+ Assert.assertEquals("1st equal instance", eq1Hash, eq1.hashCode());
+ Assert.assertEquals("2nd equal instance", eq2Hash, eq2.hashCode());
+ Assert.assertEquals("3rd equal instance", eq3Hash, eq3.hashCode());
+ Assert.assertEquals("not-equal instance", neqHash, neq.hashCode());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsTestCase.java
new file mode 100644
index 0000000000..cae3e89c48
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/EqualsTestCase.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+/**
+ * Base class for equality tests.
+ *
+ * @author dlecan
+ */
+public abstract class EqualsTestCase extends TestCase {
+ /**
+ * Number of iterations.
+ */
+ protected static final int NUM_ITERATIONS = 20;
+
+ /**
+ * Object.
+ */
+ protected Object eq1;
+
+ /**
+ * Object.
+ */
+ protected Object eq2;
+
+ /**
+ * Object.
+ */
+ protected Object eq3;
+
+ /**
+ * Object.
+ */
+ protected Object neq;
+
+ /**
+ * Creates and returns an instance of the class under test.
+ *
+ * @return a new instance of the class under test; each object returned from
+ * this method should compare equal to each other.
+ * @throws Exception
+ * Creation error.
+ */
+ protected abstract Object createInstance() throws Exception;
+
+ /**
+ * Creates and returns an instance of the class under test.
+ *
+ * @return a new instance of the class under test; each object returned from
+ * this method should compare equal to each other, but not to the
+ * objects returned from {@link #createInstance() createInstance}.
+ * @throws Exception
+ * Creation error.
+ */
+ protected abstract Object createNotEqualInstance() throws Exception;
+
+ /**
+ * Sets up the test fixture.
+ *
+ * @throws Exception
+ * Setup error.
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ eq1 = createInstance();
+ eq2 = createInstance();
+ eq3 = createInstance();
+ neq = createNotEqualInstance();
+
+ // We want these assertions to yield errors, not failures.
+ try {
+ Assert.assertNotNull("createInstance() returned null", eq1);
+ Assert.assertNotNull("2nd createInstance() returned null", eq2);
+ Assert.assertNotNull("3rd createInstance() returned null", eq3);
+ Assert.assertNotNull("createNotEqualInstance() returned null", neq);
+
+ Assert.assertNotSame(eq1, eq2);
+ Assert.assertNotSame(eq1, eq3);
+ Assert.assertNotSame(eq1, neq);
+ Assert.assertNotSame(eq2, eq3);
+ Assert.assertNotSame(eq2, neq);
+ Assert.assertNotSame(eq3, neq);
+
+ Assert.assertEquals("1st and 2nd equal instances of different classes", eq1.getClass(), eq2.getClass());
+ Assert.assertEquals("1st and 3rd equal instances of different classes", eq1.getClass(), eq3.getClass());
+ Assert.assertEquals("1st equal instance and not-equal instance of different classes", eq1.getClass(), neq.getClass());
+ } catch (final AssertionFailedError ex) {
+ throw new IllegalArgumentException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Tests whether <code>equals</code> holds up against a new
+ * <code>Object</code> (should always be <code>false</code>).
+ */
+ public final void testEqualsAgainstNewObject() {
+ final Object o = new Object();
+
+ SiriusAssert.assertNotEquals(eq1, o);
+ SiriusAssert.assertNotEquals(eq2, o);
+ SiriusAssert.assertNotEquals(eq3, o);
+ SiriusAssert.assertNotEquals(neq, o);
+ }
+
+ /**
+ * Tests whether <code>equals</code> holds up against <code>null</code>.
+ */
+ public final void testEqualsAgainstNull() {
+ SiriusAssert.assertNotEquals("1st vs. null", eq1, null);
+ SiriusAssert.assertNotEquals("2nd vs. null", eq2, null);
+ SiriusAssert.assertNotEquals("3rd vs. null", eq3, null);
+ SiriusAssert.assertNotEquals("not-equal vs. null", neq, null);
+ }
+
+ /**
+ * Tests whether <code>equals</code> holds up against objects that should
+ * not compare equal.
+ */
+ public final void testEqualsAgainstUnequalObjects() {
+ SiriusAssert.assertNotEquals("1st vs. not-equal", eq1, neq);
+ SiriusAssert.assertNotEquals("2nd vs. not-equal", eq2, neq);
+ SiriusAssert.assertNotEquals("3rd vs. not-equal", eq3, neq);
+
+ SiriusAssert.assertNotEquals("not-equal vs. 1st", neq, eq1);
+ SiriusAssert.assertNotEquals("not-equal vs. 2nd", neq, eq2);
+ SiriusAssert.assertNotEquals("not-equal vs. 3rd", neq, eq3);
+ }
+
+ /**
+ * Tests whether <code>equals</code> is <em>consistent</em>.
+ */
+ public final void testEqualsIsConsistentAcrossInvocations() {
+ for (int i = 0; i < EqualsTestCase.NUM_ITERATIONS; ++i) {
+ testEqualsAgainstNewObject();
+ testEqualsAgainstNull();
+ testEqualsAgainstUnequalObjects();
+ testEqualsIsReflexive();
+ testEqualsIsSymmetricAndTransitive();
+ }
+ }
+
+ /**
+ * Tests whether <code>equals</code> is <em>reflexive</em>.
+ */
+ public final void testEqualsIsReflexive() {
+ Assert.assertEquals("1st equal instance", eq1, eq1);
+ Assert.assertEquals("2nd equal instance", eq2, eq2);
+ Assert.assertEquals("3rd equal instance", eq3, eq3);
+ Assert.assertEquals("not-equal instance", neq, neq);
+ }
+
+ /**
+ * Tests whether <code>equals</code> is <em>symmetric</em> and
+ * <em>transitive</em>.
+ */
+ public final void testEqualsIsSymmetricAndTransitive() {
+ Assert.assertEquals("1st vs. 2nd", eq1, eq2);
+ Assert.assertEquals("2nd vs. 1st", eq2, eq1);
+
+ Assert.assertEquals("1st vs. 3rd", eq1, eq3);
+ Assert.assertEquals("3rd vs. 1st", eq3, eq1);
+
+ Assert.assertEquals("2nd vs. 3rd", eq2, eq3);
+ Assert.assertEquals("3rd vs. 2nd", eq3, eq2);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/GraphicTestsSupportHelp.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/GraphicTestsSupportHelp.java
new file mode 100644
index 0000000000..3b14ccff58
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/GraphicTestsSupportHelp.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.junit.Assert;
+
+/**
+ * Graphical helpers for tests.
+ *
+ *
+ * @author dlecan
+ */
+public class GraphicTestsSupportHelp {
+
+ /**
+ * Constructor.
+ */
+ protected GraphicTestsSupportHelp() {
+ // Nothing
+ }
+
+ /**
+ * Asserts that two points are equal. If they are not an
+ * AssertionFailedError is thrown with the given message.
+ *
+ * @param message
+ * Message
+ * @param expected
+ * Expected point
+ * @param actual
+ * Actual point
+ * @param delta
+ * X and Y delta
+ */
+ public static void assertEquals(final String message, final Point expected, final Point actual, final int delta) {
+ GraphicTestsSupportHelp.assertEquals(message, expected, actual, delta, delta);
+ }
+
+ /**
+ * Asserts that two points are equal.
+ *
+ * @param expected
+ * Expected point
+ * @param actual
+ * Actual point
+ * @param delta
+ * X and Y delta
+ */
+ public static void assertEquals(final Point expected, final Point actual, final int delta) {
+ GraphicTestsSupportHelp.assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * Asserts that two points are equal. If they are not an
+ * AssertionFailedError is thrown with the given message.
+ *
+ * @param message
+ * Message
+ * @param expected
+ * Expected point
+ * @param actual
+ * Actual point
+ * @param xDelta
+ * X delta
+ * @param yDelta
+ * Y delta
+ */
+ public static void assertEquals(final String message, final Point expected, final Point actual, final int xDelta, final int yDelta) {
+ String xfailMessage = "";
+ String yfailMessage = "";
+ if (message != null) {
+ xfailMessage += message;
+ yfailMessage += message;
+ }
+ xfailMessage += " for x coordinate";
+ yfailMessage += " for y coordinate";
+ Assert.assertEquals(xfailMessage, expected.x, actual.x, xDelta);
+ Assert.assertEquals(yfailMessage, expected.y, actual.y, yDelta);
+ }
+
+ /**
+ * Asserts that two points are equal.
+ *
+ * @param expected
+ * Expected point
+ * @param actual
+ * Actual point
+ * @param xDelta
+ * X delta
+ * @param yDelta
+ * Y delta
+ */
+ public static void assertEquals(final Point expected, final Point actual, final int xDelta, final int yDelta) {
+ GraphicTestsSupportHelp.assertEquals(null, expected, actual, xDelta, yDelta);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ICondition.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ICondition.java
new file mode 100644
index 0000000000..cdd8f36968
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ICondition.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Ketan Padegaonkar and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Ketan Padegaonkar - initial API and implementation
+ * Obeo - adapted to reuse in Junit tests.
+ *******************************************************************************/
+package org.eclipse.sirius.tests.support.api;
+
+/**
+ * Copied and adapted from org.eclipse.swtbot.swt.finder.waits.ICondition to be
+ * reused in JUnit tests.
+ *
+ * @author Ketan Padegaonkar &lt;KetanPadegaonkar [at] gmail [dot] com&gt;
+ * @see Conditions
+ * @version $Id$
+ * @since 1.2
+ */
+public interface ICondition {
+
+ /**
+ * Tests if the condition has been met.
+ *
+ * @return <code>true</code> if the condition is satisfied,
+ * <code>false</code> otherwise.
+ * @throws Exception
+ * if the test encounters an error while processing the check.
+ */
+ boolean test() throws Exception;
+
+ /**
+ * Gets the failure message when a test fails (returns <code>false</code>).
+ *
+ * @return the failure message to show in case the test fails.
+ */
+ String getFailureMessage();
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEquality.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEquality.java
new file mode 100644
index 0000000000..bfe1630f52
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEquality.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Test the equality of two {@link Image}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public final class ImageEquality {
+
+ private ImageEquality() {
+ }
+
+ /**
+ * Test the equality of two {@link Image} according to their
+ * {@link Image#getImageData()#data}.
+ *
+ * @param image1
+ * first {@link Image}
+ * @param image2
+ * second {@link Image}
+ * @return true if <code>image1</code> is equal to <code>image2</code>
+ */
+ public static boolean areEqualImages(Image image1, Image image2) {
+ byte[] expectedData = image1.getImageData().data;
+ byte[] currentData = image2.getImageData().data;
+ boolean areSameImages = expectedData.length == currentData.length;
+ if (areSameImages) {
+ for (int i = 0; i < expectedData.length && areSameImages; i++) {
+ areSameImages = areSameImages && expectedData[i] == currentData[i];
+ }
+ }
+ return areSameImages;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEqualityAsserter.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEqualityAsserter.java
new file mode 100644
index 0000000000..ae6b5555b7
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/ImageEqualityAsserter.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.swt.graphics.Image;
+import org.junit.Assert;
+
+/**
+ * Assert that 2 image are equals.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class ImageEqualityAsserter {
+
+ private final Image image1;
+
+ private final Image image2;
+
+ /**
+ * Test the equality of two {@link Image} according to their
+ * {@link Image#getImageData()#data}.
+ *
+ * @param image1
+ * first {@link Image}
+ * @param image2
+ * second {@link Image}
+ */
+
+ public ImageEqualityAsserter(Image image1, Image image2) {
+ this.image1 = image1;
+ this.image2 = image2;
+ }
+
+ /**
+ * Test the equality of two {@link Image} according to their
+ * {@link Image#getImageData()#data}.
+ */
+ public void assertImagesEquals() {
+ Assert.assertEquals("Both image should have the same bounds", image1.getBounds(), image2.getBounds());
+ byte[] expectedData = image1.getImageData().data;
+ byte[] currentData = image2.getImageData().data;
+ Assert.assertEquals("Both image should have the same data size", expectedData.length, currentData.length);
+ for (int i = 0; i < expectedData.length; i++) {
+ Assert.assertEquals("Both image should have the same byte at index " + i, expectedData[i], currentData[i]);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/PluginVersionCompatibility.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/PluginVersionCompatibility.java
new file mode 100644
index 0000000000..0ec74a5bcd
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/PluginVersionCompatibility.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Version;
+
+/**
+ * Utility class to compare version of a specific plug-in to an expected one.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ *
+ */
+public final class PluginVersionCompatibility {
+ /**
+ * The current version of the plug-in.
+ */
+ Version currentVersion;
+
+ /**
+ * Default constructor.
+ *
+ * @param symbolicName
+ * the symbolic name of the bundle to check.
+ */
+ public PluginVersionCompatibility(String symbolicName) {
+ String stringVersion = Platform.getBundle(symbolicName).getHeaders().get(org.osgi.framework.Constants.BUNDLE_VERSION);
+ currentVersion = Version.parseVersion(stringVersion);
+ }
+
+ /**
+ * Compares the currentVersion <code>Version</code> object to another
+ * version.
+ *
+ * <p>
+ * A version is considered to be <b>less than </b> another version if its
+ * major component is less than the other version's major component, or the
+ * major components are equal and its minor component is less than the other
+ * version's minor component, or the major and minor components are equal
+ * and its micro component is less than the other version's micro component,
+ * or the major, minor and micro components are equal and it's qualifier
+ * component is less than the other version's qualifier component (using
+ * <code>String.compareTo</code>).
+ *
+ * <p>
+ * A version is considered to be <b>equal to</b> another version if the
+ * major, minor and micro components are equal and the qualifier component
+ * is equal (using <code>String.compareTo</code>).
+ *
+ * @param other
+ * The <code>Version</code> object to be compared to.
+ * @return A negative integer, zero, or a positive integer if this version
+ * is less than, equal to, or greater than the specified
+ * <code>Version</code> object.
+ */
+ public int compareTo(Version other) {
+ int result = 0;
+ if (other != currentVersion) {
+ result = currentVersion.getMajor() - other.getMajor();
+ if (result == 0) {
+ result = currentVersion.getMinor() - other.getMinor();
+ if (result == 0) {
+ result = currentVersion.getMicro() - other.getMicro();
+ if (result == 0) {
+ result = currentVersion.getQualifier().compareTo(other.getQualifier());
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusAssert.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusAssert.java
new file mode 100644
index 0000000000..970c51eae7
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusAssert.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.sirius.business.api.color.AbstractColorUpdater;
+import org.eclipse.sirius.viewpoint.RGBValues;
+import org.junit.Assert;
+import org.junit.ComparisonFailure;
+
+/**
+ * Designer assertions for Junit.
+ *
+ * @author dlecan
+ */
+public class SiriusAssert extends Assert {
+
+ /**
+ * Assert not equality.
+ *
+ * @param message
+ * Message
+ * @param expected
+ * Expected object
+ * @param actual
+ * Actual objet
+ */
+ public static void assertNotEquals(final String message, final Object expected, final Object actual) {
+ if (expected == null && actual == null) {
+ return;
+ }
+ if (expected != null && !expected.equals(actual)) {
+ return;
+ }
+ SiriusAssert.failEquals(message, expected, actual);
+ }
+
+ /**
+ * Assert not equality.
+ *
+ * @param expected
+ * Expected object
+ * @param actual
+ * Actual objet
+ */
+ public static void assertNotEquals(final Object expected, final Object actual) {
+ SiriusAssert.assertNotEquals(null, expected, actual);
+ }
+
+ /**
+ * Assert not equality.
+ *
+ * @param message
+ * Message
+ * @param expected
+ * Expected object
+ * @param actual
+ * Actual objet
+ */
+ public static void failEquals(final String message, final Object expected, final Object actual) {
+ throw new ComparisonFailure(message, String.valueOf(expected), String.valueOf(actual));
+ }
+
+ /**
+ * Assert both values are equals (same RGB color values).
+ *
+ * @param message
+ * the error message
+ * @param expected
+ * the first value.
+ * @param actual
+ * the second value.
+ */
+ public static void assertSameRGB(final String message, final RGBValues expected, final RGBValues actual) {
+ if (!AbstractColorUpdater.areEquals(expected, actual)) {
+ throw new ComparisonFailure(message, String.valueOf(expected), String.valueOf(actual));
+ }
+ }
+
+ /**
+ * Assert that the file with the given absolute Path exists in the
+ * workspace.
+ *
+ * @param wksPath
+ * the file's path
+ */
+ public static void assertFileExists(final String wksPath) {
+ IFile fileToTest = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(wksPath));
+ // Refresh the file to synchronize the workspace.
+ try {
+ fileToTest.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+ } catch (CoreException e) {
+ Assert.fail(e.getMessage());
+ }
+ Assert.assertTrue("The file \"" + wksPath + "\" does not exist.", fileToTest.exists());
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusDiagramTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusDiagramTestCase.java
new file mode 100644
index 0000000000..da68c689b4
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusDiagramTestCase.java
@@ -0,0 +1,1392 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.LabelEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.action.Action;
+import org.eclipse.sirius.business.api.query.EObjectQuery;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
+import org.eclipse.sirius.diagram.DDiagram;
+import org.eclipse.sirius.diagram.DDiagramElement;
+import org.eclipse.sirius.diagram.DDiagramElementContainer;
+import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.DNode;
+import org.eclipse.sirius.diagram.DNodeContainer;
+import org.eclipse.sirius.diagram.DiagramPackage;
+import org.eclipse.sirius.diagram.DragAndDropTarget;
+import org.eclipse.sirius.diagram.EdgeTarget;
+import org.eclipse.sirius.diagram.business.api.componentization.DiagramDescriptionMappingsManager;
+import org.eclipse.sirius.diagram.business.api.componentization.DiagramDescriptionMappingsRegistry;
+import org.eclipse.sirius.diagram.business.api.helper.display.DisplayServiceManager;
+import org.eclipse.sirius.diagram.business.api.query.DiagramDescriptionMappingManagerQuery;
+import org.eclipse.sirius.diagram.business.internal.metamodel.operations.DDiagramElementContainerSpecOperations;
+import org.eclipse.sirius.diagram.description.ContainerMapping;
+import org.eclipse.sirius.diagram.description.DiagramDescription;
+import org.eclipse.sirius.diagram.description.DiagramElementMapping;
+import org.eclipse.sirius.diagram.description.DragAndDropTargetDescription;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
+import org.eclipse.sirius.diagram.description.Layer;
+import org.eclipse.sirius.diagram.description.NodeMapping;
+import org.eclipse.sirius.diagram.description.filter.FilterDescription;
+import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.ContainerDropDescription;
+import org.eclipse.sirius.diagram.description.tool.DirectEditLabel;
+import org.eclipse.sirius.diagram.description.tool.EdgeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.ReconnectEdgeDescription;
+import org.eclipse.sirius.diagram.tools.api.command.DiagramCommandFactoryService;
+import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactory;
+import org.eclipse.sirius.diagram.tools.api.command.view.HideDDiagramElementLabel;
+import org.eclipse.sirius.diagram.tools.api.command.view.RevealDDiagramElementsLabel;
+import org.eclipse.sirius.diagram.ui.business.api.view.SiriusGMFHelper;
+import org.eclipse.sirius.diagram.ui.tools.api.util.GMFNotationHelper;
+import org.eclipse.sirius.diagram.ui.tools.internal.actions.delete.DeleteFromDiagramAction;
+import org.eclipse.sirius.diagram.ui.tools.internal.actions.delete.DeleteFromModelAction;
+import org.eclipse.sirius.diagram.ui.tools.internal.actions.delete.DeleteWithHookAction;
+import org.eclipse.sirius.diagram.ui.tools.internal.commands.ChangeLayerActivationCommand;
+import org.eclipse.sirius.diagram.ui.tools.internal.commands.ResetStylePropertiesToDefaultValuesCommand;
+import org.eclipse.sirius.diagram.ui.tools.internal.handler.ChangeFilterActivation;
+import org.eclipse.sirius.tests.support.command.CreateNoteAttachmentRecordingCommand;
+import org.eclipse.sirius.tests.support.command.CreateNoteRecordingCommand;
+import org.eclipse.sirius.tools.api.command.ui.NoUICallback;
+import org.eclipse.sirius.viewpoint.DRepresentationElement;
+import org.eclipse.sirius.viewpoint.DSemanticDecorator;
+import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
+import org.eclipse.sirius.viewpoint.description.tool.DragSource;
+import org.eclipse.sirius.viewpoint.description.tool.OperationAction;
+import org.eclipse.sirius.viewpoint.description.tool.SelectionWizardDescription;
+import org.eclipse.sirius.viewpoint.description.tool.ToolDescription;
+import org.eclipse.ui.IEditorPart;
+import org.junit.Assert;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+
+/**
+ * Diagram specific generic test case.
+ *
+ * @author mchauvin
+ */
+public class SiriusDiagramTestCase extends SiriusTestCase {
+
+ private static final String TOOL_NAME_INCORRECT = "The tool name is not correct";
+
+ private static final String LAYER_NAME_INCORRECT = "The layer name is not correct";
+
+ private static final String FILTER_NAME_INCORRECT = "The filter name is not correct";
+
+ private static final String MAPPING_NAME_INCORRECT = "The mapping name is not correct";
+
+ private IDiagramCommandFactory commandFactory;
+
+ @Override
+ protected IDiagramCommandFactory getCommandFactory() {
+ if (commandFactory == null) {
+ commandFactory = DiagramCommandFactoryService.getInstance().getNewProvider().getCommandFactory(session.getTransactionalEditingDomain());
+ commandFactory.setUserInterfaceCallBack(new NoUICallback());
+ }
+ return commandFactory;
+ }
+
+ /**
+ * Performs a arrange all request on diagramEditPart.
+ *
+ * @param diagramEditPart
+ * the {@link DiagramEditPart} on to do the request
+ */
+ protected void arrangeAll(DiagramEditPart diagramEditPart) {
+ ArrangeRequest arrangeRequest = new ArrangeRequest(ActionIds.ACTION_ARRANGE_ALL);
+ List<Object> partsToArrange = new ArrayList<Object>();
+ partsToArrange.add(diagramEditPart);
+ arrangeRequest.setPartsToArrange(partsToArrange);
+ diagramEditPart.performRequest(arrangeRequest);
+ }
+
+ /**
+ * Apply a node creation tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param diagram
+ * the diagram
+ * @param container
+ * the graphical container, for instance the diagram
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyNodeCreationTool(final String toolName, final DDiagram diagram, final EObject container) {
+ final AbstractToolDescription tool = getTool(diagram, toolName);
+ if (tool != null) {
+ final Command command = getCommand(container, tool);
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(container);
+ boolean canExecute = command.canExecute();
+ domain.getCommandStack().execute(command);
+ return canExecute;
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.TOOL_NAME_INCORRECT);
+ }
+
+ /**
+ * Apply a node creation tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param layerName
+ * the layer name
+ * @param diagram
+ * the diagram
+ * @param container
+ * the graphical container, for instance the diagram
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyNodeCreationTool(final String layerName, final String toolName, final DDiagram diagram, final EObject container) {
+ boolean result = false;
+ Layer layer = getLayer(diagram, layerName);
+ if (layer != null) {
+ final AbstractToolDescription tool = getTool(layer, toolName);
+ if (tool != null) {
+ Command command = getCommand(container, tool);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Apply a node creation tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param diagram
+ * the diagram
+ * @param container
+ * the graphical container, for instance the diagram
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applySelectionTool(final String toolName, final DDiagram diagram, final EObject container) {
+ boolean result = false;
+ AbstractToolDescription tool = getTool(diagram, toolName);
+ if (tool != null) {
+ Collection<EObject> selectedElements = getSelectedEObject(tool, diagram, container);
+ Command command = getCommand(container, tool, selectedElements);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Apply a node creation tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param layerName
+ * the layer name
+ * @param diagram
+ * the diagram
+ * @param container
+ * the graphical container, for instance the diagram
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applySelectionTool(final String layerName, final String toolName, final DDiagram diagram, final EObject container) {
+ boolean result = false;
+ Layer layer = getLayer(diagram, layerName);
+ if (layer != null) {
+ AbstractToolDescription tool = getTool(layer, toolName);
+ if (tool != null) {
+ Collection<EObject> selectedElements = getSelectedEObject(tool, diagram, container);
+ Command command = getCommand(container, tool, selectedElements);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Delete from model the element represented by the edit part.
+ *
+ * @param editParts
+ * the edit parts to delete
+ */
+ protected void delete(final EditPart... editParts) {
+ final DeleteFromModelAction actionDelegate = new DeleteFromModelAction();
+ final IEditorPart editor = EclipseUIUtil.getActiveEditor();
+ final GraphicalViewer viewer = (GraphicalViewer) editor.getAdapter(GraphicalViewer.class);
+ for (EditPart editPart : editParts) {
+ viewer.appendSelection(editPart);
+ }
+ TestsUtil.synchronizationWithUIThread();
+ actionDelegate.run();
+ TestsUtil.synchronizationWithUIThread();
+ }
+
+ /**
+ * Delete the edit part using the suppr keyboard touch.
+ *
+ * @param editPart
+ * the edit part
+ */
+ @SuppressWarnings("restriction")
+ protected void deleteViaKeyboard(final EditPart editPart) {
+ final IEditorPart editor = EclipseUIUtil.getActiveEditor();
+ final DeleteWithHookAction actionDelegate = new DeleteWithHookAction(editor);
+ final GraphicalViewer viewer = (GraphicalViewer) editor.getAdapter(GraphicalViewer.class);
+ viewer.appendSelection(editPart);
+ actionDelegate.update();
+ actionDelegate.run();
+ }
+
+ /**
+ * Delete from diagram the element represented by the edit part.
+ *
+ * @param editPart
+ * the edit part
+ */
+ protected void deleteFromDiagram(final EditPart editPart) {
+ final DeleteFromDiagramAction actionDelegate = new DeleteFromDiagramAction();
+ final IEditorPart editor = EclipseUIUtil.getActiveEditor();
+ final GraphicalViewer viewer = (GraphicalViewer) editor.getAdapter(GraphicalViewer.class);
+ viewer.appendSelection(editPart);
+ final Action mockAction = new Action() {
+ // Nothing to specialize
+ };
+ actionDelegate.selectionChanged(mockAction, viewer.getSelection());
+ actionDelegate.run(mockAction);
+ }
+
+ /**
+ * Drop a semantic instance in a view.
+ *
+ * @param semanticElement
+ * the element to drop.
+ * @param containerView
+ * the drop target view.
+ * @param diagramElt
+ * the diagram element to drop.
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean dropSemantic(final EObject semanticElement, final DragAndDropTarget containerView, final DDiagramElement diagramElt) {
+ boolean result = false;
+ DragAndDropTargetDescription dragDragAndDropDescription = containerView.getDragAndDropDescription();
+ if (dragDragAndDropDescription != null) {
+ ContainerDropDescription dropTool = DDiagramElementContainerSpecOperations.getBestDropDescription(dragDragAndDropDescription, semanticElement, null,
+ ((DSemanticDecorator) containerView).getTarget(), containerView, DragSource.PROJECT_EXPLORER_LITERAL, diagramElt);
+ if (dropTool != null) {
+ Command command = getCommandFactory().buildDropInContainerCommandFromTool(containerView, semanticElement, dropTool);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Create a new note in the diagram.
+ *
+ * @param diagram
+ * the diagram
+ * @param noteText
+ * the note text
+ * @return <code>true</code> if the note could be created,
+ * <code>false</code> otherwise
+ */
+ protected final boolean createNote(final DDiagram diagram, final String noteText) {
+ boolean result = false;
+ Diagram gmfDiagram = getGmfDiagram(diagram);
+ Command createNoteCmd = new CreateNoteRecordingCommand(session.getTransactionalEditingDomain(), gmfDiagram, noteText);
+ result = createNoteCmd.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(createNoteCmd);
+ return result;
+ }
+
+ /**
+ * Attach an existing note to a node.
+ *
+ * @param noteText
+ * the note text to identify the note to attach
+ * @param diagramElement
+ * the target diagram element
+ * @return <code>true</code> if the note could be attached to the target
+ * node, <code>false</code> otherwise
+ */
+ protected final boolean attachNote(final String noteText, final DDiagramElement diagramElement) {
+ boolean result = false;
+ Node gmfNode = getGmfNode(diagramElement);
+ Diagram gmfDiagram = GMFNotationHelper.getGMFDiagrams(gmfNode.eResource()).iterator().next();
+ for (final Node note : GMFNotationHelper.getNotes(gmfDiagram)) {
+ String noteDescription = GMFNotationHelper.getNoteDescription(note);
+ if (noteText.equals(noteDescription)) {
+ Command createNoteAttachmentCmd = new CreateNoteAttachmentRecordingCommand(session.getTransactionalEditingDomain(), note, gmfNode);
+ result = createNoteAttachmentCmd.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(createNoteAttachmentCmd);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the selected objects.
+ *
+ * @param tool
+ * the tool
+ * @param diagram
+ * the diagram
+ * @return the selected objects
+ */
+ protected Collection<EObject> getSelectedEObject(final AbstractToolDescription tool, final DDiagram diagram) {
+ return getSelectedEObject(tool, diagram, diagram);
+ }
+
+ /**
+ * Get the selected objects.
+ *
+ * @param tool
+ * the tool
+ * @param diagram
+ * the diagram
+ * @param container
+ * the container
+ * @return the selected objects
+ */
+ protected Collection<EObject> getSelectedEObject(final AbstractToolDescription tool, final DDiagram diagram, final EObject container) {
+ return Collections.<EObject> emptyList();
+ }
+
+ /**
+ * Get a selection command for the tool.
+ *
+ * @param container
+ * the container
+ * @param tool
+ * the tool
+ * @param selectedElements
+ * the selected elements
+ * @return the command build to execute the tool's operation on the given
+ * container
+ */
+ protected Command getCommand(final EObject container, final AbstractToolDescription tool, final Collection<EObject> selectedElements) {
+ Command cmd = null;
+ if (tool instanceof SelectionWizardDescription && container instanceof DSemanticDecorator) {
+ cmd = getCommandFactory().buildSelectionWizardCommandFromTool((SelectionWizardDescription) tool, (DSemanticDecorator) container, selectedElements);
+ } else if (tool instanceof OperationAction) {
+ cmd = getCommandFactory().buildOperationActionFromTool((OperationAction) tool, Lists.newArrayList(Iterables.filter(selectedElements, DSemanticDecorator.class)));
+ }
+ return cmd;
+ }
+
+ /**
+ * Apply an edge creation tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param diagram
+ * the diagram
+ * @param source
+ * the graphical source element
+ * @param target
+ * the graphical target element
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyEdgeCreationTool(final String toolName, final DDiagram diagram, final EdgeTarget source, final EdgeTarget target) {
+ boolean result = false;
+ AbstractToolDescription tool = getTool(diagram, toolName);
+ if (tool instanceof EdgeCreationDescription) {
+ Command command = getCommandFactory().buildCreateEdgeCommandFromTool(source, target, (EdgeCreationDescription) tool);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Apply an edge reconnection tool on a diagram.
+ *
+ * @param toolName
+ * the tool name
+ * @param diagram
+ * the diagram
+ * @param edge
+ * the edge
+ * @param source
+ * the graphical source element
+ * @param target
+ * the graphical target element
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyEdgeReconnectionTool(final String toolName, final DDiagram diagram, final DEdge edge, final EdgeTarget source, final EdgeTarget target) {
+ boolean result = false;
+ AbstractToolDescription tool = getTool(diagram, toolName);
+ if (tool instanceof ReconnectEdgeDescription) {
+ Command command = getCommandFactory().buildReconnectEdgeCommandFromTool((ReconnectEdgeDescription) tool, edge, source, target);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Applies the {@link ContainerDropDescription} with the given name, on the
+ * given target container and the dropped dDiagram element. It simulates a
+ * DDiagramElement drop from the same diagram.
+ *
+ * @param diagram
+ * the diagram in which the tool should be applied
+ * @param dndToolName
+ * the name of the {@link ContainerDropDescription} tool
+ * @param dropContainer
+ * the container in which element should be dropped
+ * @param droppedDDiagramElement
+ * the dropped {@link DDiagramElement} from a diagram.
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyContainerDropDescriptionTool(final DDiagram diagram, final String dndToolName, DragAndDropTarget dropContainer, DDiagramElement droppedDDiagramElement) {
+ boolean result = false;
+ AbstractToolDescription dndTool = getTool(diagram, dndToolName);
+ if (dndTool instanceof ContainerDropDescription) {
+ Command command = getCommandFactory().buildDropInContainerCommandFromTool(dropContainer, droppedDDiagramElement, (ContainerDropDescription) dndTool);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Applies the {@link ContainerDropDescription} with the given name, on the
+ * given target container and the dropped semantic element. It simulates a
+ * semantic element drop from example the Model Explorer view.
+ *
+ * @param diagram
+ * the diagram in which the tool should be applied
+ * @param dndToolName
+ * the name of the {@link ContainerDropDescription} tool
+ * @param dropContainer
+ * the container in which element should be dropped
+ * @param droppedElement
+ * the dropped EObject (if the Drop is made from the Model
+ * content view) or the {@link DDiagramElement} if the drop is
+ * made from an existing {@link DDiagramElement}.
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyContainerDropDescriptionTool(final DDiagram diagram, final String dndToolName, DragAndDropTarget dropContainer, EObject droppedElement) {
+ boolean result = false;
+ AbstractToolDescription dndTool = getTool(diagram, dndToolName);
+ if (dndTool instanceof ContainerDropDescription) {
+ Command command = getCommandFactory().buildDropInContainerCommandFromTool(dropContainer, droppedElement, (ContainerDropDescription) dndTool);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Apply a direct edit tool on a diagram element.
+ *
+ * @param toolName
+ * the tool name
+ * @param diagram
+ * the diagram
+ * @param element
+ * the diagram element
+ * @param value
+ * the new value to set
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyDirectEditTool(final String toolName, final DDiagram diagram, final DDiagramElement element, final String value) {
+ boolean result = false;
+ AbstractToolDescription tool = getTool(diagram, toolName);
+ if (tool instanceof DirectEditLabel) {
+ Command command = getCommandFactory().buildDirectEditLabelFromTool(element, (DirectEditLabel) tool, value);
+ result = command.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+ return result;
+ }
+
+ /**
+ * Apply a deletion tool on a diagram element.
+ *
+ * @param element
+ * the diagram element
+ * @return <code>true</code> if the tool could be applied,
+ * <code>false</code> otherwise
+ */
+ protected final boolean applyDeletionTool(final DDiagramElement element) {
+ boolean result = false;
+ Command command = getCommandFactory().buildDeleteDiagramElement(element);
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ return result;
+ }
+
+ /**
+ * Searches the given {@link DDiagram} for a tool of the given name and
+ * returns it.
+ *
+ * @param diagram
+ * The diagram to search for a tool.
+ * @param toolName
+ * The name of the searched tool (&quot;chapter&quot; for the
+ * &quot;Create new chapter&quot; tool).
+ * @return The searched tool, <code>null</code> if it cannot be found.
+ */
+ protected final AbstractToolDescription getTool(final DDiagram diagram, final String toolName) {
+ final List<AbstractToolDescription> tools = DiagramComponentizationTestSupport.getAllTools(session, diagram.getDescription());
+ return getTool(tools, toolName);
+ }
+
+ /**
+ * Searches the given {@link Layer} for a tool of the given name and returns
+ * it.
+ *
+ * @param layer
+ * The layer to search for a tool.
+ * @param toolName
+ * The name of the searched tool (&quot;chapter&quot; for the
+ * &quot;Create new chapter&quot; tool).
+ * @return The searched tool, <code>null</code> if it cannot be found.
+ */
+ protected final AbstractToolDescription getTool(final Layer layer, final String toolName) {
+ return getTool(layer.getAllTools(), toolName);
+ }
+
+ private AbstractToolDescription getTool(final List<AbstractToolDescription> tools, final String toolName) {
+ AbstractToolDescription theAbstractToolDescription = null;
+ for (int i = 0; i < tools.size(); i++) {
+
+ final AbstractToolDescription tool = tools.get(i);
+ final String name = tool.getName();
+ if (name != null && name.equals(toolName)) {
+ theAbstractToolDescription = tool;
+ break;
+ }
+ }
+ return theAbstractToolDescription;
+ }
+
+ /**
+ * Searches the given {@link DDiagram} for a layer of the given name and
+ * returns it.
+ *
+ * @param diagram
+ * The diagram to search for a tool.
+ * @param layerName
+ * The name of the searched layer.
+ * @return The retrieved layer, or <code>null</code> if it cannot be found.
+ */
+ protected final Layer getLayer(final DDiagram diagram, final String layerName) {
+ final Collection<Layer> layers = DiagramComponentizationTestSupport.getAllLayers(session, diagram.getDescription());
+
+ for (final Layer layer : layers) {
+ if (layer.getName().equals(layerName)) {
+ return layer;
+ }
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.LAYER_NAME_INCORRECT);
+ }
+
+ /**
+ * Searches the given {@link Layer} for a node mapping of the given name and
+ * returns it.
+ *
+ * @param layer
+ * The layer to search for a tool.
+ * @param mappingName
+ * The name of the searched mapping.
+ * @return The retrieved mapping, or throws an
+ * {@link IllegalArgumentException} if it cannot be found.
+ */
+ protected final NodeMapping getNodeMapping(final Layer layer, final String mappingName) {
+
+ final DiagramDescriptionMappingsManager mappingsManager = DiagramDescriptionMappingsRegistry.INSTANCE.getDiagramDescriptionMappingsManager(session,
+ SiriusDiagramTestCase.getParentDiagramDescription(layer));
+ computeMapping(mappingsManager);
+
+ final Set<DiagramElementMapping> allMappings = new DiagramDescriptionMappingManagerQuery(mappingsManager).computeAllMappings();
+ final Iterable<NodeMapping> allNodeMappings = Iterables.filter(allMappings, NodeMapping.class);
+ for (NodeMapping nodeMapping : allNodeMappings) {
+ if (mappingName.equals(nodeMapping.getName()) && SiriusDiagramTestCase.getParentLayer(nodeMapping) == layer) {
+ return nodeMapping;
+ }
+ }
+
+ throw new IllegalArgumentException(SiriusDiagramTestCase.MAPPING_NAME_INCORRECT);
+ }
+
+ private void computeMapping(final DiagramDescriptionMappingsManager mappingsManager) {
+ if (session != null) {
+ mappingsManager.computeMappings(session.getSelectedViewpoints(false));
+ } else {
+ mappingsManager.computeMappings(null);
+ }
+ }
+
+ /**
+ * Searches the given {@link Layer} for an edge mapping of the given name
+ * and returns it.
+ *
+ * @param layer
+ * The layer to search for a tool.
+ * @param mappingName
+ * The name of the searched mapping.
+ * @return The retrieved mapping, or throws an
+ * {@link IllegalArgumentException} if it cannot be found.
+ */
+ protected final EdgeMapping getEdgeMapping(final Layer layer, final String mappingName) {
+ final DiagramDescriptionMappingsManager mappingsManager = DiagramDescriptionMappingsRegistry.INSTANCE.getDiagramDescriptionMappingsManager(session,
+ SiriusDiagramTestCase.getParentDiagramDescription(layer));
+ for (final EdgeMapping edgeMapping : mappingsManager.getEdgeMappings()) {
+ if (mappingName.equals(edgeMapping.getName())) {
+ return edgeMapping;
+ }
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.MAPPING_NAME_INCORRECT);
+ }
+
+ /**
+ * Searches the given {@link Layer} for a node mapping of the given name and
+ * returns it.
+ *
+ * @param layer
+ * The layer to search for a tool.
+ * @param mappingName
+ * The name of the searched mapping.
+ * @return The retrieved mapping, or throws an
+ * {@link IllegalArgumentException} if it cannot be found.
+ */
+ protected final ContainerMapping getContainerMapping(final Layer layer, final String mappingName) {
+
+ final DiagramDescriptionMappingsManager mappingsManager = DiagramDescriptionMappingsRegistry.INSTANCE.getDiagramDescriptionMappingsManager(session,
+ SiriusDiagramTestCase.getParentDiagramDescription(layer));
+ computeMapping(mappingsManager);
+
+ final Set<DiagramElementMapping> allMappings = new DiagramDescriptionMappingManagerQuery(mappingsManager).computeAllMappings();
+ final Iterable<ContainerMapping> allContainerMappings = Iterables.filter(allMappings, ContainerMapping.class);
+ for (ContainerMapping containerMapping : allContainerMappings) {
+ if (mappingName.equals(containerMapping.getName()) && SiriusDiagramTestCase.getParentLayer(containerMapping) == layer) {
+ return containerMapping;
+ }
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.MAPPING_NAME_INCORRECT);
+ }
+
+ /**
+ * Browse the model upward (from the leaf to the root) and return the first
+ * viewpoint found.
+ *
+ * @param anyElement
+ * any {@link EObject} instance.
+ * @return the viewpoint if found, null otherwise.
+ */
+ private static DiagramDescription getParentDiagramDescription(final EObject anyElement) {
+ EObject current = anyElement;
+ while (current != null) {
+ current = current.eContainer();
+ if (current instanceof DiagramDescription) {
+ return (DiagramDescription) current;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * return the layer which contains this mapping if available.
+ *
+ * @param mapping
+ * the diagram element mapping
+ * @return the layer containing if there is one, <code>null</code> otherwise
+ */
+ private static Layer getParentLayer(final DiagramElementMapping mapping) {
+ EObject current = mapping;
+ while (current != null) {
+ current = current.eContainer();
+ if (current instanceof Layer) {
+ return (Layer) current;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Searches the given {@link DDiagram} for a filter of the given name and
+ * returns it.
+ *
+ * @param diagram
+ * The diagram to search for a tool.
+ * @param filterName
+ * The name of the searched filter.
+ * @return The retrieved filter, or <code>null</code> if it cannot be found.
+ */
+ protected final FilterDescription getFilter(final DDiagram diagram, final String filterName) {
+ final Collection<FilterDescription> filters = diagram.getDescription().getFilters();
+
+ for (final FilterDescription filter : filters) {
+ if (filter.getName().equals(filterName)) {
+ return filter;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get a command for the tool.
+ *
+ * @param container
+ * the container
+ * @param tool
+ * the tool
+ * @return the command build to execute the tool's operation on the given
+ * container
+ */
+ protected final Command getCommand(final EObject container, final AbstractToolDescription tool) {
+
+ Command cmd = null;
+
+ if (tool instanceof NodeCreationDescription) {
+ if (container instanceof DDiagram) {
+ cmd = getCommandFactory().buildCreateNodeCommandFromTool((DDiagram) container, (NodeCreationDescription) tool);
+ } else if (container instanceof DDiagramElementContainer) {
+ cmd = getCommandFactory().buildCreateNodeCommandFromTool((DDiagramElementContainer) container, (NodeCreationDescription) tool);
+ } else if (container instanceof DNode) {
+ cmd = getCommandFactory().buildCreateNodeCommandFromTool((DNode) container, (NodeCreationDescription) tool);
+ }
+ } else if (tool instanceof ContainerCreationDescription) {
+ if (container instanceof DDiagram) {
+ cmd = getCommandFactory().buildCreateContainerCommandFromTool((DDiagram) container, (ContainerCreationDescription) tool);
+ } else if (container instanceof DNodeContainer) {
+ cmd = getCommandFactory().buildCreateContainerCommandFromTool((DNodeContainer) container, (ContainerCreationDescription) tool);
+ }
+ } else if (tool instanceof ToolDescription) {
+ cmd = getCommandFactory().buildGenericToolCommandFromTool(container, (ToolDescription) tool);
+ }
+ return cmd;
+ }
+
+ /**
+ * Activate a layer.
+ *
+ * @param dDiagram
+ * the {@link DDiagram}
+ * @param layerName
+ * the layer name
+ * @return <code>true</code> if the activation could be made,
+ * <code>false</code> otherwise
+ */
+ protected final boolean activateLayer(final DDiagram dDiagram, final String layerName) {
+ Layer layer = getLayer(dDiagram, layerName);
+ if (layer != null && !dDiagram.getActivatedLayers().contains(layer)) {
+ Command changeLayersActivationCmd = new ChangeLayerActivationCommand(session.getTransactionalEditingDomain(), dDiagram, layer, new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeLayersActivationCmd);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Deactivate a layer.
+ *
+ * @param dDiagram
+ * the {@link DDiagram}
+ * @param layerName
+ * the layer name
+ * @return <code>true</code> if the deactivation could be made,
+ * <code>false</code> otherwise
+ */
+ protected final boolean deactivateLayer(final DDiagram dDiagram, final String layerName) {
+ Layer layer = getLayer(dDiagram, layerName);
+ if (layer != null && dDiagram.getActivatedLayers().contains(layer)) {
+ Command changeLayersActivationCmd = new ChangeLayerActivationCommand(session.getTransactionalEditingDomain(), dDiagram, layer, new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeLayersActivationCmd);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Activate a filter.
+ *
+ * @param diagram
+ * the diagram
+ * @param filterName
+ * the filter name
+ * @return <code>true</code> if the activation could be made,
+ * <code>false</code> otherwise
+ */
+ protected final boolean activateFilter(final DDiagram diagram, final String filterName) {
+ final FilterDescription filter = getFilter(diagram, filterName);
+ if (filter != null) {
+ return setFilterActivation(diagram, filter, true);
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.FILTER_NAME_INCORRECT);
+ }
+
+ /**
+ * Deactivate a filter.
+ *
+ * @param diagram
+ * the diagram
+ * @param filterName
+ * the filter name
+ * @return <code>true</code> if the deactivation could be made,
+ * <code>false</code> otherwise
+ */
+ protected final boolean deactivateFilter(final DDiagram diagram, final String filterName) {
+ final FilterDescription filter = getFilter(diagram, filterName);
+ if (filter != null) {
+ return setFilterActivation(diagram, filter, false);
+ }
+ throw new IllegalArgumentException(SiriusDiagramTestCase.FILTER_NAME_INCORRECT);
+ }
+
+ private boolean setFilterActivation(final DDiagram diagram, final FilterDescription filter, final boolean visible) {
+ final Runnable change = new ChangeFilterActivation((IDiagramWorkbenchPart) EclipseUIUtil.getActiveEditor(), diagram, filter, visible);
+ change.run();
+ return true;
+ }
+
+ /**
+ * Hide the specified {@link DDiagramElement}'s label.
+ *
+ * @param dDiagramElement
+ * the specified {@link DDiagramElement} for which hide the label
+ */
+ protected void hideLabel(DDiagramElement dDiagramElement) {
+ TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+ Command hideDDiagramElementLabelCmd = new HideDDiagramElementLabel(domain, Collections.singleton(dDiagramElement));
+ domain.getCommandStack().execute(hideDDiagramElementLabelCmd);
+ TestsUtil.synchronizationWithUIThread();
+ }
+
+ /**
+ * Reveal the specified {@link DDiagramElement}'s label.
+ *
+ * @param dDiagramElement
+ * the specified {@link DDiagramElement} for which reveal the
+ * label
+ */
+ protected void revealLabel(DDiagramElement dDiagramElement) {
+ TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+ Command revealDDiagramElementLabelCmd = new RevealDDiagramElementsLabel(domain, Collections.singleton(dDiagramElement));
+ domain.getCommandStack().execute(revealDDiagramElementLabelCmd);
+ TestsUtil.synchronizationWithUIThread();
+ }
+
+ /**
+ * Get the diagram element from the semantic one.
+ *
+ * @param diagram
+ * the diagram
+ * @param semanticElement
+ * the semantic element
+ * @return the first diagram element which has as target the semantic
+ * element given as parameter
+ */
+ protected final DDiagramElement getFirstDiagramElement(final DDiagram diagram, final EObject semanticElement) {
+ return (DDiagramElement) getFirstRepresentationElement(diagram, semanticElement);
+ }
+
+ /**
+ * Get the diagram element from the specified {@link EObject} semantic
+ * element and the specified {@link DiagramElementMapping}.
+ *
+ * @param diagram
+ * the diagram
+ * @param semanticElement
+ * the semantic element
+ * @param diagramElementMapping
+ * the specified {@link DiagramElementMapping}
+ * @return the first diagram element which has as target the semantic
+ * element given as parameter and with the specified
+ * {@link DiagramElementMapping}
+ */
+ protected final DDiagramElement getFirstDiagramElement(final DDiagram diagram, final EObject semanticElement, final DiagramElementMapping diagramElementMapping) {
+ DDiagramElement dDiagramElement = null;
+ for (final DRepresentationElement element : diagram.getRepresentationElements()) {
+ if (element.getTarget() == semanticElement && element.getMapping() == diagramElementMapping && element instanceof DDiagramElement) {
+ dDiagramElement = (DDiagramElement) element;
+ break;
+ }
+ }
+ return dDiagramElement;
+ }
+
+ /**
+ * Get the diagram element which owns the given label.
+ *
+ * @param diagram
+ * the diagram on which to retrieve elements
+ * @param label
+ * the label
+ * @return a collection of diagram elements with the label
+ */
+ public List<DDiagramElement> getDiagramElementsFromLabel(final DDiagram diagram, final String label) {
+ return getDiagramElementsFromLabel(diagram, label, DDiagramElement.class);
+ }
+
+ /**
+ * Get the diagram element which owns the given label and are instances of
+ * the given class.
+ *
+ * @param <T>
+ * the class
+ * @param diagram
+ * the diagram on which to retrieve elements
+ * @param label
+ * the label
+ * @param searchedClass
+ * the class
+ * @return collection of searchedClass instances with the label
+ */
+ public <T extends DDiagramElement> List<T> getDiagramElementsFromLabel(final DDiagram diagram, final String label, final Class<T> searchedClass) {
+ final List<T> found = Lists.newArrayList();
+ final Iterator<EObject> it = diagram.eAllContents();
+ while (it.hasNext()) {
+ final EObject cur = it.next();
+ if (searchedClass.isInstance(cur) && labelFeature(cur.eClass()) != null) {
+ if (label.equals(getLabelValue(cur))) {
+ found.add(searchedClass.cast(cur));
+ }
+ }
+ }
+ return found;
+ }
+
+ private String getLabelValue(final EObject cur) {
+ return (String) cur.eGet(labelFeature(cur.eClass()));
+ }
+
+ private EStructuralFeature labelFeature(final EClass class1) {
+ return class1.getEStructuralFeature("name");
+ }
+
+ /**
+ * Get the diagram element from the semantic one.
+ *
+ * @param diagram
+ * the diagram
+ * @param semanticElement
+ * the semantic element
+ * @return the first diagram element which has as target the semantic
+ * element given as parameter
+ */
+ protected final DNode getFirstNodeElement(final DDiagram diagram, final EObject semanticElement) {
+ return getFirstRepresentationElement(diagram, semanticElement, DNode.class);
+ }
+
+ /**
+ * Get the diagram element from the semantic one.
+ *
+ * @param diagram
+ * the diagram
+ * @param semanticElement
+ * the semantic element
+ * @return the first diagram element which has as target the semantic
+ * element given as parameter
+ */
+ protected final DEdge getFirstEdgeElement(final DDiagram diagram, final EObject semanticElement) {
+ return getFirstRepresentationElement(diagram, semanticElement, DEdge.class);
+ }
+
+ /**
+ * Check if an viewpoint element is visible in a diagram.
+ *
+ * @param diagram
+ * the diagram
+ * @param element
+ * the element
+ * @return <code>true</code> if visible, <code>false</code> otherwise
+ */
+ protected static final boolean isVisible(final DDiagram diagram, final DDiagramElement element) {
+ if (diagram == null) {
+ throw new IllegalArgumentException("diagram should not be null");
+ }
+ if (element == null) {
+ throw new IllegalArgumentException("element should not be null");
+ }
+ return DisplayServiceManager.INSTANCE.getDisplayService().isDisplayed(diagram, element);
+ }
+
+ /**
+ * Get the GMF Diagram from the diagram.
+ *
+ * @param diagram
+ * the diagram
+ * @return the view which has as element the diagram element given as
+ * parameter or null if any
+ */
+ protected Diagram getGmfDiagram(final DDiagram diagram) {
+ return SiriusGMFHelper.getGmfDiagram(diagram, session);
+ }
+
+ /**
+ * Get the GMF view from the diagram element.
+ *
+ * @param diagramElement
+ * the diagram element
+ * @return the view which has as element the diagram element given as
+ * parameter or null if any
+ */
+ protected View getGmfView(final DDiagramElement diagramElement) {
+ return SiriusGMFHelper.getGmfView(diagramElement, session);
+ }
+
+ /**
+ * Get the GMF view from the diagram element and assert there is only one
+ * GMF view for this diagram element.
+ *
+ * @param diagramElement
+ * the diagram element
+ * @param clazz
+ * The type of the desired view
+ * @param session
+ * the session to use
+ *
+ * @return the view which has as element the diagram element given as
+ * parameter or null if any
+ */
+ protected static View getGmfViewAndAssertOnlyOne(final EObject diagramElement, final Class<? extends View> clazz, final Session session) {
+ View result = null;
+ if (diagramElement instanceof DSemanticDecorator) {
+
+ final Session sessionToUse;
+ if (session == null) {
+ sessionToUse = new EObjectQuery(diagramElement).getSession();
+ } else {
+ sessionToUse = session;
+ }
+
+ if (sessionToUse != null) {
+ final ECrossReferenceAdapter crossReference = sessionToUse.getSemanticCrossReferencer();
+ for (final org.eclipse.emf.ecore.EStructuralFeature.Setting setting : crossReference.getInverseReferences(diagramElement)) {
+ if (clazz.isInstance(setting.getEObject()) && setting.getEStructuralFeature() == NotationPackage.eINSTANCE.getView_Element()) {
+ if (result != null) {
+ Assert.fail("We should have only one GMF view for a diagram element.");
+ }
+ result = (View) setting.getEObject();
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get the GMF node from the diagram element.
+ *
+ * @param diagramElement
+ * the diagram element
+ * @return the node which has as element the diagram element given as
+ * parameter or null if any
+ */
+ protected Node getGmfNode(final DDiagramElement diagramElement) {
+ return SiriusGMFHelper.getGmfNode(diagramElement, session);
+ }
+
+ /**
+ * Get the GMF edge from the diagram element.
+ *
+ * @param diagramElement
+ * the diagram element
+ * @return the edge which has as element the diagram element given as
+ * parameter or null if any
+ */
+ protected Edge getGmfEdge(final DDiagramElement diagramElement) {
+ return SiriusGMFHelper.getGmfEdge(diagramElement, session);
+ }
+
+ /**
+ * Get the editPart corresponding to this diagram element.<BR>
+ * The editPart is search in the active editor.
+ *
+ * @param diagramElement
+ * the diagram element
+ *
+ * @return the editPart corresponding to the diagram element given as
+ * parameter or null if any
+ */
+ protected IGraphicalEditPart getEditPart(final DDiagramElement diagramElement) {
+ final IEditorPart editor = EclipseUIUtil.getActiveEditor();
+ TestsUtil.synchronizationWithUIThread();
+ return getEditPart(diagramElement, editor);
+ }
+
+ /**
+ * Get the editPart corresponding to this diagram <BR>
+ * The editPart is search in the active editor.
+ *
+ * @param diagram
+ * the diagram
+ *
+ * @return the editPart corresponding to the diagram element given as
+ * parameter or null if any
+ */
+ protected IGraphicalEditPart getEditPart(final DDiagram diagram) {
+ final IEditorPart editor = EclipseUIUtil.getActiveEditor();
+ return getEditPart(diagram, editor);
+ }
+
+ /**
+ * Get the editPart corresponding to this diagram element.<BR>
+ * The editPart is search in the active editor.
+ *
+ * @param diagramElement
+ * the diagram element
+ * @param editor
+ * the editor containing the editPart
+ *
+ * @return the editPart corresponding to the diagram element given as
+ * parameter or null if any
+ */
+ protected IGraphicalEditPart getEditPart(final DDiagramElement diagramElement, final IEditorPart editor) {
+ final View gmfView = getGmfView(diagramElement);
+ return getEditPart(gmfView, editor);
+ }
+
+ /**
+ * Get the editPart corresponding to this diagram element.<BR>
+ * The editPart is search in the active editor.
+ *
+ * @param diagram
+ * the diagram
+ * @param editor
+ * the editor containing the editPart
+ *
+ * @return the editPart corresponding to the diagram element given as
+ * parameter or null if any
+ */
+ protected IGraphicalEditPart getEditPart(final DDiagram diagram, final IEditorPart editor) {
+ final Diagram gmfDiagram = getGmfDiagram(diagram);
+ return getEditPart(gmfDiagram, editor);
+ }
+
+ /**
+ * Get the editPart corresponding to this diagram element.<BR>
+ * The editPart is search in the active editor.
+ *
+ * @param gmfView
+ * the gmf view
+ * @param editor
+ * the editor containing the editPart
+ *
+ * @return the editPart corresponding to the diagram element given as
+ * parameter or null if any
+ */
+ private IGraphicalEditPart getEditPart(final View gmfView, final IEditorPart editor) {
+ IGraphicalEditPart result = null;
+ if (gmfView != null && editor instanceof DiagramEditor) {
+ final Map<?, ?> editPartRegistry = ((DiagramEditor) editor).getDiagramGraphicalViewer().getEditPartRegistry();
+ final Object editPart = editPartRegistry.get(gmfView);
+ if (editPart instanceof IGraphicalEditPart) {
+ result = (IGraphicalEditPart) editPart;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set the value of an attribute of a {@link DDiagram}.
+ *
+ * @param domain
+ * the {@link EditingDomain}
+ * @param diagram
+ * the {@link DDiagram}
+ * @param eAttributeName
+ * the name of the attribute to set
+ * @param newValue
+ * the new value of the attribute to set
+ * @return <code>True</code> if the command was executable,
+ * <code>False</code> otherwise.
+ *
+ */
+ protected boolean setDDiagramAttribute(final EditingDomain domain, final DDiagram diagram, final String eAttributeName, final Object newValue) {
+ boolean result = false;
+ EClass eClass = diagram.eClass();
+ List<EAttribute> eAttributes = eClass.getEAllAttributes();
+ Iterator<EAttribute> iterator = eAttributes.iterator();
+ EAttribute targetAttribute = null;
+ while (iterator.hasNext() && targetAttribute == null) {
+ final EAttribute eAttribute = iterator.next();
+ if (eAttribute.getName().equals(eAttributeName)) {
+ targetAttribute = eAttribute;
+ }
+ }
+ Command setCmd = SetCommand.create(domain, diagram, targetAttribute, newValue);
+ result = setCmd.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(setCmd);
+ return result;
+ }
+
+ /**
+ * Unsynchronize the diagram.
+ *
+ * @param diagram
+ * the diagram
+ */
+ protected void unsynchronizeDiagram(final DDiagram diagram) {
+ // Unsynchronized the diagram
+ TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+ Command setUnsynschronizedCmd = SetCommand.create(domain, diagram, DiagramPackage.Literals.DDIAGRAM__SYNCHRONIZED, false);
+ domain.getCommandStack().execute(setUnsynschronizedCmd);
+ }
+
+ /**
+ * Retrieve the label for the element.
+ *
+ * @param diagramElement
+ * element to retrieve the label.
+ * @return the label corresponding to element.
+ */
+ protected LabelEditPart getLabelEditPart(DDiagramElement diagramElement) {
+ IGraphicalEditPart editPart = getEditPart(diagramElement);
+ for (Object child : editPart.getChildren()) {
+ if (child instanceof LabelEditPart) {
+ return (LabelEditPart) child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks that all label that should be hidden are effectively hidden in the
+ * given diagram, and that there is no other hidden label.
+ *
+ * @param diagram
+ * the diagram to test
+ * @param elementsThatShouldHaveHiddenLabel
+ * the list of label that should be hidden in the given diagram
+ */
+ protected void checkForHiddenLabels(final DDiagram diagram, DDiagramElement... elementsThatShouldHaveHiddenLabel) {
+
+ // We first get all the elements that should have visible labels
+ HashSet<DDiagramElement> allDiagramElements = Sets.newHashSet(diagram.getOwnedDiagramElements());
+ for (DDiagramElement diagramElement : diagram.getOwnedDiagramElements()) {
+ Iterator<DDiagramElement> filter = Iterables.filter(diagramElement.eContents(), DDiagramElement.class).iterator();
+ while (filter.hasNext()) {
+ allDiagramElements.add(filter.next());
+ }
+ }
+ SetView<DDiagramElement> elementsThatShouldHaveVisibleLabel = Sets.difference(allDiagramElements, Sets.newHashSet(elementsThatShouldHaveHiddenLabel));
+
+ // And ensure that all these elements have visible labels
+ for (DDiagramElement elementThatShouldHaveVisibleLabel : elementsThatShouldHaveVisibleLabel) {
+
+ LabelEditPart labelEditPart = getLabelEditPart(elementThatShouldHaveVisibleLabel);
+ TestCase.assertNotNull("This element's label should not be hidden : " + elementThatShouldHaveVisibleLabel, labelEditPart);
+ TestCase.assertTrue("This element's label should not be hidden : " + elementThatShouldHaveVisibleLabel, labelEditPart.getFigure().isVisible());
+ }
+
+ // Then we ensure that all elements that should be hidden are
+ // effectively hidden
+ for (DDiagramElement elementThatShouldHaveHiddenLabel : elementsThatShouldHaveHiddenLabel) {
+ LabelEditPart labelEditPart = getLabelEditPart(elementThatShouldHaveHiddenLabel);
+ TestCase.assertTrue("This element's label should be hidden : " + elementThatShouldHaveHiddenLabel, labelEditPart == null || !labelEditPart.getFigure().isVisible());
+ }
+ }
+
+ /**
+ * Reset the style properties to default values.
+ *
+ * @param dDiagramElement
+ * the diagram element to reset style
+ * @param diagram
+ * the diagram
+ */
+ protected void resetStylePropertiesToDefaultValues(DDiagramElement dDiagramElement, DDiagram diagram) {
+ TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+ Iterator<EObject> iterator = new EObjectQuery(dDiagramElement).getInverseReferences(NotationPackage.Literals.VIEW__ELEMENT).iterator();
+ TestCase.assertTrue("The DDiagramElement : " + dDiagramElement + " must have a associated GMF View", iterator.hasNext());
+ EObject next = iterator.next();
+ TestCase.assertTrue("The DDiagramElement : " + dDiagramElement + " must have a associated GMF View", next instanceof View);
+ View view = (View) next;
+ Command command = new ResetStylePropertiesToDefaultValuesCommand(domain, diagram, Collections.singletonMap(view, dDiagramElement));
+ domain.getCommandStack().execute(command);
+ }
+
+ /**
+ * Passed file on read only status.
+ *
+ * @param file
+ * the file to pass in read only status
+ * @throws Exception
+ * the exception
+ */
+ protected void setReadOnly(IFile file) throws Exception {
+ ResourceAttributes resource = file.getResourceAttributes();
+
+ resource.setReadOnly(true);
+
+ file.setResourceAttributes(resource);
+
+ TestCase.assertTrue("The file must be read only", file.isReadOnly());
+ }
+
+ /**
+ * Get file in the temporary project name with the fileName passed in
+ * parameter.
+ *
+ * @param fileName
+ * the file name
+ * @return the file corresponding to parameter
+ */
+ protected IFile getFile(String fileName) {
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(SiriusTestCase.TEMPORARY_PROJECT_NAME).getFile(fileName);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusTestCase.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusTestCase.java
new file mode 100644
index 0000000000..d717e08ade
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/SiriusTestCase.java
@@ -0,0 +1,1675 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.sirius.business.api.componentization.ViewpointRegistry;
+import org.eclipse.sirius.business.api.dialect.DialectManager;
+import org.eclipse.sirius.business.api.dialect.command.RefreshRepresentationsCommand;
+import org.eclipse.sirius.business.api.modelingproject.ModelingProject;
+import org.eclipse.sirius.business.api.preferences.SiriusPreferencesKeys;
+import org.eclipse.sirius.business.api.query.ViewpointQuery;
+import org.eclipse.sirius.business.api.session.DefaultLocalSessionCreationOperation;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionCreationOperation;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.business.api.session.resource.AirdResource;
+import org.eclipse.sirius.business.internal.migration.AbstractSiriusMigrationService;
+import org.eclipse.sirius.business.internal.migration.AbstractVersionSAXParser;
+import org.eclipse.sirius.business.internal.migration.RepresentationsFileMigrationService;
+import org.eclipse.sirius.business.internal.migration.RepresentationsFileVersionSAXParser;
+import org.eclipse.sirius.business.internal.migration.description.VSMMigrationService;
+import org.eclipse.sirius.business.internal.migration.description.VSMVersionSAXParser;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
+import org.eclipse.sirius.diagram.part.SiriusDiagramEditorPlugin;
+import org.eclipse.sirius.diagram.tools.api.command.DiagramCommandFactoryService;
+import org.eclipse.sirius.diagram.tools.api.command.IDiagramCommandFactory;
+import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor;
+import org.eclipse.sirius.ecore.extender.tool.api.ModelUtils;
+import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.ext.base.Options;
+import org.eclipse.sirius.tools.api.command.ICommandFactory;
+import org.eclipse.sirius.tools.api.command.semantic.AddSemanticResourceCommand;
+import org.eclipse.sirius.tools.api.command.ui.NoUICallback;
+import org.eclipse.sirius.tools.api.interpreter.InterpreterRegistry;
+import org.eclipse.sirius.ui.business.api.action.RefreshActionListenerRegistry;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditorDialogFactory;
+import org.eclipse.sirius.ui.business.api.session.IEditingSession;
+import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
+import org.eclipse.sirius.ui.business.api.viewpoint.ViewpointSelection.Callback;
+import org.eclipse.sirius.ui.business.api.viewpoint.ViewpointSelectionCallback;
+import org.eclipse.sirius.ui.business.internal.commands.ChangeViewpointSelectionCommand;
+import org.eclipse.sirius.viewpoint.DRepresentation;
+import org.eclipse.sirius.viewpoint.DRepresentationElement;
+import org.eclipse.sirius.viewpoint.SiriusPlugin;
+import org.eclipse.sirius.viewpoint.description.Group;
+import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
+import org.eclipse.sirius.viewpoint.description.Viewpoint;
+import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.junit.Assert;
+import org.osgi.framework.Version;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * The main test case for viewpoint unit tests.
+ *
+ * @author mchauvin
+ */
+public abstract class SiriusTestCase extends TestCase {
+ /** Initialization error message. */
+ public static final String INIT_ERROR_MSG = "An error occurs during tests initialization";
+
+ /**
+ * name of the project created in the test workspace.
+ */
+ protected static final String TEMPORARY_PROJECT_NAME = "DesignerTestProject";
+
+ /**
+ * The default session URI used when there is no session path passed to the
+ * generic setup.
+ */
+ protected static final URI DEFAULT_MODELING_PROJECT_REPRESENTATIONS_FILE_URI = URI.createPlatformResourceURI(File.separator + SiriusTestCase.TEMPORARY_PROJECT_NAME + File.separator
+ + ModelingProject.DEFAULT_REPRESENTATIONS_FILE_NAME, true);
+
+ private static final String DOT = ".";
+
+ /**
+ * The local session.
+ */
+ protected Session session;
+
+ /**
+ * The model request interpreter.
+ */
+ protected IInterpreter interpreter;
+
+ /**
+ * The model accessor.
+ */
+ protected ModelAccessor accessor;
+
+ /**
+ * Semantic model.
+ */
+ protected EObject semanticModel;
+
+ /**
+ * Indicates if the workspace project created during the setup should be a
+ * modeling one.
+ */
+ protected boolean createModelingProject;
+
+ /**
+ * Registered viewpoints.
+ */
+ protected final Set<Viewpoint> viewpoints = new HashSet<Viewpoint>();
+
+ /**
+ * The viewpoint selection callback to use.
+ */
+ protected Callback selectionCallback = new ViewpointSelectionCallback();
+
+ /**
+ * The reported errors.
+ */
+ protected final LinkedHashMultimap<String, IStatus> errors = LinkedHashMultimap.create();
+
+ /**
+ * A default progress monitor test code can use when one is needed.
+ */
+ protected IProgressMonitor defaultProgress = new NullProgressMonitor();
+
+ /**
+ * The unchaught exceptions handler.
+ */
+ private UncaughtExceptionHandler exceptionHandler;
+
+ /**
+ * The platform error listener.
+ */
+ private ILogListener logListener;
+
+ private boolean errorCatchActive;
+
+ /**
+ * HashMaps to store the initial values of preferences before changes.
+ */
+ private final HashMap<String, Object> oldValueDiagramPreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldValueSiriusPreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldValueSiriusUIPreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldPlatformUIPreferences = new HashMap<String, Object>();
+
+ /**
+ * Overridden to create the project.
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // CHECKSTYLE:OFF
+ System.out.println("Setup of " + this.getClass().getName() + SiriusTestCase.DOT + getName() + "()");
+ // CHECKSTYLE:ON
+ setErrorCatchActive(true);
+ if (createModelingProject) {
+ EclipseTestsSupportHelper.INSTANCE.createModelingProject(SiriusTestCase.TEMPORARY_PROJECT_NAME, false);
+ } else {
+ EclipseTestsSupportHelper.INSTANCE.createProject(SiriusTestCase.TEMPORARY_PROJECT_NAME);
+ }
+ }
+
+ /**
+ * Generic set up to create a session.
+ *
+ * @throws Exception
+ * any exception
+ */
+ protected void genericSetUp() throws Exception {
+ genericSetUp(Collections.<String> emptySet(), Collections.<String> emptySet(), null);
+ }
+
+ /**
+ * Generic set up to create a session.
+ *
+ * @param semanticModelPath
+ * the semantic model path
+ * @param modelerDescriptionPath
+ * the modeler description path (PlatformPlugin or
+ * PlatformResource)
+ * @throws Exception
+ * any exception
+ */
+ protected void genericSetUp(final String semanticModelPath, final String modelerDescriptionPath) throws Exception {
+ genericSetUp(semanticModelPath, modelerDescriptionPath, null);
+ }
+
+ /**
+ * Generic set up to create a session.
+ *
+ * @param semanticModelPath
+ * the semantic model path
+ * @param modelerDescriptionPaths
+ * the modeler description paths (PlatformPlugin or
+ * PlatformResource)
+ * @throws Exception
+ * any exception
+ */
+ protected void genericSetUp(final String semanticModelPath, final Collection<String> modelerDescriptionPaths) throws Exception {
+ genericSetUp(Collections.singleton(semanticModelPath), modelerDescriptionPaths, null);
+ }
+
+ /**
+ * Generic set up to open session.
+ *
+ * @param semanticModelPath
+ * the semantic model path
+ * @param modelerDescriptionPath
+ * the modeler description path (PlatformPlugin or
+ * PlatformResource)
+ * @param representationsModelPath
+ * the aird path
+ * @throws Exception
+ * any exception
+ */
+ protected void genericSetUp(final String semanticModelPath, final String modelerDescriptionPath, final String representationsModelPath) throws Exception {
+ genericSetUp(Collections.singleton(semanticModelPath), Collections.singleton(modelerDescriptionPath), representationsModelPath);
+ }
+
+ /**
+ * Generic set up.
+ *
+ * @param semanticModelPaths
+ * the semantic model paths
+ * @param modelerDescriptionPaths
+ * the modeler description paths (PlatformPlugin or
+ * PlatformResource)
+ * @param representationsModelPath
+ * the aird path
+ * @throws Exception
+ * any exception
+ */
+ protected void genericSetUp(final Collection<String> semanticModelPaths, final Collection<String> modelerDescriptionPaths, final String representationsModelPath) throws Exception {
+
+ final List<URI> semanticModelUris = Lists.newArrayList();
+ for (final String semanticModelPath : semanticModelPaths) {
+ semanticModelUris.add(toURI(semanticModelPath));
+ }
+
+ final List<URI> modelerDescUris = Lists.newArrayList();
+ for (final String modelerDescriptionPath : modelerDescriptionPaths) {
+ modelerDescUris.add(toURI(modelerDescriptionPath));
+ }
+ genericSetUp(semanticModelUris, modelerDescUris, true, toURI(representationsModelPath));
+ }
+
+ private URI toURI(final String path) {
+ if (path != null) {
+ URI uri;
+ /*
+ * if path starts with the temporary project name, then we have a
+ * local resource uri
+ */
+ if (path.startsWith(SiriusTestCase.TEMPORARY_PROJECT_NAME)) {
+ uri = URI.createPlatformResourceURI('/' + path, true);
+ } else if (path.startsWith('/' + SiriusTestCase.TEMPORARY_PROJECT_NAME)) {
+ uri = URI.createPlatformResourceURI(path, true);
+ } else {
+ uri = URI.createPlatformPluginURI(path, true);
+ }
+ return uri;
+ }
+ return null;
+ }
+
+ private void genericSetUp(final List<URI> semanticResourceURIs, final List<URI> modelerResourceURIs, boolean createSession, final URI sessionResourceURI) throws Exception {
+ TestsUtil.emptyEventsFromUIThread();
+
+ /* Set no ui callbacks for tests */
+ SiriusEditPlugin.getPlugin().setUiCallback(new NoUICallback());
+
+ createOrLoadAndOpenSession(createSession, sessionResourceURI);
+
+ /* Load the modeler description in the editing domain resource set */
+ if (modelerResourceURIs != null) {
+ for (final URI modelerResourceURI : modelerResourceURIs) {
+ loadModeler(modelerResourceURI, session.getTransactionalEditingDomain());
+ }
+ }
+
+ if (semanticResourceURIs != null && !semanticResourceURIs.isEmpty()) {
+ for (URI semanticResourceURI : semanticResourceURIs) {
+ if (!hasAlreadySemanticResourceLoaded(session, semanticResourceURI)) {
+ Command addSemanticResourceCmd = new AddSemanticResourceCommand(session, semanticResourceURI, new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(addSemanticResourceCmd);
+ }
+ }
+ Iterator<Resource> resourcesIterator = session.getSemanticResources().iterator();
+ if (resourcesIterator.hasNext()) {
+ Resource semanticResource = resourcesIterator.next();
+ if (!semanticResource.getContents().isEmpty()) {
+ semanticModel = semanticResource.getContents().get(0);
+ }
+ }
+
+ }
+
+ accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(session.getTransactionalEditingDomain().getResourceSet());
+ if (semanticModel != null) {
+ interpreter = SiriusPlugin.getDefault().getInterpreterRegistry().getInterpreter(semanticModel);
+ InterpreterRegistry.prepareImportsFromSession(interpreter, session);
+ }
+
+ // Set the auto-refresh to false because it's historically the default
+ // value
+ DefaultScope.INSTANCE.getNode(SiriusPlugin.ID).putBoolean(SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), true);
+ InstanceScope.INSTANCE.getNode(SiriusPlugin.ID).putBoolean(SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), false);
+
+ IDiagramCommandFactory commandFactory = DiagramCommandFactoryService.getInstance().getNewProvider().getCommandFactory(session.getTransactionalEditingDomain());
+ commandFactory.setUserInterfaceCallBack(new NoUICallback());
+
+ closeWelcomePage();
+
+ TestsUtil.emptyEventsFromUIThread();
+
+ /* Initialize error log and uncaught exception handlers */
+ initErrorLoggers();
+ }
+
+ private void createOrLoadAndOpenSession(final boolean createSession, final URI sessionResourceURI) {
+
+ if (createSession) {
+ if (sessionResourceURI == null) {
+ if (createModelingProject) {
+ createSession(SiriusTestCase.DEFAULT_MODELING_PROJECT_REPRESENTATIONS_FILE_URI);
+ } else {
+ createSession(getDefaultRepresentationsFileURI());
+ }
+ } else {
+ createSession(sessionResourceURI);
+ }
+ } else {
+ session = SessionManager.INSTANCE.getSession(sessionResourceURI, new NullProgressMonitor());
+ }
+
+ if (!session.isOpen()) {
+ session.open(new NullProgressMonitor());
+ }
+ }
+
+ /**
+ * The default session URI used when there is no session path passed to the
+ * generic setup. The name of the aird used the name of the test case to
+ * easily debug.
+ *
+ * @return default session URI.
+ */
+ protected URI getDefaultRepresentationsFileURI() {
+
+ return URI.createPlatformResourceURI(
+ File.separator + SiriusTestCase.TEMPORARY_PROJECT_NAME + File.separator + this.getClass().getSimpleName() + "_" + getName() + SiriusTestCase.DOT + ".aird", true);
+ }
+
+ /**
+ * Create and open a session from this URI.
+ *
+ * @param sessionResourceURI
+ * the URI of the session to create.
+ */
+ protected void createSession(final URI sessionResourceURI) {
+ WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
+ @Override
+ protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+ SessionCreationOperation sessionCreationOperation = new DefaultLocalSessionCreationOperation(sessionResourceURI, new NullProgressMonitor());
+ sessionCreationOperation.execute();
+ session = sessionCreationOperation.getCreatedSession();
+ // open UI session part
+ final IEditingSession editingSession = SessionUIManager.INSTANCE.getOrCreateUISession(session);
+ editingSession.open();
+ }
+ };
+ try {
+ operation.run(new NullProgressMonitor());
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException("Impossible to create the session.", e.getCause());
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Impossible to create the session.", e);
+ }
+ }
+
+ private void loadModeler(final URI modelerResourceURI, EditingDomain domain) throws Exception {
+ Group group = null;
+ try {
+ group = (Group) ModelUtils.load(modelerResourceURI, domain.getResourceSet());
+
+ } catch (final IOException exception) {
+ /*
+ * if an IOException occurs here, its probably because we try to
+ * create a plaftorm plugin URI and it was a local one
+ */
+ String uri = modelerResourceURI.toString();
+ if (uri.startsWith("platform:/plugin/")) {
+ URI alternativeURI = URI.createPlatformResourceURI(uri.substring(17), true);
+ group = (Group) ModelUtils.load(alternativeURI, domain.getResourceSet());
+ } else {
+ Assert.fail(exception.getMessage());
+ }
+ }
+ if (group != null) {
+ viewpoints.addAll(group.getOwnedViewpoints());
+ }
+ }
+
+ private boolean hasAlreadySemanticResourceLoaded(Session newSession, URI semanticResourceURI) {
+ for (Resource semanticResource : newSession.getSemanticResources()) {
+ if (semanticResourceURI.equals(semanticResource.getURI())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get a {@link ICommandFactory}. To override to return a custom
+ * {@link ICommandFactory}.
+ *
+ * @return a custom {@link ICommandFactory}
+ */
+ protected abstract ICommandFactory getCommandFactory();
+
+ /**
+ * Close the welcomePage.
+ */
+ protected void closeWelcomePage() {
+ IWorkbenchPart activePart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
+ if (activePart != null && "Welcome".equals(activePart.getTitle()) && activePart instanceof IViewPart) {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().hideView((IViewPart) activePart);
+ }
+ TestsUtil.synchronizationWithUIThread();
+ }
+
+ private void initErrorLoggers() {
+
+ logListener = new ILogListener() {
+
+ @Override
+ public void logging(IStatus status, String plugin) {
+ if (status.getSeverity() == IStatus.ERROR) {
+ errorOccurs(status, plugin);
+ }
+ }
+
+ };
+ Platform.addLogListener(logListener);
+
+ exceptionHandler = new UncaughtExceptionHandler() {
+ private final String sourcePlugin = "Uncaught exception";
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+
+ IStatus status = new Status(IStatus.ERROR, sourcePlugin, sourcePlugin, e);
+ errorOccurs(status, sourcePlugin);
+ }
+ };
+
+ Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
+
+ // setErrorCatchActive(true);
+ }
+
+ private void disposeErrorLoggers() {
+ if (logListener != null) {
+ Platform.removeLogListener(logListener);
+ }
+ }
+
+ /**
+ * check if an error occurs.
+ *
+ * @return true if an error occurs.
+ */
+ protected synchronized boolean doesAnErrorOccurs() {
+ if (errors != null) {
+ return errors.values().size() != 0;
+ }
+ return false;
+ }
+
+ /**
+ * Clear the list of errors. Can be useful when some messages are expected.
+ */
+ protected synchronized void clearErrors() {
+ errors.clear();
+ }
+
+ private synchronized void errorOccurs(IStatus status, String sourcePlugin) {
+ if (errorCatchActive) {
+ errors.put(sourcePlugin, status);
+ }
+ }
+
+ protected synchronized void setErrorCatchActive(boolean errorCatchActive) {
+ this.errorCatchActive = errorCatchActive;
+ }
+
+ protected synchronized boolean isErrorCatchActive() {
+ return errorCatchActive;
+ }
+
+ private void checkErrors() {
+ /* an exception occurs in another thread */
+
+ /*
+ * TODO: skip checkErrors when we are in a shouldSkipUnreliableTests
+ * mode. We have some unwanted resource notifications during the
+ * teardown on jenkins.
+ */
+ if (!TestsUtil.shouldSkipUnreliableTests() && doesAnErrorOccurs()) {
+ Assert.fail(getErrorLoggersMessage());
+ }
+ }
+
+ /**
+ * Compute an error message from the detected errors.
+ *
+ * @return the error message.
+ */
+ protected synchronized String getErrorLoggersMessage() {
+ StringBuilder log1 = new StringBuilder();
+ String br = "\n";
+
+ String testName = getClass().getName();
+
+ log1.append("Error(s) raised during test : " + testName).append(br);
+ for (Entry<String, Collection<IStatus>> entry : errors.asMap().entrySet()) {
+ String reporter = entry.getKey();
+ log1.append(". Log Plugin : " + reporter).append(br);
+
+ for (IStatus status : entry.getValue()) {
+ log1.append(" . " + getSeverity(status) + " from plugin:" + status.getPlugin() + ", message: " + status.getMessage() + ", exception: " + status.getException()).append(br);
+ appendStackTrace(log1, br, status);
+ }
+ log1.append(br);
+ }
+ return log1.toString();
+ }
+
+ /**
+ * Convert the <code>status</code> exception in String and add it at the end
+ * of the <code>stringBuilder</code>. Add the
+ *
+ * @param stringBuilder
+ * The string build to use
+ * @param endLineDelimiter
+ * The end line delimiter to use
+ * @param status
+ * The status to convert
+ */
+ protected void appendStackTrace(StringBuilder stringBuilder, String endLineDelimiter, IStatus status) {
+ PrintWriter pw = null;
+ String stacktrace = null;
+ if (status.getException() != null) {
+ try {
+ StringWriter sw = new StringWriter();
+ pw = new PrintWriter(sw);
+ // CHECKSTYLE:OFF
+ status.getException().printStackTrace(pw);
+ // CHECKSTYLE:ON
+ stacktrace = sw.toString();
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ if (stacktrace == null) {
+ stacktrace = status.getException().toString();
+ }
+ stringBuilder.append(" . Stack trace: " + stacktrace).append(endLineDelimiter);
+ }
+ }
+ }
+
+ /**
+ * Convert the severity of the <code>status</code> in string.
+ *
+ * @param status
+ * The status to convert.
+ * @return a string representation of the severity of the status
+ */
+ protected String getSeverity(IStatus status) {
+ String severity;
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ severity = "Ok";
+ break;
+ case IStatus.INFO:
+ severity = "Info";
+ break;
+ case IStatus.WARNING:
+ severity = "Warning";
+ break;
+ case IStatus.CANCEL:
+ severity = "Cancel";
+ break;
+ case IStatus.ERROR:
+ severity = "Error";
+ break;
+ default:
+ severity = "Unspecified";
+ }
+ return severity;
+ }
+
+ /**
+ * Initialize all viewpoints.
+ */
+ protected final void initViewpoints() {
+ final TransactionalEditingDomain domain = session.getTransactionalEditingDomain();
+ final Command command = new ChangeViewpointSelectionCommand(session, selectionCallback, viewpoints, Collections.<Viewpoint> emptySet(), new NullProgressMonitor());
+ domain.getCommandStack().execute(command);
+ }
+
+ /**
+ * Initialize a viewpoint (and force the initialization of the description
+ * to true).
+ *
+ * @param viewpointName
+ * the name of the viewpoint to initialize.
+ */
+ protected final void initViewpoint(final String viewpointName) {
+ initSirius(viewpointName, session, semanticModel);
+ }
+
+ /**
+ * Initialize a viewpoint.
+ *
+ * @param viewpointName
+ * the name of the viewpoint to initialize.
+ * @param alternateSession
+ * the session to use to initialize the viewpoint
+ * @param alternateSemanticModel
+ * the model to use to initialize the viewpoint
+ * @since 1.1
+ */
+ protected final void initSirius(final String viewpointName, final Session alternateSession, final EObject alternateSemanticModel) {
+ Viewpoint localSessionSirius = null;
+ for (final Viewpoint viewpoint : viewpoints) {
+ if (viewpointName != null && viewpointName.equals(viewpoint.getName())) {
+ localSessionSirius = getViewpointFromName(viewpointName, alternateSession);
+ break;
+ }
+ }
+ if (localSessionSirius != null) {
+ Command changeSiriussSelectionCmd = new ChangeViewpointSelectionCommand(alternateSession, new ViewpointSelectionCallback(), Collections.singleton(localSessionSirius),
+ Collections.<Viewpoint> emptySet(), new NullProgressMonitor());
+ alternateSession.getTransactionalEditingDomain().getCommandStack().execute(changeSiriussSelectionCmd);
+ }
+ }
+
+ /**
+ * Activate a viewpoint.
+ *
+ * @param name
+ * the viewpoint name to activate
+ */
+ protected final void activateViewpoint(final String name) {
+ boolean activatedSirius = false;
+ for (final Viewpoint viewpoint : viewpoints) {
+ if (name.equals(viewpoint.getName())) {
+ Viewpoint viewpointFromName = getViewpointFromName(name, session);
+ Command changeSiriussSelection = new ChangeViewpointSelectionCommand(session, selectionCallback, Collections.singleton(viewpointFromName), Collections.<Viewpoint> emptySet(),
+ new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeSiriussSelection);
+ activatedSirius = true;
+ break;
+ }
+ }
+ if (!activatedSirius) {
+ for (final Viewpoint viewpoint : ViewpointRegistry.getInstance().getViewpoints()) {
+ if (name.equals(viewpoint.getName())) {
+ Viewpoint viewpointFromName = getViewpointFromName(name, session);
+ if (viewpointFromName == null) {
+ viewpoints.add(viewpoint);
+ viewpointFromName = getViewpointFromName(name, session);
+ }
+ Command changeSiriussSelection = new ChangeViewpointSelectionCommand(session, selectionCallback, Collections.singleton(viewpointFromName), Collections.<Viewpoint> emptySet(),
+ new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeSiriussSelection);
+ activatedSirius = true;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Deactivate a viewpoint.
+ *
+ * @param name
+ * the viewpoint name to deactivate
+ */
+ protected final void deactivateSirius(final String name) {
+ boolean deactivatedSirius = false;
+ for (final Viewpoint viewpoint : viewpoints) {
+ if (name.equals(viewpoint.getName())) {
+ Viewpoint viewpointFromName = getViewpointFromName(name, session);
+ Command changeSiriussSelection = new ChangeViewpointSelectionCommand(session, selectionCallback, Collections.<Viewpoint> emptySet(), Collections.singleton(viewpointFromName),
+ new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeSiriussSelection);
+ deactivatedSirius = true;
+ break;
+ }
+ }
+ if (!deactivatedSirius) {
+ for (final Viewpoint viewpoint : ViewpointRegistry.getInstance().getViewpoints()) {
+ if (name.equals(viewpoint.getName())) {
+ Viewpoint viewpointFromName = getViewpointFromName(name, session);
+ Command changeSiriussSelection = new ChangeViewpointSelectionCommand(session, selectionCallback, Collections.<Viewpoint> emptySet(), Collections.singleton(viewpointFromName),
+ new NullProgressMonitor());
+ session.getTransactionalEditingDomain().getCommandStack().execute(changeSiriussSelection);
+ deactivatedSirius = true;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a new representation from the contextual semanticModel & the
+ * contextual Session.
+ *
+ * @param representationDescriptionName
+ * the representation description name
+ * @return the created representation, or <code>null</code> if the
+ * representation description could not be found
+ */
+ protected final DRepresentation createRepresentation(final String representationDescriptionName) {
+ return createRepresentation(representationDescriptionName, representationDescriptionName, semanticModel, session);
+ }
+
+ /**
+ * Create a new representation from the contextual Session.
+ *
+ * @param representationDescriptionName
+ * the representation description name
+ * @param semantic
+ * the semantic root object
+ * @return the created representation, or <code>null</code> if the
+ * representation description could not be found
+ */
+ protected final DRepresentation createRepresentation(final String representationDescriptionName, final EObject semantic) {
+ return createRepresentation(representationDescriptionName, representationDescriptionName, semantic, session);
+ }
+
+ /**
+ * Create a new representation.
+ *
+ * @param representationDescriptionName
+ * the representation description name
+ * @param semantic
+ * the semantic root object
+ * @param sessionToUse
+ * the session to use instead of the contextual Session
+ * @return the created representation, or <code>null</code> if the
+ * representation description could not be found
+ */
+ protected final DRepresentation createRepresentation(final String representationDescriptionName, final EObject semantic, final Session sessionToUse) {
+ return createRepresentation(representationDescriptionName, representationDescriptionName, semantic, sessionToUse);
+ }
+
+ /**
+ * Create a new representation with a specific name.
+ *
+ * @param representationDescriptionName
+ * the representation description name
+ * @param name
+ * the name of the new representation
+ * @param semantic
+ * the semantic root object
+ * @return the created representation, or <code>null</code> if the
+ * representation description could not be found
+ */
+ protected final DRepresentation createRepresentation(final String representationDescriptionName, final String name, final EObject semantic) {
+ return createRepresentation(representationDescriptionName, representationDescriptionName, semantic, session);
+ }
+
+ /**
+ * Create a new representation with a specific name.
+ *
+ * @param representationDescriptionName
+ * the representation description name
+ * @param name
+ * the name of the new representation
+ * @param semantic
+ * the semantic root object
+ * @param sessionToUse
+ * the session to use instead of the contextual Session
+ * @return the created representation, or <code>null</code> if the
+ * representation description could not be found
+ */
+ protected final DRepresentation createRepresentation(final String representationDescriptionName, final String name, final EObject semantic, final Session sessionToUse) {
+
+ final Collection<RepresentationDescription> descriptions = new ArrayList<RepresentationDescription>();
+
+ descriptions.addAll(DialectManager.INSTANCE.getAvailableRepresentationDescriptions(viewpoints, semantic));
+
+ final Command cmd = new RecordingCommand(sessionToUse.getTransactionalEditingDomain()) {
+ private DRepresentation representation;
+
+ @Override
+ protected void doExecute() {
+ for (final RepresentationDescription description : descriptions) {
+ if (description.getName().equals(representationDescriptionName)) {
+ Viewpoint viewpointOfRegistry = (Viewpoint) description.eContainer();
+ Viewpoint localSirius = getViewpointFromName(viewpointOfRegistry.getName());
+ RepresentationDescription localDescription = getLocalSessionRepresentationDescription(localSirius, representationDescriptionName);
+ representation = DialectManager.INSTANCE.createRepresentation(name, semantic, localDescription, sessionToUse, new NullProgressMonitor());
+ return;
+ }
+ }
+ }
+
+ @Override
+ public Collection<?> getResult() {
+ return Collections.singletonList(representation);
+ }
+ };
+
+ TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(semantic);
+ domain.getCommandStack().execute(cmd);
+ final Collection<?> result = cmd.getResult();
+ return result != null ? (DRepresentation) result.toArray()[0] : null;
+ }
+
+ /**
+ * Get a {@link RepresentationDescription} ref from the current session
+ * ResourceSet.
+ *
+ * @param localSirius
+ * the Sirius local to the current session ResourceSet containing
+ * the {@link RepresentationDescription} to get
+ *
+ * @param representationDescriptionName
+ * the name of the {@link RepresentationDescription} to get
+ *
+ * @return the {@link RepresentationDescription} to get
+ */
+ private RepresentationDescription getLocalSessionRepresentationDescription(Viewpoint localSirius, String representationDescriptionName) {
+ Iterable<RepresentationDescription> candidates = new ViewpointQuery(localSirius).getAllRepresentationDescriptions();
+ RepresentationDescription result = null;
+ for (RepresentationDescription localDescription : candidates) {
+ if (representationDescriptionName.equals(localDescription.getName())) {
+ result = localDescription;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get a viewpoint in the viewpoints Set named viewpointName, null else.
+ *
+ * @param viewpointName
+ * the viewpointName to look for
+ *
+ * @return the first {@link Viewpoint} of the viewpoints Set
+ */
+ public Viewpoint getViewpointFromName(String viewpointName) {
+ return getViewpointFromName(viewpointName, session);
+ }
+
+ /**
+ * Get a viewpoint in the viewpoints Set named viewpointName, null else.
+ *
+ * @param viewpointName
+ * the viewpointName to look for
+ *
+ * @param sessionToUse
+ * the Session from which ResourceSet to return the Sirius
+ *
+ * @return the first {@link Viewpoint} of the viewpoints Set, return a
+ * logical Sirius from the session's ResourceSet and not from the
+ * SiriusRegistry's ResourceSet
+ */
+ public Viewpoint getViewpointFromName(String viewpointName, Session sessionToUse) {
+ Viewpoint localViewpoint = null;
+ for (Viewpoint viewpoint : viewpoints) {
+ if (viewpoint.getName() != null && viewpoint.getName().equals(viewpointName)) {
+ URI viewpointResourceURI = viewpoint.eResource().getURI();
+ Resource newSiriusResource = sessionToUse.getTransactionalEditingDomain().getResourceSet().getResource(viewpointResourceURI, true);
+ if (!newSiriusResource.getContents().isEmpty() && newSiriusResource.getContents().get(0) instanceof Group) {
+ Group group = (Group) newSiriusResource.getContents().get(0);
+ Iterator<Viewpoint> iter = group.getOwnedViewpoints().iterator();
+
+ while (iter.hasNext() && localViewpoint == null) {
+ Viewpoint someLocalViewpoint = iter.next();
+ if (someLocalViewpoint.getName() != null && someLocalViewpoint.getName().equals(viewpointName)) {
+ localViewpoint = someLocalViewpoint;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ return localViewpoint;
+ }
+
+ /**
+ * Get a {@link RepresentationDescription} named
+ * <code>representationDescriptionName</code> owned by
+ * <code>viewpoint</code>.
+ *
+ * @param representationDescriptionName
+ * the name of the {@link RepresentationDescription} to search
+ *
+ * @param viewpoint
+ * the {@link Viewpoint} in which to search
+ *
+ * @return the found {@link RepresentationDescription} or null if nothing
+ * found
+ */
+ public RepresentationDescription getRepresentationDescription(String representationDescriptionName, Viewpoint viewpoint) {
+ RepresentationDescription result = null;
+ for (RepresentationDescription ownedRepresentationDescription : viewpoint.getOwnedRepresentations()) {
+ if (representationDescriptionName.equals(ownedRepresentationDescription.getName())) {
+ result = ownedRepresentationDescription;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get all the representation with the given representation description
+ * name.
+ *
+ * @param representationDescriptionName
+ * the name of the representation description. <code>null</code>
+ * is not excepted.
+ * @return a {@link Collection} with all representations retrieved.
+ */
+ protected final Collection<DRepresentation> getRepresentations(final String representationDescriptionName) {
+ final Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getAllRepresentations(session);
+
+ final Collection<DRepresentation> representations = new HashSet<DRepresentation>();
+
+ for (final DRepresentation representation : allRepresentations) {
+ final RepresentationDescription desc = DialectManager.INSTANCE.getDescription(representation);
+ if (representationDescriptionName.equals(desc.getName())) {
+ representations.add(representation);
+ }
+ }
+ return representations;
+ }
+
+ /**
+ * Get all the representation with the given representation description name
+ * in the given session.
+ *
+ * @param name
+ * the name. <code>null</code> is not excepted.
+ * @param alternateSession
+ * the session to look for representation
+ * @return a {@link Collection} with all representations retrieved.
+ */
+ protected final Collection<DRepresentation> getRepresentations(final String name, final Session alternateSession) {
+ final Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getAllRepresentations(alternateSession);
+
+ final Collection<DRepresentation> representations = new HashSet<DRepresentation>();
+
+ for (final DRepresentation representation : allRepresentations) {
+ final RepresentationDescription desc = DialectManager.INSTANCE.getDescription(representation);
+ if (name.equals(desc.getName())) {
+ representations.add(representation);
+ }
+ }
+ return representations;
+ }
+
+ /**
+ * Get all the representation with the given representation description name
+ * in the given session.
+ *
+ * @param name
+ * the name. <code>null</code> is not excepted.
+ * @param semantic
+ * the semantic target of the representation.
+ * @param alternateSession
+ * the session to look for representation
+ * @return a {@link Collection} with all representations retrieved.
+ */
+ protected final Collection<DRepresentation> getRepresentations(final String name, final EObject semantic, final Session alternateSession) {
+ final Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getRepresentations(semantic, alternateSession);
+
+ final Collection<DRepresentation> representations = new HashSet<DRepresentation>();
+
+ for (final DRepresentation representation : allRepresentations) {
+ final RepresentationDescription desc = DialectManager.INSTANCE.getDescription(representation);
+ if (name.equals(desc.getName())) {
+ representations.add(representation);
+ }
+ }
+ return representations;
+ }
+
+ /**
+ * Get all the representation with the given representation description
+ * name.
+ *
+ * @param name
+ * the name. <code>null</code> is not excepted.
+ * @param semantic
+ * the semantic target of the representation.
+ * @return a {@link Collection} with all representations retrieved.
+ */
+ protected final Collection<DRepresentation> getRepresentations(final String name, final EObject semantic) {
+ final Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getRepresentations(semantic, session);
+
+ final Collection<DRepresentation> representations = new HashSet<DRepresentation>();
+
+ for (final DRepresentation representation : allRepresentations) {
+ final RepresentationDescription desc = DialectManager.INSTANCE.getDescription(representation);
+ if (name.equals(desc.getName())) {
+ representations.add(representation);
+ }
+ }
+ return representations;
+ }
+
+ /**
+ * Refresh a representation.
+ *
+ * @param representation
+ * the representation to refresh.
+ */
+ protected void refresh(final DRepresentation representation) {
+ RefreshActionListenerRegistry.INSTANCE.notifyRepresentationIsAboutToBeRefreshed(representation);
+ RefreshRepresentationsCommand command = new RefreshRepresentationsCommand(session.getTransactionalEditingDomain(), new NullProgressMonitor(), representation);
+ command.setLabel("refresh from testcase");
+ session.getTransactionalEditingDomain().getCommandStack().execute(command);
+ }
+
+ /**
+ * Get the representation element from the semantic one.
+ *
+ * @param representation
+ * the representation
+ * @param semanticElement
+ * the semantic element
+ * @return the first representation element which has as target the semantic
+ * element given as parameter
+ */
+ protected final DRepresentationElement getFirstRepresentationElement(final DRepresentation representation, final EObject semanticElement) {
+ for (final DRepresentationElement element : representation.getRepresentationElements()) {
+ if (element.getTarget() == semanticElement) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the representation element from the semantic one.
+ *
+ * @param <T>
+ * generic type
+ * @param representation
+ * the representation
+ * @param semanticElement
+ * the semantic element
+ * @param clazz
+ * the type of representation element
+ * @return the first representation element which has as target the semantic
+ * element given as parameter
+ */
+ @SuppressWarnings("unchecked")
+ protected final <T> T getFirstRepresentationElement(final DRepresentation representation, final EObject semanticElement, final Class<T> clazz) {
+ for (final DRepresentationElement element : representation.getRepresentationElements()) {
+ if (clazz.isInstance(element) && element.getTarget() == semanticElement) {
+ return (T) element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get all representation elements which target a given semantic element
+ * from a representation.
+ *
+ * @param representation
+ * the representation
+ * @param semanticElement
+ * the target semantic element
+ * @return all the graphical elements with the given semantic element as
+ * target
+ */
+ protected final Collection<DRepresentationElement> getAllRepresentationElements(final DRepresentation representation, final EObject semanticElement) {
+ final Collection<DRepresentationElement> elements = new HashSet<DRepresentationElement>();
+ for (final DRepresentationElement element : representation.getRepresentationElements()) {
+ if (element.getTarget() == semanticElement) {
+ elements.add(element);
+ }
+ }
+ return elements;
+ }
+
+ /**
+ * Execute a command.
+ *
+ * @param cmd
+ * the command to execute
+ * @return <code>true</code> if the execution succeed, <code>false</code>
+ * otherwise
+ */
+ protected boolean executeCommand(final Command cmd) {
+ boolean result = cmd.canExecute();
+ session.getTransactionalEditingDomain().getCommandStack().execute(cmd);
+ return result;
+ }
+
+ /**
+ * Delete every project in the workspace.
+ */
+ protected void cleanWorkspace() {
+ for (final IProject proj : Lists.newArrayList(ResourcesPlugin.getWorkspace().getRoot().getProjects())) {
+ EclipseTestsSupportHelper.INSTANCE.deleteProject(proj.getName());
+ }
+ }
+
+ /**
+ * Copies the files located at the given paths into the test project.
+ *
+ * @param pluginID
+ * the plugin id
+ * @param pluginCommonPath
+ * the relative path in plugin
+ * @param filePaths
+ * the paths of the files to copy
+ */
+ protected void copyFilesToTestProject(String pluginID, String pluginCommonPath, String... filePaths) {
+ EclipseTestsSupportHelper.INSTANCE.createProject(SiriusTestCase.TEMPORARY_PROJECT_NAME);
+ for (final String path : filePaths) {
+ final String pluginFilePath = pluginCommonPath + path;
+ final String wksPath = SiriusTestCase.TEMPORARY_PROJECT_NAME + "/" + path;
+ EclipseTestsSupportHelper.INSTANCE.copyFile(pluginID, pluginFilePath, wksPath);
+ }
+ }
+
+ /**
+ * Close UI session.
+ *
+ * @param sessionToClose
+ * the session to close.
+ */
+ protected void closeSession(final Session sessionToClose) {
+ if (sessionToClose != null) {
+ final IEditingSession sessionUI = SessionUIManager.INSTANCE.getUISession(sessionToClose);
+ if (sessionUI != null) {
+ SessionUIManager.INSTANCE.remove(sessionUI);
+ sessionUI.close();
+ TestsUtil.synchronizationWithUIThread();
+ }
+ sessionToClose.close(new NullProgressMonitor());
+ TestsUtil.synchronizationWithUIThread();
+ for (final Session s : SessionManager.INSTANCE.getSessions()) {
+ Assert.assertFalse("Remove failed", s.equals(sessionToClose));
+ }
+ if (sessionToClose.isOpen()) {
+ sessionToClose.close(new NullProgressMonitor());
+ TestsUtil.synchronizationWithUIThread();
+ }
+ }
+ }
+
+ /**
+ * Close and reopen a UI session with saving.
+ *
+ * @throws Exception
+ * exception
+ */
+ protected void closeAndReloadSession() throws Exception {
+ final URI sessionResourceURI = session.getSessionResource().getURI();
+
+ /* close session */
+ TestsUtil.synchronizationWithUIThread();
+ closeSession(session);
+ TestsUtil.synchronizationWithUIThread();
+
+ /* reload session */
+ session = SessionManager.INSTANCE.getSession(sessionResourceURI, new NullProgressMonitor());
+
+ if (!session.isOpen()) {
+ session.open(new NullProgressMonitor());
+ }
+ SessionUIManager.INSTANCE.getOrCreateUISession(session).open();
+ TestsUtil.synchronizationWithUIThread();
+
+ Assert.assertNotNull(session);
+
+ /* Set again the variables that have been lost during the unload. */
+ interpreter = session.getInterpreter();
+ if (!session.getSemanticResources().isEmpty()) {
+ Resource resource = session.getSemanticResources().iterator().next();
+ if (resource.getContents() != null && !resource.getContents().isEmpty()) {
+ semanticModel = resource.getContents().get(0);
+ accessor = SiriusPlugin.getDefault().getModelAccessorRegistry().getModelAccessor(semanticModel);
+ }
+ }
+ }
+
+ /**
+ * Change a preference and store the old value. It will be automatically
+ * reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeDiagramPreference(String preferenceKey, Integer newValue) {
+ final IPreferenceStore prefs = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ oldValueDiagramPreferences.put(preferenceKey, prefs.getInt(preferenceKey));
+ prefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeDiagramPreference(String preferenceKey, Boolean newValue) {
+ final IPreferenceStore prefs = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ oldValueDiagramPreferences.put(preferenceKey, prefs.getBoolean(preferenceKey));
+ prefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Restore this preference to its initial value. Should be called after
+ * {@link #changeDiagramPreference(String, Boolean)} of
+ * {@link #changeDiagramPreference(String, Integer)} to have effect.
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ */
+ protected void resetDiagramPreference(String preferenceKey) {
+ final IPreferenceStore prefs = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ for (String key : oldValueDiagramPreferences.keySet()) {
+ if (key.equals(preferenceKey)) {
+ if (oldValueDiagramPreferences.get(key) instanceof Boolean) {
+ prefs.setValue(key, (Boolean) oldValueDiagramPreferences.get(key));
+ } else if (oldValueDiagramPreferences.get(key) instanceof Integer) {
+ prefs.setValue(key, (Integer) oldValueDiagramPreferences.get(key));
+ }
+ }
+ }
+ }
+
+ /**
+ * Change a boolean preference and store the old value to reset it after the
+ * test.
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changePlatformUIPreference(String preferenceKey, Boolean newValue) {
+ IPreferenceStore platformUIPrefs = PlatformUI.getPreferenceStore();
+ oldPlatformUIPreferences.put(preferenceKey, platformUIPrefs.getBoolean(preferenceKey));
+ platformUIPrefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeSiriusPreference(String preferenceKey, Boolean newValue) {
+ boolean oldValue = Platform.getPreferencesService().getBoolean(SiriusPlugin.ID, preferenceKey, false, null);
+ oldValueSiriusPreferences.put(preferenceKey, oldValue);
+
+ IEclipsePreferences corePreferences = InstanceScope.INSTANCE.getNode(SiriusPlugin.ID);
+ corePreferences.putBoolean(preferenceKey, newValue);
+
+ String message = "The " + preferenceKey + " preference value was not changed for plugin " + SiriusPlugin.ID;
+ boolean valueToCheck = Platform.getPreferencesService().getBoolean(SiriusPlugin.ID, preferenceKey, false, null);
+ TestCase.assertEquals(message, newValue.booleanValue(), valueToCheck);
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeSiriusUIPreference(String preferenceKey, Boolean newValue) {
+ Collection<SiriusPreferencesKeys> coreValues = Lists.newArrayList(SiriusPreferencesKeys.values());
+ Function<SiriusPreferencesKeys, String> prefToName = new Function<SiriusPreferencesKeys, String>() {
+ @Override
+ public String apply(SiriusPreferencesKeys input) {
+ return input.name();
+ }
+ };
+ TestCase.assertFalse("The DesignerPreferenceKey named " + preferenceKey + " should not be modified in the UI store.",
+ Lists.newArrayList(Iterables.transform(coreValues, prefToName)).contains(preferenceKey));
+
+ IPreferenceStore viewpointUIPrefs = SiriusEditPlugin.getPlugin().getPreferenceStore();
+ oldValueSiriusUIPreferences.put(preferenceKey, viewpointUIPrefs.getBoolean(preferenceKey));
+ viewpointUIPrefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Clean the current session
+ */
+ private void cleanCurrentSession() {
+ /* close the session */
+ if (session != null) {
+ final IEditingSession sessionUI = SessionUIManager.INSTANCE.getUISession(session);
+ if (sessionUI != null) {
+ SessionUIManager.INSTANCE.remove(sessionUI);
+ sessionUI.close();
+ TestsUtil.synchronizationWithUIThread();
+ }
+ if (session.isOpen()) {
+ /* close the session */
+
+ if (!TestsUtil.shouldSkipUnreliableTests()) {
+ session.close(new NullProgressMonitor());
+ } else {
+ // CHECKSTYLE:OFF
+ try {
+ session.close(new NullProgressMonitor());
+ } catch (final Exception e) {
+ System.err.println(e.getMessage());
+ }
+ // CHECKSTYLE:ON
+ }
+ TestsUtil.synchronizationWithUIThread();
+ }
+ session = null;
+ }
+ }
+
+ private void closeAllSessions() {
+ for (final Session managerSession : Lists.newArrayList(SessionManager.INSTANCE.getSessions())) {
+ if (managerSession.isOpen()) {
+ managerSession.close(new NullProgressMonitor());
+ TestsUtil.synchronizationWithUIThread();
+ }
+ }
+ }
+
+ /**
+ * This will undo the last Command if possible and return <code>True</code>
+ * if it is, <code>False</code> otherwise.
+ *
+ * @return <code>True</code> if the command was undoable, <code>False</code>
+ * otherwise.
+ * @throws Exception
+ * In case of problem
+ */
+ protected boolean undo() throws Exception {
+ CommandStack commandStack = session.getTransactionalEditingDomain().getCommandStack();
+ final boolean result = commandStack.canUndo();
+ if (result) {
+ commandStack.undo();
+ }
+ return result;
+ }
+
+ /**
+ * This will redo the last undone Command if possible and return
+ * <code>True</code> if it is, <code>False</code> otherwise.
+ *
+ * @return <code>True</code> if the command was undoable, <code>False</code>
+ * otherwise.
+ * @throws Exception
+ * In case of problem
+ */
+ protected boolean redo() throws Exception {
+ CommandStack commandStack = session.getTransactionalEditingDomain().getCommandStack();
+ final boolean result = commandStack.canRedo();
+ if (result) {
+ commandStack.redo();
+ }
+ return result;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ createModelingProject = false;
+ setErrorCatchActive(false);
+
+ TransactionalEditingDomain domain = null;
+
+ /* close the session */
+ if (session != null) {
+ domain = session.getTransactionalEditingDomain();
+ cleanCurrentSession();
+ }
+
+ closeAllSessions();
+ // Add a emptyEventsFromUIThread here to wait the closing of all editors
+ // before disposing the editing domain.
+ TestsUtil.emptyEventsFromUIThread();
+
+ if (domain != null) {
+ LinkedHashSet<Group> groups = Sets.<Group> newLinkedHashSet();
+
+ for (Viewpoint vp : viewpoints) {
+ if (vp.eContainer() instanceof Group) {
+ groups.add((Group) vp.eContainer());
+ }
+ }
+
+ for (final Resource resource : Lists.newArrayList(domain.getResourceSet().getResources())) {
+ resource.unload();
+ }
+
+ for (final Group modelerModele : groups) {
+ domain.getResourceSet().getResources().remove(modelerModele.eResource());
+ }
+
+ domain.getResourceSet().getResources().clear();
+ if (domain.getCommandStack() != null) {
+ domain.getCommandStack().flush();
+ }
+ /* dispose the editing domain */ /**
+ * {@inheritDoc}
+ */
+ // CHECKSTYLE:OFF
+ try {
+ domain.dispose();
+ } catch (final Exception e) {
+ /* don't worry, that's normal :D */
+ }
+ // CHECKSTYLE:ON
+ }
+ TestsUtil.synchronizationWithUIThread();
+ viewpoints.clear();
+
+ /* Delete the temporary project */
+ cleanWorkspace();
+
+ disposeErrorLoggers();
+ TestsUtil.emptyEventsFromUIThread();
+ // Reset the preferences changed during the test with the method
+ // changePreference
+ IPreferenceStore diagramPreferences = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ for (String key : oldValueDiagramPreferences.keySet()) {
+ if (oldValueDiagramPreferences.get(key) instanceof Boolean) {
+ diagramPreferences.setValue(key, (Boolean) oldValueDiagramPreferences.get(key));
+ } else if (oldValueDiagramPreferences.get(key) instanceof Integer) {
+ diagramPreferences.setValue(key, (Integer) oldValueDiagramPreferences.get(key));
+ }
+ }
+ IEclipsePreferences corePreferences = InstanceScope.INSTANCE.getNode(SiriusPlugin.ID);
+ for (String key : oldValueSiriusPreferences.keySet()) {
+ corePreferences.putBoolean(key, (Boolean) oldValueSiriusPreferences.get(key));
+ }
+ IPreferenceStore viewpointUIPrefs = SiriusEditPlugin.getPlugin().getPreferenceStore();
+ for (String key : oldValueSiriusUIPreferences.keySet()) {
+ viewpointUIPrefs.setValue(key, (Boolean) oldValueSiriusUIPreferences.get(key));
+ }
+ IPreferenceStore platformUIPrefs = PlatformUI.getPreferenceStore();
+ for (String key : oldPlatformUIPreferences.keySet()) {
+ platformUIPrefs.setValue(key, (Boolean) oldPlatformUIPreferences.get(key));
+ }
+
+ checkErrors();
+
+ new TestCaseCleaner(this).clearAllFields();
+
+ super.tearDown();
+ }
+
+ /**
+ * Disable the specific dialect editor dialogs.
+ *
+ * @param editor
+ * The editor on which disable the dialogs.
+ * @param shouldReloadSession
+ * true if the session must be reload, false otherwise
+ */
+ protected void disableUICallBackOnDialectEditor(DialectEditor editor, final boolean shouldReloadSession) {
+ editor.setDialogFactory(new DialectEditorDialogFactory() {
+
+ @Override
+ public void editorWillBeClosedInformationDialog(Shell parent) {
+ // do nothing
+ }
+
+ @Override
+ public void informUserOfEvent(int severity, String message) {
+ // do nothing
+ }
+ });
+ }
+
+ /**
+ * Find a viewpoint by name from the global registry.
+ *
+ * @param name
+ * name of the Sirius to look for.
+ * @return the first Sirius found in the registry with the specified name,
+ * if any. The instance returned is the one from the Sirius
+ * registry's editing domain.
+ */
+ protected Option<Viewpoint> findSirius(String name) {
+ for (Viewpoint vp : ViewpointRegistry.getInstance().getViewpoints()) {
+ if (vp.getName().equals(name)) {
+ return Options.newSome(vp);
+ }
+ }
+ return Options.newNone();
+ }
+
+ /**
+ * Return all resource type ecore or aird in resource set passed in
+ * parameter.
+ *
+ * @param rs
+ * the resource set.
+ * @return list of aird and ecore contains in resource set.
+ */
+ protected List<Resource> getResourceTypeAirdOrEcore(ResourceSet rs) {
+ List<Resource> resourcesAirdAndEcore = new ArrayList<Resource>();
+ for (Resource resource : rs.getResources()) {
+ if (resource instanceof AirdResource) {
+ resourcesAirdAndEcore.add(resource);
+ } else if ("ecore".equals(resource.getURI().fileExtension())) {
+ resourcesAirdAndEcore.add(resource);
+ }
+ }
+ return resourcesAirdAndEcore;
+ }
+
+ /**
+ * Check that the data has the expected migration need.
+ *
+ * It can be used to verify that a file has not be migrated before the test.
+ * And then it allows to check the effect of the migration in the other
+ * test.
+ *
+ * @param representationFileURI
+ * the uri of the representation file to check.
+ * @param needsMigration
+ * indicates the expected migration need.
+ * @return the loaded @link {@link Version} for convenience
+ */
+ protected Version checkRepresentationFileMigrationStatus(URI representationFileURI, boolean needsMigration) {
+ RepresentationsFileVersionSAXParser parser = new RepresentationsFileVersionSAXParser(representationFileURI);
+ return checkMigrationStatusOnData(representationFileURI, parser, RepresentationsFileMigrationService.getInstance(), needsMigration);
+ }
+
+ /**
+ * Check that the data has the expected migration need.
+ *
+ * It can be used to verify that a file has not be migrated before the test.
+ * And then it allows to check the effect of the migration in the other
+ * test.
+ *
+ * @param vsmFileURI
+ * the uri of the VSM file to check.
+ * @param needsMigration
+ * indicates the expected migration need.
+ * @return the loaded @link {@link Version} for convenience
+ */
+ protected Version checkVsmFileMigrationStatus(URI vsmFileURI, boolean needsMigration) {
+ VSMVersionSAXParser parser = new VSMVersionSAXParser(vsmFileURI);
+ return checkMigrationStatusOnData(vsmFileURI, parser, VSMMigrationService.getInstance(), needsMigration);
+ }
+
+ /**
+ * Check that the data were not migrated before the test. It allows to check
+ * the effect of the migration in the other test.
+ *
+ * @param fileURI
+ * the uri of the file to check.
+ *
+ * @param needsMigration
+ * indicates the expected migration need.
+ * @return the loaded @link {@link Version} for convenience
+ */
+ private Version checkMigrationStatusOnData(URI fileURI, AbstractVersionSAXParser versionSaxPArser, AbstractSiriusMigrationService migrationService, boolean needsMigration) {
+ // Get the version before the migration.
+ String sLoadedVersion = versionSaxPArser.getVersion(new NullProgressMonitor());
+
+ // String version can be null for old models or models not created with
+ // the tool.
+ Version loadedVersion = Version.parseVersion(sLoadedVersion);
+ TestCase.assertNotNull("The parsed version is null, check the file: " + fileURI.toPlatformString(true), loadedVersion);
+
+ // Check that the migration service detect if the migration is needed.
+ boolean migrationIsNeeded = migrationService.isMigrationNeeded(loadedVersion);
+
+ if (needsMigration) {
+ TestCase.assertTrue("The current test case checks a migration behavior, please revert the manual migration on : " + fileURI.toPlatformString(true), migrationIsNeeded);
+ } else {
+ TestCase.assertFalse("The current test case expect a file which does not need migration : " + fileURI.toPlatformString(true), migrationIsNeeded);
+ }
+
+ return loadedVersion;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestCaseCleaner.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestCaseCleaner.java
new file mode 100644
index 0000000000..38b896de3a
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestCaseCleaner.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import junit.framework.TestCase;
+
+/**
+ * A helper to forcibly clear all the fields of a test case to avoid retaining
+ * too many objects and resources in memory during a long test suite.
+ *
+ * @author pcdavid
+ */
+public class TestCaseCleaner {
+ private static final Class<?> ROOT_CLASS = TestCase.class;
+
+ private final TestCase target;
+
+ /**
+ * Constructor.
+ *
+ * @param target
+ * the test case instance to clean.
+ */
+ public TestCaseCleaner(TestCase target) {
+ this.target = target;
+ }
+
+ /**
+ * Clears (i.e. sets to null) all non-primitive and non-final fields of the
+ * target test case except those which are declared in ROOT_CLASS.
+ *
+ * @throws IllegalAccessException
+ * if if was not possible to access to some of the field by
+ * reflection.
+ */
+ public void clearAllFields() throws IllegalAccessException {
+ for (Class<?> current = target.getClass(); current != TestCaseCleaner.ROOT_CLASS; current = current.getSuperclass()) {
+ clearFieldsFrom(current);
+ }
+ }
+
+ private void clearFieldsFrom(Class<?> klass) {
+ for (Field field : klass.getDeclaredFields()) {
+ boolean isReference = !field.getType().isPrimitive();
+ try {
+ field.setAccessible(true);
+ boolean isSet = field.get(target) != null;
+ if (isReference && isSet) {
+ clearField(field);
+ }
+ } catch (IllegalArgumentException e) {
+ // Do nothing
+ } catch (IllegalAccessException e) {
+ // Do nothing
+ }
+ }
+ }
+
+ private void clearField(Field field) throws IllegalAccessException {
+ boolean isFinal = Modifier.isFinal(field.getModifiers());
+ if (!isFinal) {
+ field.set(target, null);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestsUtil.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestsUtil.java
new file mode 100644
index 0000000000..bc026d54af
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TestsUtil.java
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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
+ * Ketan Padegaonkar and others - the various waitUntil() methods come
+ * from org.eclipse.swtbot.swt.finder.SWTBotFactory
+ */
+package org.eclipse.sirius.tests.support.api;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.ui.PlatformUI;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * Useful operation common to test cases.
+ *
+ * @author mchauvin
+ */
+public final class TestsUtil {
+
+ /**
+ * Constructor.
+ */
+ protected TestsUtil() {
+ // Nothing
+ }
+
+ /**
+ * Wait the end of the asynchronous calls in UI Thread and ignore the
+ * Exception. <B>Use this exclusively</B> in the setup method to ensure a
+ * clean environment.
+ */
+ public static void emptyEventsFromUIThread() {
+ boolean shouldRetry = false;
+ do {
+ try {
+ TestsUtil.synchronizationWithUIThread();
+ shouldRetry = false;
+ // CHECKSTYLE:OFF
+ } catch (final Exception e) {
+ // CHECKSTYLE:ON
+ shouldRetry = true;
+ }
+ } while (shouldRetry);
+ }
+
+ /**
+ * Wait the end of the asynchronous calls waiting in UI thread.
+ */
+ public static void synchronizationWithUIThread() {
+ while (PlatformUI.getWorkbench().getDisplay().readAndDispatch()) {
+ // Do nothing, just wait
+ }
+ }
+
+ /**
+ * Tests whether the environment is configured to skip non-critical tests
+ * which take a long time. This possibility to skip some tests should only
+ * be used on developer machines to get faster feedback, and never on a
+ * continuous integration server.
+ *
+ * @return <code>true</code> if the environment is setup to skip long tests.
+ */
+ public static boolean shouldSkipLongTests() {
+ return "true".equals(System.getProperty("org.eclipse.sirius.tests.skipLongTests"));
+ }
+
+ /**
+ * Tests whether unreliable tests should be run. See
+ * {@link #shouldSkipUnreliableTests()}. Can be used in tests as:
+ *
+ * <pre>
+ * Assume.assumeTrue(TestUtil.shouldRunUnreliableTests())
+ * </pre>
+ *
+ * at the beginning of such tests.
+ *
+ * @return <code>true</code> iff unreliable tests should be run.
+ */
+ public static boolean shouldRunUnreliableTests() {
+ return !TestsUtil.shouldSkipUnreliableTests();
+ }
+
+ /**
+ * Tests whether the environment is configured to skip tests which are known
+ * to be unreliable (i.e. they sometimes work, sometimes fail).
+ *
+ * @return <code>true</code> if the environment is setup to skip unreliable
+ * tests.
+ */
+ public static boolean shouldSkipUnreliableTests() {
+ return "true".equals(System.getProperty("org.eclipse.sirius.tests.skipUnreliableTests"));
+ }
+
+ /**
+ * Tests whether long running tests should be run. See
+ * {@link #shouldSkipLongTests()}. Can be used in tests as:
+ *
+ * <pre>
+ * Assume.assumeTrue(TestUtil.shouldRunLongTests())
+ * </pre>
+ *
+ * at the beginning of such tests.
+ *
+ * @return <code>true</code> iff long running tests should be run.
+ */
+ public static boolean shouldRunLongTests() {
+ return !TestsUtil.shouldSkipLongTests();
+ }
+
+ /**
+ * Tells if the current platform corresponds to juno3 (i.e. Eclipse 3.8).
+ *
+ * @return true if the current platform corresponds to juno3 (i.e. Eclipse
+ * 3.8), false else
+ */
+ public static boolean isJuno3Platform() {
+ boolean isJuno3Platform = false;
+ String platformVersion = Platform.getBundle("org.eclipse.core.runtime").getHeaders().get("Bundle-Version");
+ if (platformVersion.startsWith("3.8")) {
+ isJuno3Platform = true;
+ }
+ return isJuno3Platform;
+ }
+
+ /**
+ * Tells if the current platform corresponds to Juno, Kepler, .. (i.e.
+ * Eclipse 4.x).
+ *
+ * @return true if the current platform corresponds to eclipse 4.x, false
+ * otherwise.
+ */
+ public static boolean isEclipse4xPlatform() {
+ /*
+ * Juno/Kepler Core Runtime plugins version are 3.8/3.9 and not 4.x. So
+ * the "org.eclipse.ui.workbench" is used instead.
+ */
+
+ boolean isEclipse4Platform = false;
+ Version junoStart = Version.parseVersion("3.103");
+ Bundle uiWorkbenchBundle = Platform.getBundle("org.eclipse.ui.workbench");
+ if (uiWorkbenchBundle != null && uiWorkbenchBundle.getVersion().compareTo(junoStart) >= 0) {
+ isEclipse4Platform = true;
+ }
+ return isEclipse4Platform;
+ }
+
+ /**
+ * Copied and adapted from
+ * org.eclipse.swtbot.swt.finder.SWTBotFactory.waitUntil(ICondition, long,
+ * long)
+ *
+ * Waits until the condition has been meet, or the timeout is reached. The
+ * interval is the delay between evaluating the condition after it has
+ * failed.
+ *
+ * @param condition
+ * the condition to be evaluated.
+ * @param timeout
+ * the timeout.
+ * @param interval
+ * The delay time.
+ */
+ public static void waitUntil(ICondition condition, long timeout, long interval) {
+ Assert.assertTrue("interval value is negative", interval >= 0); //$NON-NLS-1$
+ Assert.assertTrue("timeout value is negative", timeout >= 0); //$NON-NLS-1$
+ long limit = System.currentTimeMillis() + timeout;
+ while (true) {
+ try {
+ if (condition.test()) {
+ return;
+ }
+ // CHECKSTYLE:OFF
+ } catch (Throwable e) {
+ // dO nothing
+ }
+ // CHECKSTYLE:ON
+
+ try {
+ Thread.sleep(interval);
+ } catch (InterruptedException e) {
+ Assert.fail(e.getMessage());
+ }
+ if (System.currentTimeMillis() > limit) {
+ Assert.fail("Timeout after: " + timeout + " ms.: " + condition.getFailureMessage());
+ }
+ }
+ }
+
+ /**
+ * Copied and adapted from
+ * org.eclipse.swtbot.swt.finder.SWTBotFactory.waitUntil(ICondition, long,
+ * long)
+ *
+ * Waits until the condition has been meet, or the timeout is reached. The
+ * interval is the delay between evaluating the condition after it has
+ * failed.
+ *
+ * Interval : 500
+ *
+ * @param condition
+ * the condition to be evaluated.
+ * @param timeout
+ * the timeout.
+ */
+ public static void waitUntil(ICondition condition, long timeout) {
+ TestsUtil.waitUntil(condition, timeout, 500);
+ }
+
+ /**
+ * Copied and adapted from
+ * org.eclipse.swtbot.swt.finder.SWTBotFactory.waitUntil(ICondition, long,
+ * long)
+ *
+ * Waits until the condition has been meet, or the timeout is reached. The
+ * interval is the delay between evaluating the condition after it has
+ * failed.
+ *
+ * Timeout: 5000 Interval : 500
+ *
+ * @param condition
+ * the condition to be evaluated.
+ */
+ public static void waitUntil(ICondition condition) {
+ TestsUtil.waitUntil(condition, 5000, 500);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TreeItemImageQuery.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TreeItemImageQuery.java
new file mode 100644
index 0000000000..467ffbd7e6
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/api/TreeItemImageQuery.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.api;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that get the image of a {@link TreeItem} , i.e.
+ * {@link TreeItem#getImage()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemImageQuery extends RunnableWithResult.Impl<Image> {
+
+ private final TreeItem treeItem;
+
+ /**
+ * Construct a {@link TreeItemImageQuery} to get the {@link TreeItem}'s
+ * image.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to check expansion
+ */
+ public TreeItemImageQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getImage()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ Image image = treeItem.getImage();
+ setResult(image);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteAttachmentRecordingCommand.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteAttachmentRecordingCommand.java
new file mode 100644
index 0000000000..564ac1ba86
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteAttachmentRecordingCommand.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.command;
+
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.sirius.diagram.ui.tools.api.util.GMFNotationHelper;
+
+/**
+ * A Recording Command to call GMFNotationHelper.createNoteAttachment.
+ *
+ * @author smonnier
+ */
+public class CreateNoteAttachmentRecordingCommand extends RecordingCommand {
+
+ private final Node note;
+
+ private final Node gmfNode;
+
+ /**
+ * Constructor.
+ *
+ * @param domain
+ * my domain
+ * @param note
+ * a list of nodes corresponding to notes.
+ * @param gmfNode
+ * the node which has as element the diagram element given as
+ * parameter or null if any
+ */
+ public CreateNoteAttachmentRecordingCommand(TransactionalEditingDomain domain, Node note, Node gmfNode) {
+ super(domain);
+ this.note = note;
+ this.gmfNode = gmfNode;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doExecute() {
+ GMFNotationHelper.createNoteAttachment(note, gmfNode);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteRecordingCommand.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteRecordingCommand.java
new file mode 100644
index 0000000000..76e8797d80
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/command/CreateNoteRecordingCommand.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.command;
+
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.sirius.diagram.ui.tools.api.util.GMFNotationHelper;
+
+/**
+ * A Recording Command to call GMFNotationHelper.createNote.
+ *
+ * @author smonnier
+ */
+public class CreateNoteRecordingCommand extends RecordingCommand {
+
+ private final Diagram gmfDiagram;
+
+ private final String noteText;
+
+ /**
+ * Constructor.
+ *
+ * @param domain
+ * my domain
+ * @param gmfDiagram
+ * the view which has as element the diagram element given as
+ * parameter or null if any
+ * @param noteText
+ * the note text
+ */
+ public CreateNoteRecordingCommand(TransactionalEditingDomain domain, Diagram gmfDiagram, String noteText) {
+ super(domain);
+ this.gmfDiagram = gmfDiagram;
+ this.noteText = noteText;
+ }
+
+ @Override
+ protected void doExecute() {
+ GMFNotationHelper.createNote(gmfDiagram, noteText);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/SiriusTestsSupportPlugin.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/SiriusTestsSupportPlugin.java
new file mode 100644
index 0000000000..f5f8e617d0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/SiriusTestsSupportPlugin.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.internal;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle.
+ *
+ * @author mchauvin
+ */
+public class SiriusTestsSupportPlugin extends Plugin {
+
+ /** The plug-in ID. */
+ public static final String PLUGIN_ID = "org.eclipse.sirius.tests.support";
+
+ /** The shared instance */
+ private static SiriusTestsSupportPlugin plugin;
+
+ @Override
+ public void start(final BundleContext context) throws Exception {
+ super.start(context);
+ SiriusTestsSupportPlugin.plugin = this;
+ }
+
+ @Override
+ public void stop(final BundleContext context) throws Exception {
+ SiriusTestsSupportPlugin.plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ *
+ * @return the shared instance
+ */
+ public static SiriusTestsSupportPlugin getDefault() {
+ return SiriusTestsSupportPlugin.plugin;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/EclipseTestsSupportHelperImpl.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/EclipseTestsSupportHelperImpl.java
new file mode 100644
index 0000000000..208ed5adbe
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/EclipseTestsSupportHelperImpl.java
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.internal.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.channels.FileChannel;
+
+import org.eclipse.core.filebuffers.manipulation.ContainerCreator;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.common.tools.api.resource.FileProvider;
+import org.eclipse.sirius.tests.support.api.EclipseTestsSupportHelper;
+import org.eclipse.sirius.ui.tools.api.project.ModelingProjectManager;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+
+/**
+ * Eclipse specific operations helper.
+ *
+ * @author mchauvin
+ */
+public final class EclipseTestsSupportHelperImpl implements EclipseTestsSupportHelper {
+ /**
+ * Singleton instance of the eclipse tests support.
+ */
+ public static final EclipseTestsSupportHelper INSTANCE = new EclipseTestsSupportHelperImpl();
+
+ /**
+ * Avoid instantiation.
+ */
+ private EclipseTestsSupportHelperImpl() {
+ // Nothing
+ }
+
+ @Override
+ public Resource createResourceInProject(final ResourceSet set, final String projectName, final String fileName) {
+ return set.createResource(URI.createPlatformResourceURI("/" + projectName + "/" + fileName, true));
+ }
+
+ @Override
+ public IProject createModelingProject(String projectName, boolean createAndOpenBlankRepresentationsFile) {
+ try {
+ return ModelingProjectManager.INSTANCE.createNewModelingProject(projectName, null, createAndOpenBlankRepresentationsFile, new NullProgressMonitor());
+ } catch (CoreException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public IProject createProject(final String projectName) {
+ final IProjectDescription projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
+ final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ try {
+ if (!project.exists()) {
+ project.create(projectDescription, new NullProgressMonitor());
+ }
+ project.open(new NullProgressMonitor());
+ } catch (final CoreException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ return project;
+ }
+
+ @Override
+ public void deleteProject(final String projectName) {
+ final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
+ @Override
+ protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+ if (project.exists()) {
+ project.delete(true, new NullProgressMonitor());
+ }
+ }
+ };
+ try {
+ operation.run(new NullProgressMonitor());
+ } catch (InvocationTargetException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void deleteFile(String workspaceRelativePath) {
+ final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(workspaceRelativePath));
+ WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
+ @Override
+ protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
+ if (file.exists()) {
+ file.delete(true, new NullProgressMonitor());
+ }
+ }
+ };
+ try {
+ operation.run(new NullProgressMonitor());
+ } catch (InvocationTargetException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void copyFile(String relativePath, String destinationWorkspaceRelativePath) {
+
+ if (relativePath == null) {
+ throw new IllegalArgumentException("relativePath cannot be null");
+ }
+ if (destinationWorkspaceRelativePath == null) {
+ throw new IllegalArgumentException("destination WorkspaceRelativePath cannot be null");
+ }
+
+ final File sourceFile = FileProvider.getDefault().getFile(new Path(relativePath));
+ final IFile destinationFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(destinationWorkspaceRelativePath));
+
+ if (sourceFile == null) {
+ throw new IllegalArgumentException("sourceFile cannot be null: check the source path: " + relativePath);
+ }
+ if (destinationFile == null) {
+ throw new IllegalArgumentException("destinationFile cannot be null: check the workspace relative destination path: " + destinationWorkspaceRelativePath);
+ }
+
+ copyFile(sourceFile, destinationFile, true);
+ }
+
+ @Override
+ public void copyFile(final String bundleID, final String projectRelativePath, final String destinationWorkspaceRelativePath, final boolean refreshAfterCopy) {
+ if (bundleID == null) {
+ throw new IllegalArgumentException("bundleID cannot be null");
+ }
+ if (projectRelativePath == null) {
+ throw new IllegalArgumentException("projectRelativePath cannot be null");
+ }
+ if (destinationWorkspaceRelativePath == null) {
+ throw new IllegalArgumentException("destinationWorkspaceRelativePath cannot be null");
+ }
+
+ final File sourceFile = FileProvider.getDefault().getFile(bundleID, new Path(projectRelativePath));
+ final IFile destinationFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(destinationWorkspaceRelativePath));
+
+ if (sourceFile == null) {
+ throw new IllegalArgumentException("sourceFile cannot be null: check the project relative source path: " + projectRelativePath + " in " + bundleID);
+ }
+ if (destinationFile == null) {
+ throw new IllegalArgumentException("destinationFile cannot be null: check the workspace relative destination path: " + destinationWorkspaceRelativePath);
+ }
+
+ copyFile(sourceFile, destinationFile, refreshAfterCopy);
+ }
+
+ @Override
+ public void copyFile(final String bundleID, final String projectRelativePath, final String destinationWorkspaceRelativePath) {
+ copyFile(bundleID, projectRelativePath, destinationWorkspaceRelativePath, true);
+ }
+
+ private void copyFile(final File sourceFile, final IFile destinationFile, final boolean refreshAfterCopy) {
+
+ final StringBuffer errorMessage = new StringBuffer();
+ try {
+ new ContainerCreator(ResourcesPlugin.getWorkspace(), destinationFile.getParent().getFullPath()).createContainer(new NullProgressMonitor());
+
+ copyFile(sourceFile, new File(destinationFile.getLocation().toOSString()));
+
+ if (refreshAfterCopy) {
+ // Refresh the new created file
+ destinationFile.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
+ }
+ } catch (final CoreException e) {
+ errorMessage.append(e.getMessage());
+ } catch (final IOException e) {
+ errorMessage.append(e.getMessage());
+ }
+ if (!destinationFile.exists() && refreshAfterCopy) {
+ throw new RuntimeException("Problem during the copy of the file : " + errorMessage);
+ }
+ }
+
+ @Override
+ public void copyFile(final File sourceFile, final File destFile) throws IOException {
+ if (sourceFile == null) {
+ throw new IllegalArgumentException("sourceFile cannot be null");
+ }
+ if (destFile == null) {
+ throw new IllegalArgumentException("destFile cannot be null");
+ }
+ if (!sourceFile.exists()) {
+ throw new IllegalArgumentException("File '" + sourceFile + "' to copy does not exists");
+ }
+ if (!destFile.exists()) {
+ destFile.createNewFile();
+ }
+
+ FileChannel source = null;
+ FileChannel destination = null;
+ try {
+ source = new FileInputStream(sourceFile).getChannel();
+ destination = new FileOutputStream(destFile).getChannel();
+ destination.transferFrom(source, 0, source.size());
+ } finally {
+ if (source != null) {
+ source.close();
+ }
+ if (destination != null) {
+ destination.close();
+ }
+ }
+ }
+
+ @Override
+ public void changeFileReadOnlyAttribute(final String destinationWorkspaceRelativePath, final boolean readOnly) {
+ if (destinationWorkspaceRelativePath == null) {
+ throw new IllegalArgumentException("destinationWorkspaceRelativePath cannot be null");
+ }
+
+ final IFile destinationFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(destinationWorkspaceRelativePath));
+ destinationFile.getLocation().toFile().setReadOnly();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/ModelInitializer.java b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/ModelInitializer.java
new file mode 100644
index 0000000000..552bb23045
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.support/src/org/eclipse/sirius/tests/support/internal/helper/ModelInitializer.java
@@ -0,0 +1,294 @@
+/**
+ * Copyright (c) 2012 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.support.internal.helper;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+//CHECKSTYLE:OFF
+
+/**
+ * Helper to initialize a model from a seed and a collection of EPackage.
+ *
+ * @author pcd, mpo, ala
+ *
+ */
+public class ModelInitializer {
+ private final Scope scope;
+
+ private final Predicate<EClass> isInstanciable = new Predicate<EClass>() {
+ @Override
+ public boolean apply(EClass input) {
+ return !input.isAbstract() && !input.isInterface();
+ }
+ };
+
+ private final Multimap<EReference, EClass> refToCandidatesMap = HashMultimap.create();
+
+ /**
+ * Constructor.
+ *
+ * @param scope
+ */
+ public ModelInitializer(Scope scope) {
+ this.scope = scope;
+ }
+
+ /**
+ *
+ * @param acc
+ * elements to link.
+ */
+ public void linkElements(List<EObject> acc) {
+ for (EObject current : acc) {
+ for (EReference ref : current.eClass().getEAllReferences()) {
+ boolean containmentTouch = ref.isContainment() || ref.isContainer();
+ boolean safeSettable = !ref.isDerived() && !ref.isUnsettable() && ref.getEOpposite() == null;
+ if (!containmentTouch && safeSettable && !current.eIsSet(ref)) {
+ boolean selfValue = false;
+ EObject possibleValue = null;
+ for (EObject potentialValue : acc) {
+ if (ref.getEReferenceType().isSuperTypeOf(potentialValue.eClass())) {
+ if (potentialValue == current) {
+ selfValue = true;
+ } else {
+ possibleValue = potentialValue;
+ break;
+ }
+ }
+ }
+
+ if (possibleValue != null) {
+ current.eSet(ref, ref.isMany() ? Collections.singletonList(possibleValue) : possibleValue);
+ } else if (selfValue) {
+ current.eSet(ref, ref.isMany() ? Collections.singletonList(current) : current);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Fill the model: try to create all possible values for containment
+ * references.
+ *
+ * @param root
+ * the seed.
+ * @return the created objects.
+ */
+ public List<EObject> initializeContents(EObject root) {
+ Preconditions.checkNotNull(root);
+ refToCandidatesMap.clear();
+ List<EObject> created = Lists.newArrayList();
+ initializeContents(root, created);
+ return created;
+ }
+
+ private void initializeContents(EObject element, List<EObject> acc) {
+ for (EReference ref : element.eClass().getEAllReferences()) {
+ if (ref.isContainment() && needsInitialization(element, ref)) {
+ initializeContents(element, ref, acc);
+ }
+ }
+ }
+
+ private void initializeContents(EObject root, EReference ref, List<EObject> acc) {
+
+ Set<EClass> candidates = findCompatibleCandidates(root, ref);
+ Set<EClass> instanciableCandidates = Sets.newLinkedHashSet(Iterables.filter(candidates, isInstanciable));
+
+ final Collection<EClass> refToCandidates = refToCandidatesMap.get(ref);
+
+ Predicate<EClass> newCreationType = new Predicate<EClass>() {
+ @Override
+ public boolean apply(EClass input) {
+ return !refToCandidates.contains(input);
+ };
+ };
+
+ Set<EClass> neverCreatedCandidates = Sets.newLinkedHashSet(Iterables.filter(instanciableCandidates, newCreationType));
+ initializeContents(root, ref, neverCreatedCandidates, acc);
+ }
+
+ private void initializeContents(EObject element, EReference ref, Set<EClass> instanciableCandidates, List<EObject> acc) {
+ // Step 1: create an instance of the given types
+ List<EObject> instances = Lists.newArrayListWithCapacity(instanciableCandidates.size());
+ for (EClass klass : instanciableCandidates) {
+ EObject instance = klass.getEPackage().getEFactoryInstance().create(klass);
+ instances.add(instance);
+ }
+
+ if (instances.isEmpty()) {
+ return;
+ }
+
+ // Step 2: fill reference with all created instances
+ if (ref.isMany()) {
+ acc.addAll(instances);
+ refToCandidatesMap.putAll(ref, instanciableCandidates);
+ element.eSet(ref, instances);
+ } else {
+ EObject instance = instances.iterator().next();
+ if (instances.size() != 1) {
+ // If there is ambiguity, let the subclasses choose.
+ instance = multiCandidateSingleRef(element, ref, instances);
+ }
+
+ if (instance != null) {
+ refToCandidatesMap.put(ref, instance.eClass());
+ element.eSet(ref, instance);
+ acc.add(instance);
+
+ instances = Collections.singletonList(instance);
+ } else {
+ // No child added to the model
+ instances.clear();
+ }
+ }
+
+ for (EObject instance : instances) {
+ // Step 3: perform additional operations after element creation
+ customizeCreatedElement(instance);
+
+ // Step 4: fill the created element
+ initializeContents(instance, acc);
+ }
+ }
+
+ /**
+ * Indicates whether the given reference of the given element should be
+ * initialized (default behavior: containment, required and not set).
+ * Subclasses should override this method
+ *
+ * @param element
+ * the element to fill
+ * @param containmentRef
+ * a containment reference reference to set (or not)
+ * @return true if the given reference of the given element should be
+ * initialized, false otherwise
+ */
+ protected boolean needsInitialization(EObject element, EReference containmentRef) {
+ return containmentRef.isContainment() && containmentRef.isRequired() && !element.eIsSet(containmentRef);
+ }
+
+ /**
+ * There are several candidates for a single valued reference. Subclasses
+ * should handle the ambiguity. The defaut behavior is to return null to
+ * stop.
+ *
+ * @param element
+ * the current element.
+ * @param ref
+ * the single valued ref to set.
+ * @param instanciableCandidates
+ * the computed compatible candidates.
+ * @return null to stop or one of the candidates.
+ */
+ protected EObject multiCandidateSingleRef(EObject element, EReference ref, Collection<EObject> instances) {
+ // Resolve the ambiguity by adding the first found element
+ // Sub classes can do something else
+ return null;
+ }
+
+ /**
+ * This method is called right after each element creation. Subclasses can
+ * override this method to set specific features to the created element.
+ *
+ * @param createdElement
+ * the element that has just been created
+ */
+ protected void customizeCreatedElement(EObject createdElement) {
+ // Default behavior is to do nothing
+ }
+
+ /**
+ * Finds legitimate candidates for the given element's reference. Subclasses
+ * can extend this method to customize how can candidates be retrieved.
+ *
+ * @param container
+ * the container element to fill
+ * @param containmentReference
+ * the reference to set
+ * @return all legitimate candidates (i.e. EClasses having a type
+ * compatabible with the given reference's type)
+ */
+ protected Set<EClass> findCompatibleCandidates(EObject container, EReference containmentReference) {
+ Set<EClass> candidates = Sets.newLinkedHashSet();
+ for (EPackage pkg : scope.getScope()) {
+ candidates.addAll(findCompatibleCandidates(container, containmentReference, pkg));
+ }
+ candidates.removeAll(scope.getEclassesToAvoid());
+ return candidates;
+ }
+
+ /**
+ * Finds legitimate candidates for the given element's reference in the
+ * scope of the given {@link EPackage}.
+ *
+ * @param container
+ * the container element to fill
+ * @param reference
+ * the reference to set
+ * @param currentScope
+ * the {@link EPackage} in which candidates will be browsed
+ * @return all legitimate candidates (i.e. EClasses having a type
+ * compatabible with the given reference's type)
+ */
+ protected Collection<? extends EClass> findCompatibleCandidates(EObject container, EReference reference, EPackage currentScope) {
+ EClass type = reference.getEReferenceType();
+ Set<EClass> result = Sets.newLinkedHashSet();
+ for (EClass klass : Iterables.filter(currentScope.getEClassifiers(), EClass.class)) {
+ boolean isCompatible = klass.equals(type) || klass.getEAllSuperTypes().contains(type);
+ if (isCompatible) {
+ result.add(klass);
+ }
+ }
+ return result;
+ }
+
+ public static class Scope {
+ private final Set<EPackage> scope = Sets.newLinkedHashSet();
+
+ private final Set<EClass> eclassesToAvoid = Sets.newHashSet();
+
+ public Scope(Collection<? extends EPackage> packages, Collection<EClass> doNotIns) {
+ this.scope.addAll(Preconditions.checkNotNull(packages));
+ this.eclassesToAvoid.addAll(Preconditions.checkNotNull(doNotIns));
+ }
+
+ public Scope(Collection<? extends EPackage> packages) {
+ this.scope.addAll(Preconditions.checkNotNull(packages));
+ }
+
+ public Set<EClass> getEclassesToAvoid() {
+ return eclassesToAvoid;
+ }
+
+ public Set<EPackage> getScope() {
+ return scope;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/.checkstyle b/plugins/org.eclipse.sirius.tests.swtbot.support/.checkstyle
new file mode 100644
index 0000000000..de41933953
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/.checkstyle
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+ <local-check-config name="Sirius Checks" location="/org.eclipse.sirius.settings/CheckstyleConfiguration.xml" type="project" description="">
+ <additional-data name="protect-config-file" value="false"/>
+ </local-check-config>
+ <fileset name="all" enabled="true" check-config-name="Sirius Checks" local="true">
+ <file-match-pattern match-pattern="." include-pattern="true"/>
+ </fileset>
+ <filter name="FilesFromPackage" enabled="true">
+ <filter-data value="src-gen"/>
+ </filter>
+</fileset-config>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/.classpath b/plugins/org.eclipse.sirius.tests.swtbot.support/.classpath
new file mode 100644
index 0000000000..39819a3af8
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/sirius/**"/>
+ <accessrule kind="nonaccessible" pattern="junit/framework/Assert"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/.project b/plugins/org.eclipse.sirius.tests.swtbot.support/.project
new file mode 100644
index 0000000000..34dee4c9ce
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.sirius.tests.swtbot.support</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.sirius.tests.swtbot.support/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..c47f91c28e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,24 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tests.swtbot.support/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..b352f2318d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/META-INF/MANIFEST.MF
@@ -0,0 +1,69 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.sirius.tests.swtbot.support;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.sirius.tests.swtbot.support.internal.DesignerSWTBotTestsSupportPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.ui;visibility:=reexport,
+ org.junit;bundle-version="[4.0.0,5.0.0)",
+ org.eclipse.swtbot.junit4_x;visibility:=reexport,
+ org.eclipse.swtbot.eclipse.finder;visibility:=reexport,
+ org.eclipse.swtbot.swt.finder;visibility:=reexport,
+ org.eclipse.swtbot.eclipse.gef.finder;bundle-version="2.0.5",
+ org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
+ org.hamcrest.library;bundle-version="[1.1.0,2.0.0)",
+ org.apache.log4j;bundle-version="1.2.13",
+ org.eclipse.draw2d;bundle-version="3.4.2",
+ org.eclipse.gef;bundle-version="3.4.1",
+ org.eclipse.core.resources,
+ org.eclipse.ui.navigator.resources,
+ org.eclipse.sirius,
+ org.eclipse.sirius.ui,
+ org.eclipse.sirius.tree.ui,
+ org.eclipse.sirius.table.ui,
+ com.google.guava;bundle-version="[11.0.2,16.0)",
+ org.eclipse.gmf.runtime.draw2d.ui;bundle-version="1.2.1",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.0",
+ org.eclipse.gmf.runtime.diagram.ui,
+ org.eclipse.sirius.common.ui,
+ org.eclipse.sirius.diagram,
+ org.eclipse.emf.common.ui;bundle-version="2.5.0",
+ org.eclipse.ui.ide,
+ org.eclipse.sirius.tests.support;bundle-version="1.0.0",
+ org.eclipse.sirius.common,
+ org.eclipse.sirius.ecore.extender,
+ org.eclipse.ui.views.log,
+ org.eclipse.sirius.diagram.ui
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Export-Package: org.eclipse.sirius.tests.swtbot.support.api;uses:="org.eclipse.sirius.tests.swtbot.support.api.business,org.eclipse.sirius.tests.swtbot.support.api.perspective,org.eclipse.swtbot.eclipse.gef.finder",
+ org.eclipse.sirius.tests.swtbot.support.api.bot,
+ org.eclipse.sirius.tests.swtbot.support.api.bot.description,
+ org.eclipse.sirius.tests.swtbot.support.api.business;
+ uses:="org.eclipse.emf.ecore.resource,
+ org.eclipse.emf.common.util,
+ org.eclipse.swtbot.swt.finder.widgets,
+ org.eclipse.swtbot.eclipse.finder",
+ org.eclipse.sirius.tests.swtbot.support.api.business.sessionbrowser,
+ org.eclipse.sirius.tests.swtbot.support.api.condition,
+ org.eclipse.sirius.tests.swtbot.support.api.dialog,
+ org.eclipse.sirius.tests.swtbot.support.api.editor;uses:="org.eclipse.swtbot.eclipse.gef.finder.widgets,org.eclipse.ui,org.eclipse.swtbot.eclipse.finder",
+ org.eclipse.sirius.tests.swtbot.support.api.matcher,
+ org.eclipse.sirius.tests.swtbot.support.api.matcher.geometry,
+ org.eclipse.sirius.tests.swtbot.support.api.perspective;uses:="org.eclipse.swtbot.eclipse.finder",
+ org.eclipse.sirius.tests.swtbot.support.api.test,
+ org.eclipse.sirius.tests.swtbot.support.api.view,
+ org.eclipse.sirius.tests.swtbot.support.api.widget,
+ org.eclipse.sirius.tests.swtbot.support.internal;x-internal:=true,
+ org.eclipse.sirius.tests.swtbot.support.internal.business;x-internal:=true,
+ org.eclipse.sirius.tests.swtbot.support.utils;uses:="org.eclipse.swtbot.swt.finder.widgets,org.eclipse.swt.widgets",
+ org.eclipse.sirius.tests.swtbot.support.utils.business,
+ org.eclipse.sirius.tests.swtbot.support.utils.dnd,
+ org.eclipse.sirius.tests.swtbot.support.utils.menu,
+ org.eclipse.sirius.tests.swtbot.support.utils.tree
+Bundle-Vendor: %providerName
+Import-Package: org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n,
+ org.eclipse.sirius.ext.base;version="1.0.0",
+ org.eclipse.sirius.ext.draw2d.figure;version="1.0.0",
+ org.eclipse.sirius.ext.gmf.runtime.editparts;version="1.0.0"
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/build.properties b/plugins/org.eclipse.sirius.tests.swtbot.support/build.properties
new file mode 100644
index 0000000000..b03f019105
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/build.properties
@@ -0,0 +1,15 @@
+# ====================================================================
+# Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms 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
+# ====================================================================
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/plugin.properties b/plugins/org.eclipse.sirius.tests.swtbot.support/plugin.properties
new file mode 100644
index 0000000000..afcfff70c2
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/plugin.properties
@@ -0,0 +1,12 @@
+# ====================================================================
+# Copyright (c) 2007, 2014 THALES GLOBAL SERVICES
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms 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 = Sirius SWTBot Tests Support (Incubation)
+providerName = Eclipse.org
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/pom.xml b/plugins/org.eclipse.sirius.tests.swtbot.support/pom.xml
new file mode 100644
index 0000000000..5063b08f39
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2007, 2013 THALES GLOBAL SERVICES
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.sirius</groupId>
+ <artifactId>sirius-parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../../packaging/org.eclipse.sirius.parent</relativePath>
+ </parent>
+
+ <artifactId>org.eclipse.sirius.tests.swtbot.support</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+</project>
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java
new file mode 100644
index 0000000000..5c236e425f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/AbstractSiriusSwtBotGefTestCase.java
@@ -0,0 +1,1555 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderedShapeEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DescriptionCompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.TextEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.sirius.business.api.dialect.DialectManager;
+import org.eclipse.sirius.business.api.preferences.SiriusPreferencesKeys;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.common.tools.internal.resource.ResourceSyncClientNotifier;
+import org.eclipse.sirius.diagram.part.SiriusDiagramEditorPlugin;
+import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramPreferencesKeys;
+import org.eclipse.sirius.diagram.ui.business.internal.dialect.DiagramDialectUIServices;
+import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramEdgeEditPart;
+import org.eclipse.sirius.diagram.ui.tools.internal.actions.style.ResetStylePropertiesToDefaultValuesAction;
+import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper;
+import org.eclipse.sirius.tests.support.api.EclipseTestsSupportHelper;
+import org.eclipse.sirius.tests.support.api.TestCaseCleaner;
+import org.eclipse.sirius.tests.support.api.TestsUtil;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation.ZoomLevel;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UILocalSession;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIPerspective;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIProject;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.OperationRedoneCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.OperationUndoneCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerHelper;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotVSMEditor;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotVSMHelper;
+import org.eclipse.sirius.tests.swtbot.support.api.perspective.DesignerPerspectives;
+import org.eclipse.sirius.tests.swtbot.support.api.view.DesignerViews;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotCommonHelper;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
+import org.eclipse.sirius.viewpoint.DRepresentation;
+import org.eclipse.sirius.viewpoint.SiriusPlugin;
+import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
+import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.eclipse.gef.finder.SWTBotGefTestCase;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.ClassUtils;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.ErrorEditorPart;
+import org.hamcrest.Matcher;
+import org.junit.Assert;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Wrapper for several UI* classes to handle ui management in tests. If needed,
+ * new setup operations can be done in
+ * {@link #onSetUpBeforeClosingWelcomePage()} overridden method.
+ *
+ * {@link #onSetUpAfterOpeningDesignerPerspective()} allows developer to add
+ * extra behavior after opening designer perspective.
+ *
+ * @author dlecan
+ */
+@SuppressWarnings("restriction")
+public abstract class AbstractSiriusSwtBotGefTestCase extends SWTBotGefTestCase {
+
+ static {
+ SWTBotPreferences.TIMEOUT = 10000;
+ }
+
+ /**
+ * Models dir.
+ */
+ protected static final String MODELS_DIR = "Models";
+
+ /** Test project name. */
+ protected static final String TEMP_PROJECT_NAME = "DesignerTestProject";
+
+ private static final String EN_US = "EN_US";
+
+ private static final String SET_STYLE_TO_WORKSPACE_IMAGE = "Set style to workspace image";
+
+ private static final String POINT = ".";
+
+ private static final String EDIT_MENU_NAME = "Edit";
+
+ private static boolean fFullScreen = true;
+
+ /**
+ * Designer perspective.
+ */
+ protected UIPerspective designerPerspective = new UIPerspective(bot);
+
+ /**
+ * Designer perspective.
+ */
+ protected DesignerPerspectives designerPerspectives = new DesignerPerspectives(bot);
+
+ /** . */
+ protected DesignerViews designerViews = new DesignerViews(bot);
+
+ /**
+ * Designer project.
+ */
+ protected UIProject designerProject;
+
+ /**
+ * The Session Resource wrapper.
+ */
+ protected UIResource sessionAirdResource;
+
+ /**
+ * The Session Tree item wrapper.
+ */
+ protected UILocalSession localSession;
+
+ /**
+ * The DialectEditor (opened on representation creation) wrapper.
+ */
+ protected SWTBotDesignerEditor editor;
+
+ /**
+ * The reported errors.
+ */
+ protected LinkedHashMultimap<String, IStatus> errors;
+
+ private boolean defaultEnableAnimatedZoom;
+
+ private boolean defaultEnableAnimatedLayout;
+
+ private final HashMap<String, Object> oldValuePreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldValueSiriusPreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldValueSiriusUIPreferences = new HashMap<String, Object>();
+
+ private final HashMap<String, Object> oldPlatformUIPreferences = new HashMap<String, Object>();
+
+ /**
+ * The unchaught exceptions handler.
+ */
+ private UncaughtExceptionHandler exceptionHandler;
+
+ /**
+ * The platform error listener.
+ */
+ private ILogListener logListener;
+
+ private boolean errorCatchActive;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ PlatformUI.getWorkbench().getWorkbenchWindows()[0].getShell().setFullScreen(AbstractSiriusSwtBotGefTestCase.fFullScreen);
+ }
+ });
+
+ /* Init error log and uncauht exception handlers */
+ errors = LinkedHashMultimap.create();
+ initErrorLoggers();
+
+ System.out.println("Setup of " + this.getClass().getName() + AbstractSiriusSwtBotGefTestCase.POINT + getName() + "()");
+ try {
+ super.setUp();
+
+ // Disable the animated zoom and the animated arrange to save time
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ IPreferenceStore preferenceStore = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ defaultEnableAnimatedZoom = preferenceStore.getBoolean(IPreferenceConstants.PREF_ENABLE_ANIMATED_ZOOM);
+ preferenceStore.setValue(IPreferenceConstants.PREF_ENABLE_ANIMATED_ZOOM, false);
+ defaultEnableAnimatedLayout = preferenceStore.getBoolean(IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT);
+ preferenceStore.setValue(IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT, false);
+
+ // Set the auto-refresh to false because it's historically
+ // the
+ // default value
+ DefaultScope.INSTANCE.getNode(SiriusPlugin.ID).putBoolean(SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), true);
+ InstanceScope.INSTANCE.getNode(SiriusPlugin.ID).putBoolean(SiriusPreferencesKeys.PREF_AUTO_REFRESH.name(), getAutoRefreshMode());
+ }
+ });
+
+ // If you need another name, override getProjectName()
+ designerProject = designerPerspective.createProject(getProjectName());
+
+ onSetUpBeforeClosingWelcomePage();
+
+ closeWelcomePage();
+
+ // Set up a no ui callback for auto migration
+ // SiriusEditPlugin.getPlugin().setUiCallback(new
+ // UiCallBackWithoutMigrationNotification(SiriusEditPlugin.getPlugin().getUiCallback()));
+
+ // Open Design perspective
+ designerPerspectives.openModelingPerspective();
+
+ onSetUpAfterOpeningDesignerPerspective();
+ // CHECKSTYLE:OFF
+ } catch (Throwable e) {
+ takeScreenshot("-after-setup");
+ // Call the tear down to clean the environment (not done by JUnit if
+ // setup failed)
+ try {
+ failureTearDown();
+ } catch (Exception secondException) {
+ // CHECKSTYLE:ON
+ // Ignore this secondException, because the first is the more
+ // important
+ }
+ if (e instanceof Exception) {
+ throw (Exception) e;
+ } else {
+ throw new RuntimeException(e);
+ }
+ }
+
+ }
+
+ /**
+ * Define the auto refresh mode to use during this tests.
+ *
+ * @return the auto refresh mode.
+ */
+ protected boolean getAutoRefreshMode() {
+ return false;
+ }
+
+ /**
+ * Get the project name to create.
+ *
+ * @return Project name.
+ */
+ protected String getProjectName() {
+ return AbstractSiriusSwtBotGefTestCase.TEMP_PROJECT_NAME;
+ }
+
+ /**
+ * Do something before closing welcome page during setup.
+ *
+ * @throws Exception
+ * Error.
+ */
+ protected void onSetUpBeforeClosingWelcomePage() throws Exception {
+ // Default, nothing
+ }
+
+ /**
+ * Do something after opening designer perspective, just before executing
+ * test.
+ *
+ * @throws Exception
+ * Error.
+ */
+ protected void onSetUpAfterOpeningDesignerPerspective() throws Exception {
+ // Default, nothing
+ }
+
+ /**
+ * Close all opened editors without saving. A waitAllUiEvents is called to
+ * wait the closing of editors that is run by Eclipse in asyncExec.
+ */
+ protected void closeAllEditors() {
+ bot.getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < PlatformUI.getWorkbench().getWorkbenchWindows().length; i++) {
+ for (int j = 0; j < PlatformUI.getWorkbench().getWorkbenchWindows()[i].getPages().length; j++) {
+ PlatformUI.getWorkbench().getWorkbenchWindows()[i].getPages()[j].closeAllEditors(false);
+ }
+ }
+ }
+ });
+ // wait ui events according to editor
+ SWTBotUtils.waitAllUiEvents();
+ }
+
+ private void closeAllSessions() {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ for (final Session sess : Sets.newLinkedHashSet(SessionManager.INSTANCE.getSessions())) {
+ if (sess.isOpen()) {
+ sess.save(new NullProgressMonitor());
+ try {
+ Job.getJobManager().join(ResourceSyncClientNotifier.FAMILY, new NullProgressMonitor());
+ } catch (OperationCanceledException e) {
+ TestCase.fail(e.getLocalizedMessage());
+ } catch (InterruptedException e) {
+ TestCase.fail(e.getLocalizedMessage());
+ }
+ sess.close(new NullProgressMonitor());
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Close the Welcome Page.
+ */
+ protected void closeWelcomePage() {
+ Matcher<IWorkbenchPartReference> matcher = WidgetMatcherFactory.withPartName("Welcome");
+ List<SWTBotView> views = bot.views(matcher);
+ for (SWTBotView swtBotView : views) {
+ swtBotView.close();
+ }
+ }
+
+ /**
+ * Request an explicit refresh of the current diagram.
+ */
+ protected void manualRefresh() {
+ // TODO delete the specific case of Eclipse 4.x platform once tabbar
+ // issues will be fixed
+ if (!TestsUtil.isEclipse4xPlatform()) {
+ bot.toolbarButtonWithTooltip(DiagramDialectUIServices.REFRESH_DIAGRAM).click();
+ } else {
+ // Use context menu instead of tabbar
+ new SWTBotDesignerEditor(bot.activeEditor().getReference(), bot).clickContextMenu("Refresh");
+ }
+ SWTBotUtils.waitProgressMonitorClose("Progress Information");
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * runtTest() method is overridden to allow to take a screenshot just after
+ * test execution and before tearDown operation. As tearDown closes diagram
+ * and session, after it, screenshots don't show any interesting things.
+ */
+ @Override
+ // CHECKSTYLE:OFF
+ // Need Throwable type by contract
+ protected void runTest() throws Throwable {
+ try {
+ super.runTest();
+ } catch (Throwable running) {
+ // CHECKSTYLE:ON
+ takeScreenshot("-before-tearDown");
+ throw running;
+ }
+ }
+
+ /**
+ * Helper used by {@link #runTest()}.
+ *
+ * @param suffix
+ * The suffix of the screenshot to create
+ * @see #runTest()
+ */
+ public void takeScreenshot(CharSequence suffix) {
+ String fileName = "screenshots/screenshot-" + ClassUtils.simpleClassName(getClass()) + AbstractSiriusSwtBotGefTestCase.POINT + getName() + suffix + AbstractSiriusSwtBotGefTestCase.POINT
+ + SWTBotPreferences.SCREENSHOT_FORMAT.toLowerCase();
+ new File("screenshots").mkdirs(); //$NON-NLS-1$
+ SWTUtils.captureScreenshot(fileName);
+ }
+
+ /**
+ * Open error log.
+ *
+ * @deprecated Use {@link #openErrorLogViewByAPI()} instead. This method is
+ * faster.
+ */
+ @Deprecated
+ protected void openErrorLogView() {
+ bot.menu("Window").menu("Show View").menu("Other...").click();
+ bot.waitUntil(Conditions.shellIsActive("Show View"));
+ bot.text().setText("err");
+ bot.tree().expandNode("General").select("Error Log");
+ bot.button("OK").click();
+ }
+
+ /**
+ * Open error log.
+ */
+ protected void openErrorLogViewByAPI() {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("org.eclipse.pde.runtime.LogView");
+ } catch (PartInitException e) {
+ TestCase.fail("Unable to open errorLog view : " + e.getMessage());
+ }
+ }
+ });
+ }
+
+ /**
+ * Get the number of Status in the error log at the time of the call.
+ *
+ * @return the number of Status in the error log at the time of the call
+ */
+ public int getNbStatusInErrorLog() {
+ openErrorLogViewByAPI();
+
+ SWTBotView logViewBot = bot.viewByTitle("Error Log");
+ logViewBot.show();
+ SWTBotTree tree = logViewBot.bot().tree();
+ int nbStatus = tree.getAllItems().length;
+ logViewBot.close();
+
+ return nbStatus;
+ }
+
+ /**
+ * Assert the editor is not an error one, close it before failing if it is
+ * to avoid breaking further tests.
+ *
+ * @param message
+ * : message on failure.
+ * @param activeEditor
+ * the editor to check.
+ */
+ protected void assertEditorIsNotError(String message, SWTBotEditor activeEditor) {
+ IEditorPart editorPart = activeEditor.getReference().getEditor(false);
+ boolean isError = editorPart instanceof ErrorEditorPart;
+ if (isError) {
+ activeEditor.close();
+ }
+ TestCase.assertFalse(message, isError);
+ }
+
+ /**
+ * Undo with shortcut CTRL+z, at the end of this method execution, the
+ * operation undo is finished.
+ */
+ protected void undo() {
+ Assert.assertTrue(editor != null);
+ ICondition condition = new OperationUndoneCondition();
+ bot.activeEditor();
+
+ String savedKeyboardLayout = SWTBotPreferences.KEYBOARD_LAYOUT;
+ SWTBotPreferences.KEYBOARD_LAYOUT = AbstractSiriusSwtBotGefTestCase.EN_US;
+ editor.getCanvas().pressShortcut(SWT.CTRL, 'z');
+ SWTBotPreferences.KEYBOARD_LAYOUT = savedKeyboardLayout;
+
+ bot.waitUntil(condition);
+ }
+
+ /**
+ * Undo using the command stack of the editing domain of the current
+ * session.
+ *
+ * @param session
+ * current session to undo last action.
+ */
+ protected void undo(Session session) {
+ session.getTransactionalEditingDomain().getCommandStack().undo();
+ }
+
+ /**
+ * Undo the command named cmdName with the menu Edit.
+ *
+ * @param cmdName
+ * the command to undo
+ */
+ protected void undo(String cmdName) {
+ bot.menu(AbstractSiriusSwtBotGefTestCase.EDIT_MENU_NAME).menu("Undo " + cmdName).click();
+ }
+
+ /**
+ * Redo with shortcut CTRL+y, at the end of this method execution, the
+ * operation redo is finished.
+ */
+ protected void redo() {
+ Assert.assertTrue(editor != null);
+ ICondition condition = new OperationRedoneCondition();
+ bot.activeEditor();
+
+ String savedKeyboardLayout = SWTBotPreferences.KEYBOARD_LAYOUT;
+ SWTBotPreferences.KEYBOARD_LAYOUT = AbstractSiriusSwtBotGefTestCase.EN_US;
+ if (System.getProperty("os.name").equals("Linux") && (TestsUtil.isJuno3Platform() || TestsUtil.isEclipse4xPlatform())) {
+ editor.getCanvas().pressShortcut(SWT.SHIFT | SWT.CTRL, 'z');
+ } else {
+ editor.getCanvas().pressShortcut(SWT.CTRL, 'y');
+ }
+ SWTBotPreferences.KEYBOARD_LAYOUT = savedKeyboardLayout;
+
+ bot.waitUntil(condition);
+ }
+
+ /**
+ * Redo the command named cmdName with the menu Edit.
+ *
+ * @param cmdName
+ * the command to redo
+ */
+ protected void redo(String cmdName) {
+ bot.menu(AbstractSiriusSwtBotGefTestCase.EDIT_MENU_NAME).menu("Redo " + cmdName).click();
+ }
+
+ /**
+ * Redo using the command stack of the editing domain of the current
+ * session.
+ *
+ * @param session
+ * current session to redo last action.
+ */
+ protected void redo(Session session) {
+ session.getTransactionalEditingDomain().getCommandStack().redo();
+ }
+
+ /**
+ * Cancel the custom style.
+ */
+ protected void launchCancelCustomStyle() {
+ bot.buttonWithTooltip("Cancel custom style").click();
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeDiagramPreference(final String preferenceKey, final Boolean newValue) {
+ final IPreferenceStore prefs = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ oldValuePreferences.put(preferenceKey, prefs.getBoolean(preferenceKey));
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ prefs.setValue(preferenceKey, newValue);
+ }
+ });
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeSiriusPreference(String preferenceKey, Boolean newValue) {
+ boolean oldValue = Platform.getPreferencesService().getBoolean(SiriusPlugin.ID, preferenceKey, false, null);
+ oldValueSiriusPreferences.put(preferenceKey, oldValue);
+
+ IEclipsePreferences corePreferences = InstanceScope.INSTANCE.getNode(SiriusPlugin.ID);
+ corePreferences.putBoolean(preferenceKey, newValue);
+
+ String message = "The " + preferenceKey + " preference value was not changed for plugin " + SiriusPlugin.ID;
+ boolean valueToCheck = Platform.getPreferencesService().getBoolean(SiriusPlugin.ID, preferenceKey, false, null);
+ TestCase.assertEquals(message, newValue.booleanValue(), valueToCheck);
+ }
+
+ /**
+ * Change a boolean preference and store the old value. It will be
+ * automatically reset during tear down.
+ *
+ * TO CALL ONLY ONCE PER TEST (set up + test)
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changeSiriusUIPreference(String preferenceKey, Boolean newValue) {
+ Collection<SiriusPreferencesKeys> coreValues = Lists.newArrayList(SiriusPreferencesKeys.values());
+ Function<SiriusPreferencesKeys, String> prefToName = new Function<SiriusPreferencesKeys, String>() {
+ @Override
+ public String apply(SiriusPreferencesKeys input) {
+ return input.name();
+ }
+ };
+ TestCase.assertFalse("The DesignerPreferenceKey named " + preferenceKey + " should not be modified in the UI store.",
+ Lists.newArrayList(Iterables.transform(coreValues, prefToName)).contains(preferenceKey));
+
+ IPreferenceStore viewpointUIPrefs = SiriusEditPlugin.getPlugin().getPreferenceStore();
+ oldValueSiriusUIPreferences.put(preferenceKey, viewpointUIPrefs.getBoolean(preferenceKey));
+ viewpointUIPrefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Change a boolean preference and store the old value to reset it after the
+ * test.
+ *
+ * @param preferenceKey
+ * The key of the preference.
+ * @param newValue
+ * The new value.
+ */
+ protected void changePlatformUIPreference(String preferenceKey, Boolean newValue) {
+ IPreferenceStore viewpointUIPrefs = PlatformUI.getPreferenceStore();
+ oldPlatformUIPreferences.put(preferenceKey, viewpointUIPrefs.getBoolean(preferenceKey));
+ viewpointUIPrefs.setValue(preferenceKey, newValue);
+ }
+
+ /**
+ * Delete the selected element if possible.
+ */
+ protected void deleteSelectedElement() {
+ SWTBotMenu deleteMenu = checkDeleteMenuEnablement(true);
+ deleteMenu.click();
+ }
+
+ /**
+ * Delete the selected element from diagram if possible.
+ */
+ protected void deleteFromDiagram() {
+ String savedKeyboardLayout = SWTBotPreferences.KEYBOARD_LAYOUT;
+ SWTBotPreferences.KEYBOARD_LAYOUT = AbstractSiriusSwtBotGefTestCase.EN_US;
+ editor.getCanvas().pressShortcut(SWT.CTRL | SWT.SHIFT, 'd');
+ SWTBotPreferences.KEYBOARD_LAYOUT = savedKeyboardLayout;
+ SWTBotUtils.waitAllUiEvents();
+
+ // bot.waitUntil(condition);
+ // bot.toolbarButtonWithTooltip(DiagramUIActionsMessages.DeleteFromDiagram_ActionToolTipText).click();
+ }
+
+ /**
+ * Delete the selected element if possible.
+ *
+ * @param expected
+ * expected value of the delete menu.
+ * @return the delete bot menu.
+ */
+ protected SWTBotMenu checkDeleteMenuEnablement(boolean expected) {
+ SWTBotMenu deleteMenu = bot.menu(AbstractSiriusSwtBotGefTestCase.EDIT_MENU_NAME).menu("Delete");
+
+ String errorMessage = expected ? "Delete menu should be enabled" : "Delete menu was not enabled";
+ TestCase.assertEquals(errorMessage, expected, deleteMenu.isEnabled());
+
+ return deleteMenu;
+ }
+
+ /**
+ * Toggle Active view/editor maximize. If possible call directly
+ * {@link #maximizeEditor(SWTBotDesignerEditor)} and
+ * {@link #restoreEditor(SWTBotDesignerEditor)}, they are faster because
+ * they use directly Eclipse API.
+ */
+ protected void maximizeEditor() {
+ bot.menu("Window").menu("Navigation").menu("Maximize Active View or Editor").click();
+ }
+
+ /**
+ * Maximize view/editor maximize using the eclipse API.
+ *
+ * @param swtBotDesignerEditor
+ * The editor to maximize
+ */
+ protected void maximizeEditor(SWTBotDesignerEditor swtBotDesignerEditor) {
+ swtBotDesignerEditor.maximize();
+ }
+
+ /**
+ * Press zoom in button.
+ *
+ * @param swtBotDesignerEditor
+ * The current editor
+ */
+ protected void pressZoomInButton(SWTBotDesignerEditor swtBotDesignerEditor) {
+ pressZoomInButton(swtBotDesignerEditor, 1);
+ }
+
+ /**
+ * Press "pressCount" times on zoom in button.
+ *
+ * @param swtBotDesignerEditor
+ * The current editor
+ * @param pressCount
+ * the number of times to press zoom in
+ */
+ protected void pressZoomInButton(SWTBotDesignerEditor swtBotDesignerEditor, int pressCount) {
+ for (int i = 1; i <= pressCount; i++) {
+ // TODO remove this work-around once tabbar will contain zoom in
+ // button
+ if (TestsUtil.isEclipse4xPlatform()) {
+ double currentZoom = GraphicalHelper.getZoom((IGraphicalEditPart) ((DiagramRootEditPart) swtBotDesignerEditor.rootEditPart().part()).getContents());
+ swtBotDesignerEditor.zoom(ZoomLevel.createNextZoomInLevel(currentZoom));
+ } else {
+ // 2 possible values for this tooltip according to the target
+ // platform
+ // No common constant was found, so we try with both possible
+ // values
+ try {
+ swtBotDesignerEditor.bot().toolbarButtonWithTooltip("Zoom In (Ctrl++)").click();
+ } catch (WidgetNotFoundException e) {
+ swtBotDesignerEditor.bot().toolbarButtonWithTooltip("Zoom In (Ctrl+=)").click();
+ }
+ }
+ }
+ }
+
+ /**
+ * Press zoom out button.
+ *
+ * @param swtBotDesignerEditor
+ * The current editor
+ */
+ protected void pressZoomOutButton(SWTBotDesignerEditor swtBotDesignerEditor) {
+ pressZoomOutButton(swtBotDesignerEditor, 1);
+ }
+
+ /**
+ * Press "pressCount" times on zoom out button.
+ *
+ * @param swtBotDesignerEditor
+ * The current editor
+ * @param pressCount
+ * the number of times to press zoom in
+ */
+ protected void pressZoomOutButton(SWTBotDesignerEditor swtBotDesignerEditor, int pressCount) {
+ for (int i = 1; i <= pressCount; i++) {
+ // TODO remove this work-around once tabbar will contain zoom out
+ // button
+ if (TestsUtil.isEclipse4xPlatform()) {
+ double currentZoom = GraphicalHelper.getZoom((IGraphicalEditPart) ((DiagramRootEditPart) swtBotDesignerEditor.rootEditPart().part()).getContents());
+ swtBotDesignerEditor.zoom(ZoomLevel.createNextZoomOutLevel(currentZoom));
+ } else {
+ swtBotDesignerEditor.bot().toolbarButtonWithTooltip("Zoom Out (Ctrl+-)").click();
+ }
+ }
+ }
+
+ /**
+ * Restore the size of the view/editor using the eclipse API.
+ *
+ * @param swtBotDesignerEditor
+ * The editor to restore
+ */
+ protected void restoreEditor(SWTBotDesignerEditor swtBotDesignerEditor) {
+ swtBotDesignerEditor.restore();
+ }
+
+ /***
+ * Do a arrange all of the current diagram.
+ *
+ * @return the menu of the ArrangeAll action
+ */
+ protected SWTBotMenu arrangeAll() {
+ // Give the focus to the editor
+ editor.setFocus();
+ // Select the diagram itself
+ editor.select(editor.mainEditPart());
+ // Launch the arrange via the menu bar
+ SWTBotMenu arrangeAllMenutBot = bot.menu("Diagram").menu("Arrange").menu("All").click();
+ SWTBotUtils.waitAllUiEvents();
+ return arrangeAllMenutBot;
+ }
+
+ /**
+ * Do a diagram refresh.
+ */
+ protected void refreshDiagram() {
+ editor.click(0, 0);
+ bot.toolbarButtonWithTooltip("Refresh diagram").click();
+ SWTBotUtils.waitProgressMonitorClose("Progress Information");
+ }
+
+ /**
+ * Get all the representation with the given representation description
+ * name.
+ *
+ * @param session
+ * The session containing the searched representations.
+ * @param representationDescriptionName
+ * the name of the representation description. <code>null</code>
+ * is not excepted.
+ * @return a {@link Collection} with all representations retrieved.
+ */
+ protected Collection<DRepresentation> getRepresentations(final Session session, final String representationDescriptionName) {
+ final Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getAllRepresentations(session);
+
+ final Collection<DRepresentation> representations = new HashSet<DRepresentation>();
+
+ for (final DRepresentation representation : allRepresentations) {
+ final RepresentationDescription desc = DialectManager.INSTANCE.getDescription(representation);
+ if (desc != null && representationDescriptionName.equals(desc.getName())) {
+ representations.add(representation);
+ }
+ }
+ return representations;
+ }
+
+ /**
+ * Return the first representation with the given representation description
+ * name and representation name.
+ *
+ * @param session
+ * The session containing the searched representations.
+ * @param representationDescriptionName
+ * the name of the representation description. <code>null</code>
+ * is not excepted.
+ * @param representationName
+ * the name of the representation
+ * @return the first corresponding representation
+ */
+ protected final DRepresentation getRepresentationWithName(Session session, String representationDescriptionName, final String representationName) {
+ try {
+ final DRepresentation existingRepresentation = Iterables.find(getRepresentations(session, representationDescriptionName), new Predicate<DRepresentation>() {
+ @Override
+ public boolean apply(DRepresentation input) {
+ return input.getName().equals(representationName);
+ }
+ });
+ return existingRepresentation;
+ } catch (NoSuchElementException e) {
+ throw new NoSuchElementException("No representation found in session with \"" + representationName + "\" as representation name and with \"" + representationDescriptionName
+ + "\" as representation description name.");
+ }
+
+ }
+
+ /**
+ * Open the first representation with the given representation description
+ * name and representation name.
+ *
+ * @param session
+ * The session containing the searched representations.
+ * @param representationDescriptionName
+ * the name of the representation description. <code>null</code>
+ * is not excepted.
+ * @param representationName
+ * the name of the representation
+ * @param expectedRepresentationClass
+ * the expected type of representation to found
+ * @return the editor of the first corresponding representation
+ */
+ protected SWTBotDesignerEditor openRepresentation(Session session, String representationDescriptionName, final String representationName,
+ Class<? extends DRepresentation> expectedRepresentationClass) {
+ return openRepresentation(session, representationDescriptionName, representationName, expectedRepresentationClass, false);
+ }
+
+ /**
+ * Open the first representation with the given representation description
+ * name and representation name.
+ *
+ * @param session
+ * The session containing the searched representations.
+ * @param representationDescriptionName
+ * the name of the representation description. <code>null</code>
+ * is not excepted.
+ * @param representationName
+ * the name of the representation
+ * @param expectedRepresentationClass
+ * the expected type of representation to found
+ * @param disableSnapToGridOnThisEditor
+ * true if the snapToGrid must be disable for this editor, false
+ * otherwise
+ * @return the editor of the first corresponding representation
+ */
+ protected SWTBotDesignerEditor openRepresentation(Session session, String representationDescriptionName, final String representationName,
+ Class<? extends DRepresentation> expectedRepresentationClass, boolean disableSnapToGridOnThisEditor) {
+ // Get the diagram with this name
+ DRepresentation representation = getRepresentationWithName(session, representationDescriptionName, representationName);
+ TestCase.assertTrue("This representation should be a " + expectedRepresentationClass.getSimpleName(), expectedRepresentationClass.isInstance(representation));
+ // Open the corresponding editor
+ IEditorPart editorPart = DialectUIManager.INSTANCE.openEditor(session, representation, new NullProgressMonitor());
+ SWTBotUtils.waitAllUiEvents();
+ // Get the corresponding SWtBotEditor
+ SWTBotDesignerEditor swtBotEditor = SWTBotDesignerHelper.getDesignerEditor(editorPart.getTitle());
+ if (disableSnapToGridOnThisEditor) {
+ swtBotEditor.disableSnapToGrid();
+ }
+ return swtBotEditor;
+ }
+
+ /**
+ * Get the widget bot corresponding to the button to set a workspace image
+ * on a selected node. If tabbar parameter at true, get the button of the
+ * tabbar, else get the button of the Appearance tab on the properties view.
+ *
+ * @param tabbar
+ * if tabbar parameter at true, get the button of the tabbar,
+ * else get the button of the Appearance tab on the properties
+ * view
+ * @param enabled
+ * true to check if the button must be enable, false to check if
+ * it shouldn't be enabled
+ * @return the widget bot corresponding to the button to set a workspace
+ * image on a selected node
+ */
+ protected AbstractSWTBot<? extends Widget> getSetStyleToWorkspaceImageButton(boolean tabbar, boolean enabled) {
+ AbstractSWTBot<? extends Widget> wkpImageButton = null;
+ if (tabbar) {
+ wkpImageButton = getSetStyleToWorkspaceImageButtonFromTabbar();
+ } else {
+ wkpImageButton = getSetStyleToWorkspaceImageButtonFromAppearanceTab();
+ }
+ TestCase.assertNotNull("Can't find the SetStyleToWorkspaceImage button in the " + (tabbar ? "tabbar" : "Appearance tab"), wkpImageButton);
+ TestCase.assertEquals("The SetStyleToWorkspaceImage button should be " + (enabled ? "enabled" : "disabled"), enabled, wkpImageButton.isEnabled());
+ return wkpImageButton;
+ }
+
+ /**
+ * Get the widget bot corresponding to the button to
+ * "Reset style properties to default" on a selected node/edge. If tabbar
+ * parameter at true, get the button of the tabbar, else get the button of
+ * the Appearance tab on the properties view.
+ *
+ * @param tabbar
+ * if tabbar parameter at true, get the button of the tabbar,
+ * else get the button of the Appearance tab on the properties
+ * view
+ * @param enabled
+ * true to check if the button must be enable, false to check if
+ * it shouldn't be enabled
+ * @return the widget bot corresponding to the button to
+ * "Reset style properties to default" on a selected node/edge
+ */
+ protected AbstractSWTBot<? extends Widget> getResetStylePropertiesToDefaultValuesButton(boolean tabbar, boolean enabled) {
+ AbstractSWTBot<? extends Widget> resetStylePropertiesToDefaultValuesButton = null;
+ if (!tabbar) {
+ resetStylePropertiesToDefaultValuesButton = getResetStylePropertiesToDefaultValuesButtonFromAppearanceTab();
+ } else {
+ resetStylePropertiesToDefaultValuesButton = getResetStylePropertiesToDefaultValuesButtonFromTabbar();
+ }
+ TestCase.assertNotNull("Can't find the \"" + ResetStylePropertiesToDefaultValuesAction.ACTION_NAME + "\" button in the " + (tabbar ? "tabbar" : "Appearance tab"),
+ resetStylePropertiesToDefaultValuesButton);
+ TestCase.assertEquals("The \"" + ResetStylePropertiesToDefaultValuesAction.ACTION_NAME + "\" button should be " + (enabled ? "enabled" : "disabled"), enabled,
+ resetStylePropertiesToDefaultValuesButton.isEnabled());
+ return resetStylePropertiesToDefaultValuesButton;
+ }
+
+ private SWTBotToolbarButton getSetStyleToWorkspaceImageButtonFromTabbar() {
+ return getTabbarButton(AbstractSiriusSwtBotGefTestCase.SET_STYLE_TO_WORKSPACE_IMAGE);
+ }
+
+ /**
+ * Returns the button allowing to reset the style to default from the
+ * tabbar.
+ *
+ * @return the button allowing to reset the style to default from the tabbar
+ */
+ protected SWTBotToolbarButton getResetStylePropertiesToDefaultValuesButtonFromTabbar() {
+ return getTabbarButton(ResetStylePropertiesToDefaultValuesAction.ACTION_NAME);
+ }
+
+ private SWTBotButton getSetStyleToWorkspaceImageButtonFromAppearanceTab() {
+ return getSectionButton(3, AbstractSiriusSwtBotGefTestCase.SET_STYLE_TO_WORKSPACE_IMAGE);
+ }
+
+ /**
+ * Click on the specified button.
+ *
+ * @param button
+ * the specified button
+ */
+ protected void click(AbstractSWTBot<? extends Widget> button) {
+ if (button instanceof SWTBotToolbarButton) {
+ ((SWTBotToolbarButton) button).click();
+ } else if (button instanceof SWTBotButton) {
+ ((SWTBotButton) button).click();
+ }
+ }
+
+ /**
+ * Returns the button allowing to reset the style to default from the
+ * appearance section.
+ *
+ * @return the button allowing to reset the style to default from the
+ * appearance section
+ */
+ protected SWTBotButton getResetStylePropertiesToDefaultValuesButtonFromAppearanceTab() {
+ SWTBotButton resetStylePropertiesToDefaultValuesButtonFromAppearanceTab = null;
+ int buttonIndex = 4;
+ editor.show();
+ editor.setFocus();
+ ISelection selection = editor.getSelection();
+ if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+ if (structuredSelection.getFirstElement() instanceof AbstractDiagramEdgeEditPart) {
+ buttonIndex = 3;
+ }
+ }
+ resetStylePropertiesToDefaultValuesButtonFromAppearanceTab = getSectionButton(buttonIndex, ResetStylePropertiesToDefaultValuesAction.ACTION_NAME);
+ return resetStylePropertiesToDefaultValuesButtonFromAppearanceTab;
+ }
+
+ /**
+ * Returns the button from the 'Appearance' section at the given index, that
+ * should have the given tooltip.
+ *
+ * @param index
+ * the index of the button to get from the 'Appearance' section
+ * @param tooltip
+ * the expected tooltip for this button
+ * @return the button from the 'Appearance' section at the given index, that
+ * should have the given tooltip
+ */
+ protected SWTBotButton getSectionButton(int index, String tooltip) {
+ SWTBot propertiesBot = bot.viewByTitle("Properties").bot();
+ bot.viewByTitle("Properties").setFocus();
+ SWTBotDesignerHelper.selectPropertyTabItem("Appearance");
+ SWTBotButton button = propertiesBot.buttonInGroup("Fonts and Colors:", index);
+
+ TestCase.assertNotNull(button);
+ // get button from index and check requested tool-tip allows to check
+ // position
+ TestCase.assertEquals(tooltip, button.getToolTipText());
+
+ return button;
+ }
+
+ private SWTBotToolbarButton getTabbarButton(String tooltip) {
+ editor.show();
+ SWTBot tabbarBot = editor.bot();
+ SWTBotToolbarButton button = tabbarBot.toolbarButtonWithTooltip(tooltip);
+
+ TestCase.assertNotNull("No button found with tooltip \"" + tooltip + "\"", button);
+
+ return button;
+ }
+
+ private void initErrorLoggers() {
+
+ logListener = new ILogListener() {
+
+ @Override
+ public void logging(IStatus status, String plugin) {
+ if (status.getSeverity() == IStatus.ERROR) {
+
+ if (!"org.eclipse.ui.views.properties.tabbed".equals(status.getPlugin())
+ && status.getMessage() != null
+ && !status
+ .getMessage()
+ .startsWith(
+ "Contributor org.eclipse.ui.navigator.ProjectExplorer cannot be created., exception: org.eclipse.core.runtime.CoreException: Plug-in \"org.eclipse.ui.navigator.resources\" was unable to instantiate class \"org.eclipse.ui.internal.navigator.resources.workbench.TabbedPropertySheetTitleProvider\".")) {
+ errorOccurs(status, plugin);
+ }
+ }
+ }
+
+ };
+ Platform.addLogListener(logListener);
+
+ exceptionHandler = new UncaughtExceptionHandler() {
+ private final String sourcePlugin = "Uncaught exception";
+
+ @Override
+ public void uncaughtException(Thread t, Throwable e) {
+
+ IStatus status = new Status(IStatus.ERROR, sourcePlugin, sourcePlugin, e);
+ errorOccurs(status, sourcePlugin);
+ }
+ };
+
+ Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
+
+ setErrorCatchActive(true);
+ }
+
+ private void disposeErrorLoggers() {
+ if (logListener != null) {
+ Platform.removeLogListener(logListener);
+ }
+ }
+
+ /**
+ * check if an error occurs.
+ *
+ * @return true if an error occurs.
+ */
+ protected synchronized boolean doesAnErrorOccurs() {
+ if (errors != null) {
+ return errors.values().size() != 0;
+ }
+ return false;
+ }
+
+ /**
+ * check if an error catch is active.
+ *
+ * @return true if an error catch is active.
+ */
+ protected synchronized boolean isErrorCatchActive() {
+ return errorCatchActive;
+ }
+
+ private synchronized void errorOccurs(IStatus status, String sourcePlugin) {
+ if (errorCatchActive) {
+ errors.put(sourcePlugin, status);
+ }
+ }
+
+ /**
+ * Activate or deactivate the external error detection: the test will fail
+ * in an error is logged or uncaught.
+ *
+ * @param errorCatchActive
+ * boolean to indicate if we activate or deactivate the external
+ * error detection
+ */
+ protected synchronized void setErrorCatchActive(boolean errorCatchActive) {
+ this.errorCatchActive = errorCatchActive;
+ }
+
+ private void checkErrors() {
+ /* an exception occurs in another thread */
+
+ /*
+ * TODO : skip checkErrors when we are in a shouldSkipUnreliableTests
+ * mode. We have some unwanted resource notifications during the
+ * teardown on jenkins.
+ */
+ if (!TestsUtil.shouldSkipUnreliableTests() && doesAnErrorOccurs()) {
+ Assert.fail(getErrorLoggersMessage());
+ }
+ }
+
+ /**
+ * Compute an error message from the detected errors.
+ *
+ * @return the error message.
+ */
+ protected synchronized String getErrorLoggersMessage() {
+
+ StringBuilder log1 = new StringBuilder();
+ String br = "\n";
+
+ String testName = getClass().getName();
+
+ log1.append("Error(s) raised during test : " + testName).append(br);
+ for (Entry<String, Collection<IStatus>> entry : errors.asMap().entrySet()) {
+ String reporter = entry.getKey();
+ log1.append(". Log Plugin : " + reporter).append(br);
+
+ for (IStatus status : entry.getValue()) {
+ log1.append(" . " + getSeverity(status) + " from plugin:" + status.getPlugin() + ", message: " + status.getMessage() + ", exception: " + status.getException()).append(br);
+ appendStackTrace(log1, br, status);
+ }
+ log1.append(br);
+ }
+ return log1.toString();
+ }
+
+ private void appendStackTrace(StringBuilder log1, String br, IStatus status) {
+ PrintWriter pw = null;
+ String stacktrace = null;
+ if (status.getException() != null) {
+ try {
+ StringWriter sw = new StringWriter();
+ pw = new PrintWriter(sw);
+ // CHECKSTYLE:OFF
+ status.getException().printStackTrace(pw);
+ // CHECKSTYLE:ON
+ stacktrace = sw.toString();
+ } finally {
+ if (pw != null) {
+ pw.close();
+ }
+ if (stacktrace == null) {
+ stacktrace = status.getException().toString();
+ }
+ log1.append(" . Stack trace: " + stacktrace).append(br);
+ }
+ }
+ }
+
+ private String getSeverity(IStatus status) {
+ String severity;
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ severity = "Ok";
+ break;
+ case IStatus.INFO:
+ severity = "Info";
+ break;
+ case IStatus.WARNING:
+ severity = "Warning";
+ break;
+ case IStatus.CANCEL:
+ severity = "Cancel";
+ break;
+ case IStatus.ERROR:
+ severity = "Error";
+ break;
+ default:
+ severity = "Unspecified";
+ }
+ return severity;
+ }
+
+ // Cannot be overriden, we are trying to preserve and cleanup workspace for
+ // next tests
+ private void failureTearDown() throws Exception {
+ try {
+ SWTBotUtils.waitAllUiEvents();
+
+ // Close an eventual popup if the test failed and a popup remain
+ // opened
+ if (bot != null) {
+ /*
+ * replace shells() by this code to avoid a
+ * WidgetNotFoundException: The widget {null} was disposed.
+ */
+ Shell[] shells = bot.getFinder().getShells();
+ ArrayList<SWTBotShell> result = new ArrayList<SWTBotShell>();
+ for (Shell shell : shells) {
+ if (!shell.isDisposed()) {
+ result.add(new SWTBotShell(shell));
+ }
+ }
+ final SWTBotShell[] foundShells = result.toArray(new SWTBotShell[] {});
+
+ for (final SWTBotShell swtBotShell : foundShells) {
+ // Close all opened windows except Eclipse
+ if (swtBotShell.isOpen()) {
+ for (IWorkbenchWindow w : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ if (swtBotShell.widget != w.getShell()) {
+ swtBotShell.close();
+ }
+ }
+ }
+ }
+ }
+
+ SWTBotUtils.waitAllUiEvents();
+
+ // Close all opened editors without saving before session closing to
+ // avoid ui events managed to late provoking exceptions for example
+ // because the session is already closed on ui event execution
+ closeAllEditors();
+
+ SWTBotUtils.waitAllUiEvents();
+
+ closeAllSessions();
+
+ SWTBotUtils.waitAllUiEvents();
+ Job.getJobManager().join(ResourceSyncClientNotifier.FAMILY, new NullProgressMonitor());
+
+ bot.closeAllEditors();
+
+ // Let the following loop delete the project.
+ designerProject = null;
+
+ SWTBotUtils.waitAllUiEvents();
+ // Delete projects created by the tests
+ for (final IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
+ designerPerspective.deleteProject(project.getName());
+ }
+
+ disposeErrorLoggers();
+ } finally {
+ // Reset the preferences changed during the test with the method
+ // changePreference. This is done in the finally block in case of
+ // ConcurrentModificationException during closeAllSession.
+ resetPreferences();
+
+ // Wait all ui events. Indeed, if we don't wait, the access to
+ // preferenceStore cause some NPE because the editor is not dispose
+ // :
+ // java.lang.NullPointerException
+ // at
+ // org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor$PropertyChangeListener.propertyChange(DiagramDocumentEditor.java:1661)
+ SWTBotUtils.waitAllUiEvents();
+
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ IPreferenceStore preferenceStore = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ preferenceStore.setValue(IPreferenceConstants.PREF_ENABLE_ANIMATED_ZOOM, defaultEnableAnimatedZoom);
+ preferenceStore.setValue(IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT, defaultEnableAnimatedLayout);
+ }
+ });
+ setErrorCatchActive(false);
+ checkErrors();
+ }
+
+ }
+
+ private void resetPreferences() {
+ // Reset the preferences changed during the test with the method
+ // changePreference. This is done in the finally block in case of
+ // ConcurrentModificationException during closeAllSession.
+ IPreferenceStore prefs = SiriusDiagramEditorPlugin.getInstance().getPreferenceStore();
+ for (String key : oldValuePreferences.keySet()) {
+ prefs.setValue(key, (Boolean) oldValuePreferences.get(key));
+ }
+
+ boolean currentUiPreference = prefs.getBoolean(SiriusDiagramPreferencesKeys.PREF_OLD_UI.name());
+ if (currentUiPreference) {
+ System.out.println("This test has not reset the oldUiPreference : " + this.getClass().getName() + " (it is currently true).");
+ }
+
+ // Reset the preferences changed during the test with the method
+ // changePreference. This is done in the finally block in case of
+ // ConcurrentModificationException during closeAllSession.
+ IPreferenceStore platformPrefs = PlatformUI.getPreferenceStore();
+ for (String key : oldPlatformUIPreferences.keySet()) {
+ platformPrefs.setValue(key, (Boolean) oldPlatformUIPreferences.get(key));
+ }
+
+ IPreferenceStore viewpointUIPrefs = SiriusEditPlugin.getPlugin().getPreferenceStore();
+ for (String key : oldValueSiriusUIPreferences.keySet()) {
+ viewpointUIPrefs.setValue(key, (Boolean) oldValueSiriusUIPreferences.get(key));
+ }
+
+ IEclipsePreferences corePreferences = InstanceScope.INSTANCE.getNode(SiriusPlugin.ID);
+ for (String key : oldValueSiriusPreferences.keySet()) {
+ corePreferences.putBoolean(key, (Boolean) oldValueSiriusPreferences.get(key));
+ }
+ }
+
+ /**
+ * Open viewpoint specification model.
+ *
+ * @param viewpointSpecificationModel
+ * the name of viewpoint specification model (.odesing)
+ * @return odesignEditor
+ */
+ public SWTBotVSMEditor openViewpointSpecificationModel(String viewpointSpecificationModel) {
+ SWTBotCommonHelper.openEditor(getProjectName(), viewpointSpecificationModel);
+ SWTBotVSMEditor odesignEditor = SWTBotVSMHelper.getVSMEditorContainingName(viewpointSpecificationModel);
+ odesignEditor.setFocus();
+ return odesignEditor;
+ }
+
+ /***
+ * Copy file to test run project.
+ *
+ * @param pluginId
+ * corresponding to project name containing data for test
+ * @param dataUnitDir
+ * the path of the directory containing datas
+ * @param fileNames
+ * the files to copy
+ */
+ protected void copyFileToTestProject(String pluginId, String dataUnitDir, final String... fileNames) {
+ for (final String fileName : fileNames) {
+ EclipseTestsSupportHelper.INSTANCE.copyFile(pluginId, dataUnitDir + fileName, getProjectName() + "/" + fileName);
+ }
+ }
+
+ /**
+ * Explore the current {@link SWTBotDesignerEditor} edit part children
+ * recursively to find out a {@link TextEditPart} with the expected label.
+ *
+ * @param label
+ * the label of the expected {@link TextEditPart}
+ * @return a {@link TextEditPart} with the expected label if existing, null
+ * otherwise
+ */
+ public SWTBotGefEditPart findTextEditPart(String label) {
+ return findTextEditPart(editor.rootEditPart(), label);
+ }
+
+ /**
+ * Explore the {@link SWTBotDesignerEditor} edit part children recursively
+ * to find out a {@link TextEditPart} with the expected label.
+ *
+ * @param designerEditor
+ * the current {@link SWTBotDesignerEditor} to look for a
+ * {@link TextEditPart}
+ * @param label
+ * the label of the expected {@link TextEditPart}
+ * @return a {@link TextEditPart} with the expected label if existing, null
+ * otherwise
+ */
+ public SWTBotGefEditPart findTextEditPart(SWTBotDesignerEditor designerEditor, String label) {
+ return findTextEditPart(designerEditor.rootEditPart(), label);
+ }
+
+ /**
+ * Explore the {@link SWTBotGefEditPart} children recursively to find out a
+ * {@link TextEditPart} with the expected label.
+ *
+ * @param parent
+ * the {@link SWTBotGefEditPart} parent to start exploration
+ * @param label
+ * the label of the expected {@link TextEditPart}
+ * @return a {@link TextEditPart} with the expected label if existing, null
+ * otherwise
+ */
+ public SWTBotGefEditPart findTextEditPart(SWTBotGefEditPart parent, String label) {
+ SWTBotGefEditPart result = null;
+ if (parent.part() instanceof TextEditPart) {
+ TextEditPart textEditPart = (TextEditPart) parent.part();
+ DescriptionCompartmentEditPart descriptionCompartmentEditPart = Iterables.getOnlyElement(Iterables.filter(textEditPart.getChildren(), DescriptionCompartmentEditPart.class));
+ if (descriptionCompartmentEditPart.getFigure() instanceof WrappingLabel && label.equals(((WrappingLabel) descriptionCompartmentEditPart.getFigure()).getText())) {
+ result = parent;
+ }
+ } else {
+ for (SWTBotGefEditPart child : parent.children()) {
+ SWTBotGefEditPart childrenResult = findTextEditPart(child, label);
+ if (childrenResult != null) {
+ return childrenResult;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Change the default font.
+ *
+ * @param fontName
+ * the font name to set as default.
+ * @return the previous default font name.
+ */
+ protected String changeDefaultFontName(String fontName) {
+ IPreferenceStore preferenceStore = (IPreferenceStore) SiriusDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT.getPreferenceStore();
+ FontData fontData = PreferenceConverter.getFontData(preferenceStore, IPreferenceConstants.PREF_DEFAULT_FONT);
+
+ // Get the actual font.
+ String oldName = fontData.getName();
+
+ // Change the font.
+ fontData.setName(fontName);
+ PreferenceConverter.setDefault(preferenceStore, IPreferenceConstants.PREF_DEFAULT_FONT, fontData);
+ return oldName;
+ }
+
+ /**
+ * Scan contained figures to find the background color of a figure typed as
+ * figureClass.
+ *
+ * @param editPart
+ * EditPart containing the figures that need investigation
+ * @param figureClass
+ * expected figure type
+ * @return the background color of the figure if found, null otherwise
+ */
+ protected Color getFigureBackgroundColor(AbstractBorderedShapeEditPart editPart, Class<? extends Figure> figureClass) {
+ IFigure figure = editPart.getFigure();
+ if (figureClass.isInstance(figure)) {
+ return figure.getBackgroundColor();
+ } else {
+ return getFigureBackgroundColor(figure, figureClass);
+ }
+ }
+
+ /**
+ * Scan contained figures to find the background color of a figure typed as
+ * figureClass.
+ *
+ * @param parentFigure
+ * {@link Figure} containing the figures that need investigation
+ * @param figureClass
+ * expected figure type
+ * @return the background color of the figure if found, null otherwise
+ */
+ protected Color getFigureBackgroundColor(IFigure parentFigure, Class<? extends Figure> figureClass) {
+ Iterable<? extends Figure> filter = Iterables.filter(parentFigure.getChildren(), figureClass);
+ if (Iterables.size(filter) == 1) {
+ return Iterables.getOnlyElement(filter).getBackgroundColor();
+ }
+ Color backgroundColor = null;
+ for (IFigure childFigure : Iterables.filter(parentFigure.getChildren(), IFigure.class)) {
+ backgroundColor = getFigureBackgroundColor(childFigure, figureClass);
+ if (backgroundColor != null) {
+ break;
+ }
+ }
+ return backgroundColor;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ failureTearDown();
+
+ new TestCaseCleaner(this).clearAllFields();
+
+ super.tearDown();
+ setErrorCatchActive(false);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/SWTDesignerBot.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/SWTDesignerBot.java
new file mode 100644
index 0000000000..fa137cf4e3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/SWTDesignerBot.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.bot;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.hamcrest.Matcher;
+
+/**
+ * Inner bot.
+ *
+ * @author dlecan
+ */
+public class SWTDesignerBot extends SWTWorkbenchBot {
+
+ /**
+ * Get GMF drop down button with SWT.SEPARATOR style instead of
+ * SWT.DROP_DOWN style !
+ *
+ * @param tooltip
+ * the tooltip on the widget.
+ * @return a ToolItem with the specified <code>tooltip</code>.
+ */
+ @SuppressWarnings("unchecked")
+ public ToolItem toolbarSpecialDropDownButtonWithTooltip(final String tooltip) {
+ final Matcher matcher = WidgetMatcherFactory.allOf(WidgetMatcherFactory.widgetOfType(ToolItem.class), WidgetMatcherFactory.withTooltip(tooltip),
+ WidgetMatcherFactory.withStyle(SWT.SEPARATOR, "SWT.SEPARATOR"));
+ return (ToolItem) widget(matcher, 0);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/AbstractOdesignTreeItemBot.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/AbstractOdesignTreeItemBot.java
new file mode 100644
index 0000000000..7f99019662
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/AbstractOdesignTreeItemBot.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.bot.description;
+
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusPropertiesView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Mother class for manipulating an VSM element in the VSM editor.
+ *
+ * @author amartin
+ */
+public class AbstractOdesignTreeItemBot {
+ SWTBotTreeItem treeItem;
+
+ SWTBot bot;
+
+ SiriusPropertiesView propertiesView;
+
+ /**
+ * The constructor.
+ *
+ * @param bot
+ * The current bot.
+ * @param treeItem
+ * the SWTBotTreeItem of the tree.
+ * @param propertiesView
+ * the properties view to use in order edit the element.
+ */
+ public AbstractOdesignTreeItemBot(SWTBot bot, SWTBotTreeItem treeItem, SiriusPropertiesView propertiesView) {
+ this.treeItem = treeItem;
+ this.bot = bot;
+ this.propertiesView = propertiesView;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/DiagramDescriptionBot.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/DiagramDescriptionBot.java
new file mode 100644
index 0000000000..1613c5f966
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/DiagramDescriptionBot.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.bot.description;
+
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusPropertiesView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to manipulate a Diagram Description element in a odesign
+ * editor.
+ *
+ * @author amartin
+ */
+public class DiagramDescriptionBot extends AbstractOdesignTreeItemBot {
+
+ /**
+ * The constructor.
+ *
+ * @param bot
+ * the bot.
+ * @param treeItem
+ * the treItem to manipulate.
+ * @param propertiesView
+ * the properties view to edit the properties of the viewpoint
+ * element.
+ *
+ */
+ public DiagramDescriptionBot(SWTBot bot, SWTBotTreeItem treeItem, SiriusPropertiesView propertiesView) {
+ super(bot, treeItem, propertiesView);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/GroupBot.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/GroupBot.java
new file mode 100644
index 0000000000..9910c1f736
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/GroupBot.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.bot.description;
+
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusPropertiesView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to manipulate a Group element in a VSM editor.
+ *
+ * @author amartin
+ */
+public class GroupBot extends AbstractOdesignTreeItemBot {
+
+ /**
+ * The constructor.
+ *
+ * @param bot
+ * the bot.
+ * @param treeItem
+ * the treItem to manipulate.
+ * @param propertiesView
+ * the properties view to edit the properties of the viewpoint
+ * element.
+ *
+ */
+ public GroupBot(SWTBot bot, SWTBotTreeItem treeItem, SiriusPropertiesView propertiesView) {
+ super(bot, treeItem, propertiesView);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/SiriusBot.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/SiriusBot.java
new file mode 100644
index 0000000000..399910f330
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/bot/description/SiriusBot.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.bot.description;
+
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusPropertiesView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to manipulate a Sirius element in a odesign editor.
+ *
+ * @author amartin
+ */
+public class SiriusBot extends AbstractOdesignTreeItemBot {
+ /**
+ * The constructor.
+ *
+ * @param bot
+ * the bot.
+ * @param treeItem
+ * the treeItem to manipulate.
+ * @param propertiesView
+ * the properties view to edit the properties of the viewpoint
+ * element.
+ */
+ public SiriusBot(SWTBot bot, SWTBotTreeItem treeItem, SiriusPropertiesView propertiesView) {
+ super(bot, treeItem, propertiesView);
+ }
+
+ /**
+ * A function who create a diagram in a odesign.
+ *
+ * @param diagramName
+ * the name of the diagram to create.
+ * @return the SWT diagram created.
+ */
+ public DiagramDescriptionBot createDiagramDescription(String diagramName) {
+ treeItem.contextMenu("New Child").menu("Diagram Description");
+ propertiesView.setName(diagramName);
+ treeItem.setFocus();
+ return new DiagramDescriptionBot(bot, treeItem.getNode(diagramName), propertiesView);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/AbstractUIRepresentation.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/AbstractUIRepresentation.java
new file mode 100644
index 0000000000..01561ae130
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/AbstractUIRepresentation.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.sirius.tests.swtbot.support.api.bot.SWTDesignerBot;
+import org.eclipse.sirius.tests.swtbot.support.api.business.sessionbrowser.AbstractUIElementWithTreeItem;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotCommonHelper;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.ui.business.api.dialect.DialectEditor;
+import org.eclipse.sirius.viewpoint.DRepresentation;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Object to represent representations (diagrams, tables, ...).
+ *
+ * @author dlecan
+ * @param <E>
+ * Type of editor.
+ */
+public abstract class AbstractUIRepresentation<E extends SWTBotEditor> extends AbstractUIElementWithTreeItem {
+
+ /**
+ * Inner special SWTBot.
+ */
+ protected SWTDesignerBot designerBot = new SWTDesignerBot();
+
+ private final String representationName;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item.
+ *
+ * @param representationName
+ * Representation name.
+ */
+ public AbstractUIRepresentation(final SWTBotTreeItem treeItem, final String representationName) {
+ super(treeItem);
+ this.representationName = representationName;
+ }
+
+ /**
+ * Close current representation.
+ */
+ public void close() {
+ SWTBotCommonHelper.closeCurrentEditor();
+ }
+
+ /**
+ * Open current representation. Does nothing if current diagram was created
+ * in this test session instead of being simply opened.
+ */
+ protected void doOpen() {
+
+ if (getTreeItem() != null) {
+
+ getTreeItem().select().setFocus();
+ getTreeItem().doubleClick();
+ }
+
+ SWTBotUtils.waitProgressMonitorClose("Open representation");
+ }
+
+ /**
+ * save current representation.
+ */
+
+ protected void doSave() {
+ SWTBotCommonHelper.saveCurrentEditor();
+ }
+
+ /**
+ * Delete this representation.
+ */
+ public void delete() {
+ SWTBotUtils.clickContextMenu(getTreeItem(), "Delete");
+ }
+
+ /**
+ * Returns the representationName.
+ *
+ * @return The representationName.
+ */
+ protected String getRepresentationName() {
+ return representationName;
+ }
+
+ /**
+ * Get the associated {@link DRepresentation}.
+ *
+ * @return the associated {@link DRepresentation}
+ */
+ public DRepresentation getDRepresentation() {
+ DRepresentation dRepresentation = null;
+ IEditorPart editorPart = getEditor().getReference().getEditor(false);
+ if (editorPart instanceof DialectEditor) {
+ DialectEditor dialectEditor = (DialectEditor) editorPart;
+ dRepresentation = dialectEditor.getRepresentation();
+ }
+ return dRepresentation;
+ }
+
+ /**
+ * Get Editor.
+ *
+ * @return Editor.
+ */
+ public abstract E getEditor();
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/ExistingSemanticResourceWizardUIWrapper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/ExistingSemanticResourceWizardUIWrapper.java
new file mode 100644
index 0000000000..8a469ae116
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/ExistingSemanticResourceWizardUIWrapper.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+
+/**
+ * A UI wrapper of the semantic resource selection browser to add existing
+ * semantic resource to a session.
+ *
+ * @author edugueperoux
+ */
+public class ExistingSemanticResourceWizardUIWrapper {
+
+ // private SWTBotShell semanticResourceSelectionBrowserBot;
+
+ /**
+ * Default constructor.
+ *
+ * @param semanticResourceSelectionBrowserBot
+ * UI wrapper to the semantic resource selection browser.
+ */
+ public ExistingSemanticResourceWizardUIWrapper(SWTBotShell semanticResourceSelectionBrowserBot) {
+ // this.semanticResourceSelectionBrowserBot =
+ // semanticResourceSelectionBrowserBot;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/SemanticResourceFromSratchWizardUIWrapper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/SemanticResourceFromSratchWizardUIWrapper.java
new file mode 100644
index 0000000000..3b5fe2bb52
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/SemanticResourceFromSratchWizardUIWrapper.java
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.sirius.tests.swtbot.support.api.condition.ItemEnabledCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.dialog.ViewpointSelectionDialog;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotCombo;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+
+/**
+ * UI wrapper for the WizardPage of creation from scratch of a semantic resource
+ * to add to the current session.
+ *
+ * @author edugueperoux
+ */
+public class SemanticResourceFromSratchWizardUIWrapper {
+
+ private final SWTBotShell newPage;
+
+ private final ViewpointSelectionDialog selectionDialog;
+
+ /**
+ * Default constructor.
+ *
+ * @param uiLocalSession
+ * the current {@link UILocalSession}
+ *
+ * @param newPage
+ * UI wrapper to a session.
+ */
+ public SemanticResourceFromSratchWizardUIWrapper(UILocalSession uiLocalSession, SWTBotShell newPage) {
+ this.newPage = newPage;
+ this.selectionDialog = new ViewpointSelectionDialog(uiLocalSession.bot);
+ }
+
+ /**
+ * Set in the "Metamodel URI" text field the nsURI of the metamodel for
+ * which to create a model instance.
+ *
+ * @param nsURI
+ * the nsURI of the EPackage on which we create the model
+ * instance.
+ *
+ * @return this
+ */
+ public SemanticResourceFromSratchWizardUIWrapper selectDirecltyMetamodelURI(String nsURI) {
+ SWTBot bot = newPage.bot();
+ SWTBotCombo comboBox = bot.comboBox();
+ comboBox.setFocus();
+ comboBox.setSelection(nsURI);
+ return this;
+ }
+
+ /**
+ * Set in the "Metamodel URI" text field the nsURI of the metamodel for
+ * which to create a model instance.
+ *
+ * @param rootModelElementName
+ * the name of the metaclass to use as type for the root element
+ * of the semantic resource to create.
+ *
+ * @return this
+ */
+ public SemanticResourceFromSratchWizardUIWrapper selectRootModelElementToUse(String rootModelElementName) {
+ SWTBot bot = newPage.bot();
+ SWTBotCombo swtBotCombo = bot.comboBox(1);
+ swtBotCombo.setFocus();
+ swtBotCombo.setText(rootModelElementName);
+ return this;
+ }
+
+ /**
+ * Set in the "Metamodel URI" text field the nsURI of the metamodel for
+ * which to create a model instance.
+ *
+ * @param semanticResourceFileName
+ * the semantic resource filename to create
+ *
+ * @return this
+ */
+ public SemanticResourceFromSratchWizardUIWrapper setSemanticResourceFileName(String semanticResourceFileName) {
+ SWTBot bot = newPage.bot();
+ SWTBotText textBot = bot.text(0);
+ textBot.setFocus();
+ textBot.setText(semanticResourceFileName);
+ return this;
+ }
+
+ /**
+ * Click on the Finish button.
+ *
+ * @param viewpointsToSelect
+ * set of viewpoint to select
+ */
+ public void finishWithViewpointSelection(Set<String> viewpointsToSelect) {
+ SWTBot bot = newPage.bot();
+ SWTBotButton button = bot.button("Finish");
+ bot.waitUntil(new ItemEnabledCondition(button));
+ button.click();
+
+ selectionDialog.selectViewpoint(viewpointsToSelect, Collections.<String> emptySet());
+ bot.waitUntil(Conditions.shellCloses(newPage));
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIAddLocalSemanticResourceWizardUIWrapper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIAddLocalSemanticResourceWizardUIWrapper.java
new file mode 100644
index 0000000000..687ed8c082
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIAddLocalSemanticResourceWizardUIWrapper.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.sirius.tests.swtbot.support.api.condition.ItemEnabledCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.WrappedSWTBotRadio;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+
+/**
+ * SWTBot bot for the wizard to add a local semantic resource to the current
+ * session.
+ *
+ * @author edugueperoux
+ */
+public class UIAddLocalSemanticResourceWizardUIWrapper {
+
+ /** The wizard. */
+ protected SWTBotShell localSemanitcResourceWizardUIWrapper;
+
+ private final UILocalSession uiLocalSession;
+
+ /**
+ * Default constructor.
+ *
+ * @param uiLocalSession
+ * the UI wrapper of the session to use
+ */
+ public UIAddLocalSemanticResourceWizardUIWrapper(UILocalSession uiLocalSession) {
+ this.uiLocalSession = uiLocalSession;
+ uiLocalSession.getRootSessionTreeItem().contextMenu("Add Model").click();
+ localSemanitcResourceWizardUIWrapper = uiLocalSession.bot.activeShell();
+ }
+
+ /**
+ * Get a UI wrapper for the WizardPage of creation from scratch of a
+ * semantic resource to add to the current session.
+ *
+ * @return SemanticResourceFromSratchWizardUIWrapper UI wrapper for the
+ * WizardPage of creation from scratch of a semantic resource to add
+ * to the current session
+ */
+ public SemanticResourceFromSratchWizardUIWrapper createNewSemanticResourceFromSratchWizardUIWrapper() {
+ SWTBot bot = localSemanitcResourceWizardUIWrapper.bot();
+ SWTBotRadio radio = bot.radio(0);
+ new WrappedSWTBotRadio(radio).click();
+ SWTBotButton button = bot.button("Next >");
+ bot.waitUntil(new ItemEnabledCondition(button));
+ button.click();
+ return new SemanticResourceFromSratchWizardUIWrapper(uiLocalSession, bot.activeShell());
+ }
+
+ /**
+ * Get the UI wrapper for the WizardPage of selection of a existing semantic
+ * resource to the current session.
+ *
+ * @return a ExistingSemanticResourceWizardUIWrapper to use for add of
+ * existing semantic resource to the current session
+ */
+ public ExistingSemanticResourceWizardUIWrapper addExistingSemanticResourceWizardUIWrapper() {
+ SWTBot bot = localSemanitcResourceWizardUIWrapper.bot();
+ bot.buttonWithLabel("Add existing resource").setFocus();
+ bot.buttonWithLabel("Finish").click();
+ return new ExistingSemanticResourceWizardUIWrapper(bot.activeShell());
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIDiagramRepresentation.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIDiagramRepresentation.java
new file mode 100644
index 0000000000..5e4ad16785
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIDiagramRepresentation.java
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.sirius.diagram.part.SiriusDiagramEditorPlugin;
+import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramPreferencesKeys;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerHelper;
+import org.eclipse.sirius.tests.swtbot.support.api.view.DesignerViews;
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusOutlineView;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarDropDownButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.hamcrest.Matcher;
+
+/**
+ * Object to manage diagram representations.
+ *
+ * @author dlecan
+ */
+public class UIDiagramRepresentation extends AbstractUIRepresentation<SWTBotDesignerEditor> {
+
+ /**
+ * Zoom levels.
+ *
+ * @author dlecan
+ */
+ public static enum ZoomLevel {
+ /**
+ * Zoom 50%.
+ */
+ ZOOM_50("50%", 0.5),
+
+ /**
+ * Zoom 100%.
+ */
+ ZOOM_100("100%", 1.0),
+
+ /**
+ * Zoom 125%.
+ */
+ ZOOM_125("125%", 1.25),
+
+ /**
+ * Zoom 200%.
+ */
+ ZOOM_200("200%", 2.0),
+
+ /**
+ * Zoom 400%.
+ */
+ ZOOM_400("400%", 4.0);
+
+ private final String level;
+
+ private final double amount;
+
+ private ZoomLevel(final String level, final double amount) {
+ this.level = level;
+ this.amount = amount;
+ }
+
+ /**
+ * Returns the level.
+ *
+ * @return The level.
+ */
+ public String getLevel() {
+ return level;
+ }
+
+ /**
+ * Returns the amount.
+ *
+ * @return The amount.
+ */
+ public double getAmount() {
+ return amount;
+ }
+
+ /**
+ * Returns the {@link ZoomLevel} corresponding to the next zoom in (e.g.
+ * 2.0 if current zoom level is >= 1.25 and < to 2).
+ *
+ * @param currentZoomLevel
+ * the current zoom level
+ * @return the {@link ZoomLevel} corresponding to the next zoom in (e.g.
+ * 2.0 if current zoom level is >= 1.25 and < to 2)
+ */
+ public static ZoomLevel createNextZoomInLevel(double currentZoomLevel) {
+ ZoomLevel nextZoomInLevel = ZOOM_100;
+ if (currentZoomLevel >= 2) {
+ nextZoomInLevel = ZOOM_400;
+ }
+ if (currentZoomLevel >= 1.25) {
+ nextZoomInLevel = ZOOM_200;
+ } else if (currentZoomLevel >= 1.0) {
+ nextZoomInLevel = ZOOM_125;
+ }
+ return nextZoomInLevel;
+ }
+
+ /**
+ * Returns the {@link ZoomLevel} corresponding to the next zoom out
+ * (e.g. 1.25 if current zoom level is <= 2 and > to 1.25).
+ *
+ * @param currentZoomLevel
+ * the current zoom level
+ * @return the {@link ZoomLevel} corresponding to the next zoom zoom out
+ * (e.g. 1.25 if current zoom level is <= 2 and > to 1.25)
+ */
+ public static ZoomLevel createNextZoomOutLevel(double currentZoomLevel) {
+ ZoomLevel nextZoomOutLevel = ZOOM_200;
+ if (currentZoomLevel <= 1.0) {
+ nextZoomOutLevel = ZOOM_50;
+ } else if (currentZoomLevel <= 1.25) {
+ nextZoomOutLevel = ZOOM_100;
+ } else if (currentZoomLevel <= 2.0) {
+ nextZoomOutLevel = ZOOM_125;
+ }
+ return nextZoomOutLevel;
+ }
+ }
+
+ /**
+ * The default zoom level.
+ */
+ public static final ZoomLevel ZOOM_DEFAULT = ZoomLevel.ZOOM_100;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item.
+ *
+ * @param representationName
+ * Representation name.
+ */
+ public UIDiagramRepresentation(final SWTBotTreeItem treeItem, final String representationName) {
+ super(treeItem, representationName);
+ }
+
+ /**
+ * Open current representation. Does nothing if current diagram was created
+ * in this test session instead of being simply opened.
+ *
+ * @return Current representation.
+ */
+ public UIDiagramRepresentation open() {
+ super.doOpen();
+ return this;
+ }
+
+ /**
+ * save current representation.
+ *
+ * @return Current representation.
+ */
+
+ public UIDiagramRepresentation save() {
+ super.doSave();
+ return this;
+ }
+
+ /**
+ * Zoom to next zoom value.
+ *
+ * @return Current representation.
+ */
+ public UIDiagramRepresentation zoomDefault() {
+ return zoom(UIDiagramRepresentation.ZOOM_DEFAULT);
+ }
+
+ /**
+ * Zoom to next zoom value.
+ *
+ * @param zoomLevel
+ * Zoom level
+ *
+ * @return Current representation.
+ */
+ public UIDiagramRepresentation zoom(final ZoomLevel zoomLevel) {
+ getEditor().zoom(zoomLevel);
+ return this;
+ }
+
+ /**
+ * .
+ *
+ * @param layerName
+ * .
+ * @return .
+ */
+ public UIDiagramRepresentation changeLayerActivation(final String layerName) {
+
+ if (useTabbar()) {
+ SWTBotToolbarDropDownButton button = designerBot.toolbarDropDownButtonWithTooltip("Layers");
+ Matcher<MenuItem> withLayerName = WidgetMatcherFactory.withText(layerName);
+ SWTBotMenu layerButton = button.menuItem(withLayerName);
+ layerButton.click();
+ } else {
+ DesignerViews designerViews = new DesignerViews(designerBot);
+ final SiriusOutlineView outlineView = designerViews.getOutlineView().layers();
+ outlineView.activateLayer(layerName);
+ }
+
+ return this;
+ }
+
+ private boolean useTabbar() {
+ IPreferencesService prefs = Platform.getPreferencesService();
+ return !prefs.getBoolean(SiriusDiagramEditorPlugin.ID, SiriusDiagramPreferencesKeys.PREF_OLD_UI.name(), false, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SWTBotDesignerEditor getEditor() {
+ return SWTBotDesignerHelper.getDesignerEditorContainingName(getRepresentationName());
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UILocalSession.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UILocalSession.java
new file mode 100644
index 0000000000..939e8aa258
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UILocalSession.java
@@ -0,0 +1,625 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.sirius.business.api.helper.SiriusUtil;
+import org.eclipse.sirius.business.api.modelingproject.ModelingProject;
+import org.eclipse.sirius.business.api.query.URIQuery;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.business.api.session.SessionStatus;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UINewRepresentationBuilderFlow.ItemChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.business.sessionbrowser.UILocalSessionBrowser;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.ItemEnabledCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.SessionClosedCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.SessionSavedCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.TreeItemExpanded;
+import org.eclipse.sirius.tests.swtbot.support.api.dialog.ViewpointSelectionDialog;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.ui.tools.api.views.modelexplorerview.IModelExplorerView;
+import org.eclipse.sirius.viewpoint.description.Viewpoint;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.junit.Assert;
+
+/**
+ * Object to do graphical operations on sessions.
+ *
+ * @author dlecan
+ */
+public class UILocalSession {
+
+ private static final String SEPARATOR = "/";
+
+ /** The UIResource associated to the model resource. */
+ protected UIResource modelResource;
+
+ /** The Session associated to this UILocalSession. */
+ protected Session openedSession;
+
+ /** The SWTBot bot used buy this LocalSession. */
+ protected final SWTWorkbenchBot bot;
+
+ /**
+ * The UIResource associated to this Session.
+ */
+ protected final UIResource sessionResource;
+
+ private SWTBotView modelContentView;
+
+ /**
+ * Default constructor, only visible for subclasses.
+ *
+ * @param sessionResource
+ * Session resource
+ */
+ public UILocalSession(final UIResource sessionResource) {
+ this.sessionResource = sessionResource;
+ this.modelResource = null;
+ bot = new SWTWorkbenchBot();
+ initSession();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param modelResource
+ * Model resource
+ * @param sessionResource
+ * Session resource
+ */
+ public UILocalSession(final UIResource modelResource, final UIResource sessionResource) {
+ this.modelResource = modelResource;
+ this.sessionResource = sessionResource;
+ bot = new SWTWorkbenchBot();
+ initSession();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param modelResource
+ * Model resource
+ * @param sessionResource
+ * Session resource
+ * @param openedSession
+ * Session
+ */
+ public UILocalSession(final UIResource modelResource, final UIResource sessionResource, final Session openedSession) {
+ this(modelResource, sessionResource);
+ this.openedSession = openedSession;
+ }
+
+ /**
+ * Init the openedSession field from the sessionResource UIResource.
+ */
+ private void initSession() {
+ URI sessionResourceURI = URI.createPlatformResourceURI(sessionResource.getFullPath(), true);
+ openedSession = SessionManager.INSTANCE.getSession(sessionResourceURI, new NullProgressMonitor());
+ if (modelResource == null && !openedSession.getSemanticResources().isEmpty()) {
+ Resource firstSemanticResource = openedSession.getSemanticResources().iterator().next();
+ String path = sessionResource.getProject().getName();
+ for (int i = 1; i < firstSemanticResource.getURI().segmentCount() - 1; i++) {
+ path += UILocalSession.SEPARATOR + firstSemanticResource.getURI().segment(i);
+ }
+ modelResource = new UIResource(sessionResource.getProject(), path, firstSemanticResource.getURI().lastSegment());
+ }
+ }
+
+ /**
+ * Gets the opened session.
+ *
+ * @return the openedSession. May be <code>null</code>.
+ */
+ public Session getOpenedSession() {
+ return openedSession;
+ }
+
+ /**
+ * Select "Local Session View".
+ *
+ * @return Current {@link UILocalSession}
+ */
+ public UILocalSession selectView() {
+ modelContentView = bot.viewById(IModelExplorerView.ID);
+ modelContentView.setFocus();
+ return this;
+ }
+
+ /**
+ * Get ui tree node of semantic resource.
+ *
+ * @param uiResource
+ * UI resource we want to get in local session.
+ * @return Corresponding {@link SWTBotTreeItem}
+ */
+ public SWTBotTreeItem getSemanticResourceNode(final UIResource uiResource) {
+ SWTBotTreeItem semanticResourceNode = null;
+ SWTBotTreeItem rootTreeItem = getRootSessionTreeItem().expand();
+ if (new URIQuery(this.openedSession.getSessionResource().getURI()).isInMemoryURI()) {
+ // transient session case
+ semanticResourceNode = rootTreeItem.expand();
+ } else {
+ if (isModelingProject()) {
+ semanticResourceNode = rootTreeItem;
+ if (uiResource.getNodePath() != null && !uiResource.getNodePath().isEmpty()) {
+ for (int i = 0; i < uiResource.getNodePath().size(); i++) {
+ String pathSegment = uiResource.getNodePath().get(i);
+ semanticResourceNode = semanticResourceNode.getNode(pathSegment).expand();
+ }
+ }
+ } else {
+ semanticResourceNode = getRepresentationsFileTreeItem();
+ }
+ semanticResourceNode = semanticResourceNode.getNode(getSemanticResourceNodeLabel(uiResource)).expand();
+ }
+ return semanticResourceNode;
+ }
+
+ /**
+ * Creation new diagram.<br/>
+ * Equivalent to call
+ * <code>newRepresentation(String, UIDiagramRepresentation.class)</code>.
+ *
+ * @param clickedRepresentationName
+ * Representation name where to in contextual menu.
+ * @return UI representation builder
+ */
+ public ItemChoice<UIDiagramRepresentation> newDiagramRepresentation(final String clickedRepresentationName) {
+ return new UINewRepresentationBuilder<UIDiagramRepresentation>(clickedRepresentationName, UIDiagramRepresentation.class);
+ }
+
+ /**
+ * Creation new diagram.<br/>
+ * Equivalent to call
+ * <code>newRepresentation(String, UIDiagramRepresentation.class)</code>.
+ *
+ * @param clickedRepresentationName
+ * Representation name where to in contextual menu.
+ * @return UI representation builder
+ */
+ public ItemChoice<UITableRepresentation> newTableRepresentation(final String clickedRepresentationName) {
+ return new UINewRepresentationBuilder<UITableRepresentation>(clickedRepresentationName, UITableRepresentation.class);
+ }
+
+ /**
+ * Creation new table.<br/>
+ * Equivalent to call
+ * <code>newRepresentation(String, UIDiagramRepresentation.class)</code>.
+ *
+ * @param clickedRepresentationName
+ * Representation name where to in contextual menu.
+ * @return UI representation builder
+ */
+ public ItemChoice<UITreeRepresentation> newTreeRepresentation(final String clickedRepresentationName) {
+ return new UINewRepresentationBuilder<UITreeRepresentation>(clickedRepresentationName, UITreeRepresentation.class);
+ }
+
+ /**
+ * Open the representation adding wizard to create a new local semantic
+ * resource and add it to the current session or add a existing one.
+ *
+ * @return UIAddLocalSemanticResourceWizardUIWrapper a UI wrapper to the
+ * Wizard to add semantic resource
+ */
+ public UIAddLocalSemanticResourceWizardUIWrapper addLocalSemanticResource() {
+ return new UIAddLocalSemanticResourceWizardUIWrapper(this);
+ }
+
+ /**
+ * Get browser for this local session.
+ *
+ * @return Browser to browse local session.
+ */
+ public UILocalSessionBrowser getLocalSessionBrowser() {
+ return new UILocalSessionBrowser(getRepresentationsFileTreeItem());
+ }
+
+ private String getLocalSessionNodeLabel() {
+ if (isTransient()) {
+ return modelResource.getName();
+ }
+ return sessionResource.getName();
+ }
+
+ /**
+ * Returns the label associated to the selected semantic node.
+ *
+ * @param modelUIResource
+ * a {@link UIResource} corresponding to a semantic resource
+ *
+ * @return the label associated to the selected semantic node
+ */
+ protected String getSemanticResourceNodeLabel(UIResource modelUIResource) {
+ String semanticResourceNodeLabel = null;
+ if (isTransient()) {
+ // transient session case
+ semanticResourceNodeLabel = modelUIResource.getName();
+ } else if (isFirstSemanticResourceShared()) {
+ Resource semanticResource = getCorrespondingResource(modelUIResource, openedSession.getSemanticResources());
+ if (semanticResource != null) {
+ semanticResourceNodeLabel = modelUIResource.getName() + " - [" + semanticResource.getURI() + "]";
+ }
+ } else {
+ semanticResourceNodeLabel = modelUIResource.getName() + " - [platform:/resource/" + modelResource.getProject().getName() + UILocalSession.SEPARATOR + modelUIResource.getLongName() + "]";
+ }
+ return semanticResourceNodeLabel;
+ }
+
+ private Resource getCorrespondingResource(UIResource modelUIResource, Collection<Resource> resources) {
+ Resource correspondingResource = null;
+ for (Resource resource : resources) {
+ if (modelUIResource.getName().equals(resource.getURI().lastSegment())) {
+ correspondingResource = resource;
+ break;
+ }
+ }
+ return correspondingResource;
+ }
+
+ private boolean isTransient() {
+ return this.openedSession != null && this.openedSession.getSessionResource() != null && new URIQuery(this.openedSession.getSessionResource().getURI()).isInMemoryURI();
+ }
+
+ private boolean isFirstSemanticResourceShared() {
+ boolean isFirstSemanticResourceShared = new URIQuery(openedSession.getSemanticResources().iterator().next().getURI()).isCDOURI();
+ return isFirstSemanticResourceShared;
+ }
+
+ /**
+ * Returns the UIResource associated to this Session.
+ *
+ * @return the UIResource associated to this Session
+ */
+ public UIResource getSessionResource() {
+ return sessionResource;
+ }
+
+ /**
+ * Close <strong>unsaved</strong> session.
+ *
+ * @param save
+ * <code>true</code> if session has to be saved before closing.
+ */
+ public void close(final boolean save) {
+ if (isDirty()) {
+ close();
+ final SWTBotButton button;
+ if (save) {
+ button = bot.button("Yes");
+ } else {
+ button = bot.button("No");
+ }
+ bot.waitUntil(new ItemEnabledCondition(button));
+ SWTBotShell saveShell = bot.shell("Save");
+ button.click();
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses(saveShell));
+
+ bot.waitUntil(new SessionClosedCondition(getOpenedSession()));
+ } else {
+ closeNoDirty();
+ }
+ }
+
+ /**
+ * Verify that session is dirty.
+ *
+ * @return true if session is dirty
+ */
+ public boolean isDirty() {
+ boolean isDirty = false;
+ if (openedSession == null || SessionStatus.DIRTY.equals(openedSession.getStatus())) {
+ isDirty = true;
+ }
+ return isDirty;
+ }
+
+ /**
+ * Close session which is not dirty.
+ */
+ public void closeNoDirty() {
+ Assert.assertFalse("The session is not expected to be dirty", isDirty());
+ close();
+ bot.waitUntil(new SessionClosedCondition(getOpenedSession()));
+ }
+
+ /**
+ * Refresh the content of the session displayed in Model Explorer.
+ */
+ public void refresh() {
+ final SWTBotTreeItem rootTreeItem = getRootSessionTreeItem().select();
+ SWTBotUtils.clickContextMenu(rootTreeItem, "Refresh");
+ SWTBotUtils.waitAllUiEvents();
+ }
+
+ /**
+ * Close the current session.
+ */
+ protected void close() {
+ final SWTBotTreeItem rootTreeItem = getRootSessionTreeItem().select();
+ if (getOpenedSession().isOpen()) {
+ if (isModelingProject()) {
+ SWTBotUtils.clickContextMenu(rootTreeItem, "Close Project");
+ SWTBotUtils.waitAllUiEvents();
+ } else {
+ SWTBotUtils.clickContextMenu(rootTreeItem, "Close");
+ SWTBotUtils.waitAllUiEvents();
+ }
+ }
+ }
+
+ /**
+ * Close session and discard changes.
+ */
+ public void closeAndDiscardChanges() {
+ close(false);
+ }
+
+ /**
+ * Save session.
+ *
+ * @return Current {@link UILocalSession}
+ */
+ public UILocalSession save() {
+ final SWTBotTreeItem rootTreeItem = getRootSessionTreeItem().select();
+ if (getOpenedSession().getStatus() == SessionStatus.DIRTY) {
+ SWTBotUtils.clickContextMenu(rootTreeItem, "Save");
+ SWTBotUtils.waitProgressMonitorClose("Progress Information");
+ bot.waitUntil(new SessionSavedCondition(getOpenedSession()), 2 * SWTBotPreferences.TIMEOUT);
+ }
+ return this;
+ }
+
+ /**
+ * Get {@link SWTBotTree} for the current local session.
+ *
+ * @return Current {@link SWTBotTree}
+ */
+ public SWTBotTree getSWTBotTree() {
+ return modelContentView.bot().tree();
+ }
+
+ /**
+ * Get root of session tree.
+ *
+ * @return Root of session tree.
+ */
+ public SWTBotTreeItem getRootSessionTreeItem() {
+ selectView();
+ SWTBotTreeItem treeItem = null;
+ if (isModelingProject()) {
+ treeItem = sessionResource.getProject().getProjectTreeItem();
+ } else {
+ treeItem = getRepresentationsFileTreeItem();
+ }
+ return treeItem;
+ }
+
+ /**
+ * Get the {@link SWTBotTreeItem} representing the representations file.
+ *
+ * @return the {@link SWTBotTreeItem} representing the representations file
+ */
+ public SWTBotTreeItem getRepresentationsFileTreeItem() {
+ SWTBotTreeItem treeItem = null;
+ selectView();
+ final SWTBotTree modelContentTree = getSWTBotTree();
+
+ bot.waitUntil(new ItemEnabledCondition(modelContentTree));
+
+ SWTBotTreeItem[] allItems = modelContentTree.getAllItems();
+ String localSessionNodeLabel = getLocalSessionNodeLabel();
+
+ treeItem = findAndExpand(allItems, localSessionNodeLabel);
+ return treeItem.expand();
+ }
+
+ /**
+ * Tells if this session is a Modeling Project.
+ *
+ * @return true if it is a Modeling Project
+ */
+ public boolean isModelingProject() {
+ boolean isModelingProject = false;
+ String projectName = sessionResource.getProject().getName();
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ try {
+ isModelingProject = project.exists() && project.hasNature(ModelingProject.NATURE_ID);
+ } catch (CoreException e) {
+ isModelingProject = false;
+ }
+ return isModelingProject;
+ }
+
+ private SWTBotTreeItem findAndExpand(SWTBotTreeItem[] allItems, String localSessionNodeLabel) {
+ SWTBotTreeItem treeItem = null;
+ if (localSessionNodeLabel == null) {
+ return treeItem;
+ }
+
+ String dirtylocalSessionNodeLabel = "*" + localSessionNodeLabel;
+ for (SWTBotTreeItem item : allItems) {
+ String text = item.getText();
+
+ if (item.isEnabled() && localSessionNodeLabel.equals(text) || dirtylocalSessionNodeLabel.equals(text)) {
+ treeItem = item;
+ } else {
+ boolean oldExpanded = item.isExpanded();
+ item.expand();
+ treeItem = findAndExpand(item.getItems(), localSessionNodeLabel);
+ if (treeItem == null && !oldExpanded) {
+ item.collapse();
+ }
+ }
+ if (treeItem != null) {
+ break;
+ }
+ }
+ return treeItem;
+ }
+
+ /**
+ * Allow to change viewpoints selection.
+ *
+ * This method opens the Viewpoints selection dialog from the contextual
+ * menu on the session item.
+ *
+ * @param viewpointsToSelect
+ * New viewpoints to select
+ * @param viewpointsToDeselect
+ * new viewpoints to deselect
+ * @return This
+ */
+ public UILocalSession changeViewpointSelection(final Set<String> viewpointsToSelect, final Set<String> viewpointsToDeselect) {
+ final SWTBotTreeItem rootTreeItem = getRootSessionTreeItem().select();
+ SWTBotUtils.clickContextMenu(rootTreeItem, ViewpointSelectionDialog.VIEWPOINT_DIALOG_NAME);
+ return changeViewpointSelectionInOpenedSelectionDialog(viewpointsToSelect, viewpointsToDeselect);
+ }
+
+ /**
+ * Allow to change viewpoints selection.
+ *
+ * This method can be used when the selection dialog has been opened
+ * elsewhere (from contextual menu, after session creation wizard, ...).
+ *
+ * @param viewpointsToSelect
+ * New viewpoints to select
+ * @param viewpointsToDeselect
+ * new viewpoints to deselect
+ * @return This
+ */
+ public UILocalSession changeViewpointSelectionInOpenedSelectionDialog(final Set<String> viewpointsToSelect, final Set<String> viewpointsToDeselect) {
+ new ViewpointSelectionDialog(bot).selectViewpoint(viewpointsToSelect, viewpointsToDeselect);
+ return this;
+ }
+
+ /**
+ * Export this Modeling Project to a repo and create a Shared Modeling
+ * Project.
+ *
+ * @return the shared modeling project
+ */
+ public UILocalSession export() {
+ return export(false, true, false);
+ }
+
+ /**
+ * Export this Modeling Project to a repo and create a Shared Modeling
+ * Project.
+ *
+ * @param overrideExistingResources
+ * specify if the export can override existing resources
+ * @param connectToExportedProject
+ * specify if a shared modeling project must be created
+ * @param exportReferencedWorkspaceImages
+ * specify if we must export referenced workspace image
+ * @return the shared modeling project, or null if connectToExportedProject
+ * was at false
+ */
+ public UILocalSession export(boolean overrideExistingResources, boolean connectToExportedProject, boolean exportReferencedWorkspaceImages) {
+ return export(overrideExistingResources, connectToExportedProject, exportReferencedWorkspaceImages, "localhost", "2037", "collab");
+ }
+
+ /**
+ * Export this Modeling Project to a repo and create a Shared Modeling
+ * Project.
+ *
+ * @param overrideExistingResources
+ * specify if the export can override existing resources
+ * @param connectToExportedProject
+ * specify if a shared modeling project must be created
+ * @param exportReferencedWorkspaceImages
+ * specify if we must export referenced workspace image
+ * @param serverLocation
+ * the server location where to export
+ * @param serverPortNumber
+ * the server port number where to export
+ * @param repositoryName
+ * the repository name where to export
+ * @return the shared modeling project, or null if connectToExportedProject
+ * was at false
+ */
+ public UILocalSession export(boolean overrideExistingResources, boolean connectToExportedProject, boolean exportReferencedWorkspaceImages, String serverLocation, String serverPortNumber,
+ String repositoryName) {
+ SWTBotTreeItem projectTreeItem = getSessionResource().getProject().getProjectTreeItem();
+ projectTreeItem.select();
+ SWTBotUtils.clickContextMenu(projectTreeItem, "Export...");
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive("Export"));
+ SWTBotShell activeShell = bot.activeShell();
+ SWTBotUtils.waitAllUiEvents();
+ SWTBot exportWizardBot = activeShell.bot();
+ String exportWizardName = "Shared Modeling Project from Local";
+ exportWizardBot.text().setText(exportWizardName);
+ SWTBotTreeItem treeItem = exportWizardBot.tree().getTreeItem("Sirius");
+ bot.waitUntil(new TreeItemExpanded(treeItem, exportWizardName));
+ treeItem.getNode(exportWizardName).select();
+ exportWizardBot.button("Next >").click();
+ if (overrideExistingResources) {
+ exportWizardBot.button("Override existing resources").click();
+ }
+ if (!connectToExportedProject) {
+ exportWizardBot.button("Connect to the exported project").click();
+ }
+ if (!exportReferencedWorkspaceImages) {
+ exportWizardBot.checkBox("Export referenced workspace images").click();
+ }
+ exportWizardBot.button("Next >").click();
+ exportWizardBot.text(0).setText(serverLocation);
+ exportWizardBot.text(1).setText(serverPortNumber);
+ exportWizardBot.text(2).setText(repositoryName);
+ exportWizardBot.button("Test connection").click();
+ SWTBotButton finishButton = exportWizardBot.button("Finish");
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.widgetIsEnabled(finishButton));
+ finishButton.click();
+ if (connectToExportedProject) {
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive("Connect to the Exported Project"), 5 * SWTBotPreferences.TIMEOUT);
+ SWTBot connectWizardBot = bot.activeShell().bot();
+ finishButton = connectWizardBot.button("Finish");
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.widgetIsEnabled(finishButton));
+ finishButton.click();
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellIsActive(ViewpointSelectionDialog.VIEWPOINT_DIALOG_NAME));
+ SWTBotShell viewpointSelectionShell = bot.activeShell();
+ SWTBot viewpointSelectionBot = viewpointSelectionShell.bot();
+ Collection<Viewpoint> selectedViewpoints = getOpenedSession().getSelectedViewpoints(false);
+ for (Viewpoint locallySelectedViewpoint : selectedViewpoints) {
+ for (int i = 0; i < viewpointSelectionBot.table().rowCount(); i++) {
+ SWTBotTableItem tableItem = viewpointSelectionBot.table().getTableItem(i);
+ if (locallySelectedViewpoint.getName().equals(tableItem.getText(2))) {
+ viewpointSelectionBot.table().click(i, 0);
+ break;
+ }
+ }
+ }
+ viewpointSelectionBot.button("OK").click();
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses(viewpointSelectionShell));
+ }
+ bot.waitUntil(org.eclipse.swtbot.swt.finder.waits.Conditions.shellCloses(activeShell));
+ UIProject sharedModelingProject = new UIProject(getSessionResource().getProject().getName() + ".shared");
+ UIResource sharedSessionResource = new UIResource(sharedModelingProject, sharedModelingProject.getName() + "." + SiriusUtil.SESSION_RESOURCE_EXTENSION);
+ return new UILocalSession(sharedSessionResource);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilder.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilder.java
new file mode 100644
index 0000000000..73e48c7951
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilder.java
@@ -0,0 +1,174 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.sirius.tests.swtbot.support.api.business.UINewRepresentationBuilderFlow.EndFlow;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UINewRepresentationBuilderFlow.ItemChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UINewRepresentationBuilderFlow.NameChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.ItemEnabledCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerHelper;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.tests.swtbot.support.utils.business.UIRepresentationUtils;
+import org.eclipse.sirius.ui.tools.api.Messages;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotText;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Builder tool to create "New representations".
+ *
+ * @author dlecan
+ * @param <R>
+ * Type of representation.
+ */
+public class UINewRepresentationBuilder<R extends AbstractUIRepresentation<?>> implements ItemChoice<R>, NameChoice<R>, EndFlow<R> {
+
+ private final String representationNameToClick;
+
+ private String newRepresentationName;
+
+ private final SWTWorkbenchBot mainBot;
+
+ private SWTBotShell shell;
+
+ private SWTBot shellBot;
+
+ private final Class<R> representationType;
+
+ /**
+ * Constructor.
+ *
+ * @param clickedRepresentationName
+ * Representation name clicked in contextual menu
+ * @param representationType
+ * Java type of representation.
+ */
+ public UINewRepresentationBuilder(final String clickedRepresentationName, final Class<R> representationType) {
+ this.mainBot = new SWTWorkbenchBot();
+ this.representationNameToClick = clickedRepresentationName;
+ this.representationType = representationType;
+ }
+
+ /**
+ * On method.
+ *
+ * @param treeItem
+ * Tree item on which you want to create new representation.
+ * @return Current {@link UINewRepresentationBuilder}
+ */
+ @Override
+ public NameChoice<R> on(final SWTBotTreeItem treeItem) {
+ treeItem.select();
+ SWTBotUtils.clickContextMenu(treeItem, representationNameToClick);
+
+ shell = mainBot.shell(Messages.createRepresentationInputDialog_Title);
+ shell.activate();
+
+ shellBot = new SWTBot(shell.widget);
+
+ return this;
+ }
+
+ /**
+ * withName method.
+ *
+ * @param name
+ * name of the new representation.
+ * @return Current {@link UINewRepresentationBuilder}
+ */
+ @Override
+ public EndFlow<R> withName(final String name) {
+ newRepresentationName = name;
+ final SWTBotText text = shellBot.text();
+ text.setText(newRepresentationName);
+ return this;
+ }
+
+ /**
+ * New representation with default name.
+ *
+ * @return Current {@link UINewRepresentationBuilder}
+ */
+ @Override
+ public EndFlow<R> withDefaultName() {
+ final SWTBotText text = shellBot.text();
+ return withName(text.getText());
+ }
+
+ /**
+ * Finish creation with click on "ok".
+ *
+ * @return Representation.
+ */
+ @Override
+ public R ok() {
+ return ok(false);
+ }
+
+ /**
+ * Finish creation with click on "ok".
+ *
+ * @param disableSnapToGridOnThisEditor
+ * true if the snapToGrid must be disable for this editor, false
+ * otherwise
+ * @return Representation.
+ */
+ @Override
+ public R ok(boolean disableSnapToGridOnThisEditor) {
+ final SWTBotButton ok = shellBot.button("OK");
+ shellBot.waitUntilWidgetAppears(new ItemEnabledCondition(ok));
+ ok.click();
+ SWTBotUtils.waitProgressMonitorClose("Progress Information");
+ finish();
+
+ // Get the corresponding SWtBotEditor
+ SWTBotDesignerEditor swtBotEditor = SWTBotDesignerHelper.getDesignerEditor(newRepresentationName);
+ if (swtBotEditor != null && disableSnapToGridOnThisEditor) {
+ swtBotEditor.disableSnapToGrid();
+ }
+ return UIRepresentationUtils.buildRepresentation(null, getRealNewRepresentationName(), getRepresentationType());
+ }
+
+ /**
+ * Finish creation with click on "cancel".
+ */
+ @Override
+ public void cancel() {
+ final SWTBotButton cancel = shellBot.button("Cancel");
+ shellBot.waitUntilWidgetAppears(new ItemEnabledCondition(cancel));
+ cancel.click();
+ finish();
+ }
+
+ private void finish() {
+ mainBot.waitUntil(Conditions.shellCloses(shell));
+ mainBot.sleep(500);
+ }
+
+ private String getRealNewRepresentationName() {
+ String result;
+ if (newRepresentationName == null) {
+ result = representationNameToClick;
+ } else {
+ result = newRepresentationName;
+ }
+ return result;
+ }
+
+ private Class<R> getRepresentationType() {
+ return representationType;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilderFlow.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilderFlow.java
new file mode 100644
index 0000000000..1b00cb408f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UINewRepresentationBuilderFlow.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Class which stores flow declaration for {@link UINewRepresentationBuilder}.
+ *
+ * @author dlecan
+ */
+public class UINewRepresentationBuilderFlow {
+
+ /**
+ * Choice of item.
+ *
+ * @author dlecan
+ * @param <R>
+ * Type of UI representation.
+ */
+ public interface ItemChoice<R extends AbstractUIRepresentation<?>> {
+ /**
+ * On method.
+ *
+ * @param treeItem
+ * Tree item on which you want to create new representation.
+ * @return Current {@link NameChoice}
+ */
+ NameChoice<R> on(final SWTBotTreeItem treeItem);
+ }
+
+ /**
+ * Choice of name.
+ *
+ * @param <R>
+ * Type of UI representation
+ *
+ * @author dlecan
+ */
+ public interface NameChoice<R extends AbstractUIRepresentation<?>> {
+
+ /**
+ * withName method.
+ *
+ * @param name
+ * name of the new representation.
+ * @return Current {@link EndFlow}
+ */
+ EndFlow<R> withName(final String name);
+
+ /**
+ * New representation with default name.
+ *
+ * @return Current {@link EndFlow}
+ */
+ EndFlow<R> withDefaultName();
+
+ }
+
+ /**
+ * End of flow.
+ *
+ * @param <R>
+ * Type of UI representation
+ *
+ * @author dlecan
+ */
+ public interface EndFlow<R extends AbstractUIRepresentation<?>> {
+
+ /**
+ * Finish creation with click on "ok".
+ *
+ * @return Representation.
+ */
+ R ok();
+
+ /**
+ * Finish creation with click on "ok".
+ *
+ * @param disableSnapToGridOnThisEditor
+ * true if the snapToGrid must be disable for this editor,
+ * false otherwise
+ *
+ * @return Representation.
+ */
+ R ok(boolean disableSnapToGridOnThisEditor);
+
+ /**
+ * Finish creation with click on "cancel".
+ */
+ void cancel();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIPerspective.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIPerspective.java
new file mode 100644
index 0000000000..79f41e858f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIPerspective.java
@@ -0,0 +1,367 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionListener;
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.sirius.business.api.session.SessionManagerListener;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.SessionChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.TreeItemAvailableCondition;
+import org.eclipse.sirius.tests.swtbot.support.internal.business.UISessionCreationWizard;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.viewpoint.SiriusPlugin;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Object to manage graphical operations on perspectives.
+ *
+ * @author dlecan
+ */
+public class UIPerspective {
+
+ private static final String VIEWPOINT = "Sirius";
+
+ // Seconds
+ private static final int TIMEOUT = 60;
+
+ private static final String WIZARDS_LIST_TITLE = "New";
+
+ private static final String REPRESENTATIONS_FILE_LABEL = "Representations File";
+
+ /**
+ * Inner session listener to track session changes
+ *
+ * @author dlecan
+ */
+ private final class OpenedSessionListener extends SessionManagerListener.Stub {
+
+ private final CountDownLatch sessionOpenedSignal;
+
+ private Session openedSession;
+
+ /**
+ * @param sessionOpenedSignal
+ */
+ private OpenedSessionListener(final CountDownLatch sessionOpenedSignal) {
+ this.sessionOpenedSignal = sessionOpenedSignal;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyAddSession(final Session newSession) {
+ openedSession = newSession;
+ sessionOpenedSignal.countDown();
+ }
+
+ /**
+ * Returns the openedSession.
+ *
+ * @return The openedSession.
+ */
+ public Session getOpenedSession() {
+ return openedSession;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notify(final Session updated, final int notification) {
+ switch (notification) {
+ case SessionListener.OPENED:
+ if (openedSession == updated) {
+ sessionOpenedSignal.countDown();
+ }
+ break;
+ case SessionListener.REPRESENTATION_CHANGE:
+ openedSession = updated;
+ // Twice here
+ sessionOpenedSignal.countDown();
+ sessionOpenedSignal.countDown();
+ break;
+ default:
+ // Nothing
+ break;
+ }
+ }
+ }
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Constructor.
+ *
+ * @param bot
+ * SWTBot
+ */
+ public UIPerspective(final SWTWorkbenchBot bot) {
+ this.bot = bot;
+ }
+
+ /**
+ * Create a project.
+ *
+ * @param projectName
+ * name of the created project
+ * @return Current {@link UIProject}.
+ */
+ public UIProject createProject(final String projectName) {
+ final IProjectDescription projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
+ final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ try {
+ if (!project.exists()) {
+ project.create(projectDescription, new NullProgressMonitor());
+ }
+ project.open(new NullProgressMonitor());
+ } catch (final CoreException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ return new UIProject(projectName);
+ }
+
+ /**
+ * Delete the project.
+ *
+ * @param project
+ * name of the project to delete.
+ */
+ public void deleteProject(final UIProject project) {
+ deleteProject(project.getName());
+ }
+
+ /**
+ * Delete the project.
+ *
+ * @param projectName
+ * name of the project to delete.
+ */
+ public void deleteProject(final String projectName) {
+ final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ try {
+ if (project.exists()) {
+ project.delete(true, true, new NullProgressMonitor());
+ }
+ } catch (final CoreException e) {
+ // Propagate as runtime exception
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Open the session creation wizard.
+ *
+ * @return Current {@link UIPerspective}.
+ */
+ public SessionChoice openSessionCreationWizard() {
+
+ openRepresentationsFileWizard();
+
+ return new UISessionCreationWizard();
+ }
+
+ /**
+ * Open the session creation wizard from a specific semantic resource.
+ *
+ * @param uiResource
+ * {@link UIResource} to use to openthe wizard.
+ * @return Current {@link UIPerspective}.
+ */
+ public SessionChoice openSessionCreationWizardFromSemanticResource(final UIResource uiResource) {
+
+ uiResource.getProject().selectResource(uiResource);
+
+ openRepresentationsFileWizard();
+
+ return new UISessionCreationWizard(uiResource);
+
+ }
+
+ /**
+ * Opens the "New Representation Files" wizard through the File > New >
+ * Other... menu.
+ */
+ private void openRepresentationsFileWizard() {
+ bot.menu("File").menu(UIPerspective.WIZARDS_LIST_TITLE).menu("Other...").click();
+
+ SWTBot wizardListBot = bot.activeShell().bot();
+ wizardListBot.waitUntil(Conditions.shellIsActive(UIPerspective.WIZARDS_LIST_TITLE));
+
+ wizardListBot.text().setText(UIPerspective.REPRESENTATIONS_FILE_LABEL);
+
+ SWTBotTree wizardsTree = wizardListBot.tree();
+
+ wizardsTree.setFocus();
+
+ SWTBotTreeItem viewpointCategory = null;
+ try {
+ viewpointCategory = wizardsTree.getTreeItem(UIPerspective.VIEWPOINT);
+ } catch (WidgetNotFoundException e) {
+ // Accessing the tree item can fail when launching the test suite
+ // with jenkins. Adding the following condition in a catch section
+ // seems to fix it.
+ bot.waitUntil(new TreeItemAvailableCondition(wizardsTree, UIPerspective.VIEWPOINT, true));
+ viewpointCategory = wizardsTree.getTreeItem(UIPerspective.VIEWPOINT);
+ }
+ viewpointCategory.expand();
+
+ SWTBotTreeItem representationsFileNode = viewpointCategory.getNode(UIPerspective.REPRESENTATIONS_FILE_LABEL);
+
+ representationsFileNode.select();
+
+ wizardListBot.button("Next >").click();
+
+ bot.waitUntil(Conditions.shellIsActive("New Representations File"));
+ }
+
+ /**
+ * Open directly a session.
+ *
+ * @param uiLocalSessionResource
+ * <code>.aird</code> file to use to open the local session.
+ * @return UI local session.
+ */
+ public UILocalSession openSessionFromFile(final UIResource uiLocalSessionResource) {
+ return openSessionFromFile(uiLocalSessionResource, false);
+ }
+
+ /**
+ * Open directly a session.
+ *
+ * @param uiLocalSessionResource
+ * <code>.aird</code> file to use to open the local session.
+ * @param useMoreThanOneSemanticFiles
+ * true if the session uses more than one semantic files
+ * (fragmented file, more complex use case, ...).
+ * @return UI local session.
+ */
+ public UILocalSession openSessionFromFile(final UIResource uiLocalSessionResource, final boolean useMoreThanOneSemanticFiles) {
+ // Need to wait later opening of session.
+ final SessionManager sessionManager = SessionManager.INSTANCE;
+
+ final CountDownLatch sessionOpenedSignal = new CountDownLatch(2);
+
+ final OpenedSessionListener openedSessionListener = new OpenedSessionListener(sessionOpenedSignal);
+ sessionManager.addSessionsListener(openedSessionListener);
+
+ // Open session
+ uiLocalSessionResource.openSession();
+
+ SWTBotUtils.waitProgressMonitorClose("Open session");
+
+ try {
+ // Wait until session is opened.
+ final boolean awaitRes = sessionOpenedSignal.await(UIPerspective.TIMEOUT, TimeUnit.SECONDS);
+
+ Session openedSession;
+ if (awaitRes) {
+ openedSession = openedSessionListener.getOpenedSession();
+ } else {
+ Assert.assertTrue("No session is opened!", sessionManager.getSessions().size() > 0);
+ // There is a problem with listeners
+ // Try to get "last" session anyway
+ // This may lead to unexpected behavior as we are not sure to
+ // get the expected session !
+ openedSession = Lists.newLinkedList(sessionManager.getSessions()).getLast();
+ SiriusPlugin.getDefault().warning("Session is graphically opened but session listener was not properly notified.", null);
+ }
+
+ final Collection<Resource> semanticResources = openedSession.getSemanticResources();
+
+ if (useMoreThanOneSemanticFiles) {
+ MatcherAssert.assertThat("Semantic resource not found", semanticResources.size(), Matchers.not(Matchers.is(0)));
+ } else {
+ // Only one semantic resource should be found !
+ if (semanticResources.size() > 1) {
+ StringBuffer names = new StringBuffer();
+ for (Resource resource : semanticResources) {
+ names.append(resource.getURI().toPlatformString(true));
+ names.append(", ");
+ }
+ names.delete(names.length() - 2, names.length());
+ Assert.fail("Too many semantic resources, only one semantic resource is expected. List of semantic resources: " + names);
+ }
+ }
+
+ final Resource semanticResource = semanticResources.iterator().next();
+
+ final UIResource uiSemanticResource = UIResource.createFromResource(semanticResource);
+
+ return new UILocalSession(uiSemanticResource, uiLocalSessionResource, openedSession);
+
+ } catch (final InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ sessionManager.removeSessionsListener(openedSessionListener);
+ }
+
+ }
+
+ /**
+ * Get the opened session.
+ *
+ * @param uiResource
+ * the aird resource (it could not exist)
+ * @return UI local session.
+ */
+ public UILocalSession getOpenedSession(final UIResource uiResource) {
+
+ final SessionManager sessionManager = SessionManager.INSTANCE;
+
+ bot.waitUntil(new DefaultCondition() {
+
+ @Override
+ public boolean test() throws Exception {
+ return !sessionManager.getSessions().isEmpty();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "no session have been created";
+ }
+ });
+
+ final Session session = sessionManager.getSessions().iterator().next();
+
+ final Collection<Resource> semanticResources = session.getSemanticResources();
+
+ final Resource semanticResource = semanticResources.iterator().next();
+ final UIResource uiSemanticResource = UIResource.createFromResource(semanticResource);
+
+ return new UILocalSession(uiSemanticResource, uiResource, session);
+
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIProject.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIProject.java
new file mode 100644
index 0000000000..978da98030
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIProject.java
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.sirius.tests.swtbot.support.api.condition.TreeItemContainsAtLeastOneChild;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.TreeItemExpanded;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.TreeItemSelected;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.sirius.ui.tools.api.views.modelexplorerview.IModelExplorerView;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
+
+/**
+ * Object to manage graphical projects.
+ *
+ * @author dlecan
+ */
+public class UIProject {
+
+ private final String name;
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Constructor.
+ *
+ * @param pName
+ * Project name
+ */
+ public UIProject(final String pName) {
+ bot = new SWTWorkbenchBot();
+ name = pName;
+
+ }
+
+ /**
+ * Open the project.
+ */
+ public void open() {
+ SWTBot projectExplorerBot = bot.viewById(IModelExplorerView.ID).bot();
+ SWTBotTree projectExplorerTree = projectExplorerBot.tree();
+ projectExplorerTree.setFocus();
+ SWTBotTreeItem treeItem = projectExplorerTree.getTreeItem(getName());
+ treeItem.select();
+ bot.waitUntil(new TreeItemSelected(treeItem));
+ SWTBotUtils.clickContextMenu(treeItem, "Open Project");
+ SWTBotUtils.waitAllUiEvents();
+ }
+
+ /**
+ * Delete resource.
+ *
+ * @param resource
+ * Path to resource to delete (with / separator)
+ * @return Current {@link UIProject}
+ */
+ public UIProject deleteResource(final UIResource resource) {
+ SWTBotTreeItem treeItem = getProjectTreeItem();
+
+ try {
+
+ for (final String node : resource.getNodePath()) {
+ treeItem = treeItem.expandNode(node);
+ }
+
+ treeItem.setFocus();
+ treeItem.select().contextMenu("Delete").click();
+ final SWTBotShell shell = bot.shell("Delete Resources");
+ shell.activate();
+ bot.button("OK").click();
+ bot.waitUntil(Conditions.shellCloses(shell));
+ bot.sleep(500);
+ } catch (final TimeoutException e) {
+ // do nothing
+ }
+
+ return this;
+ }
+
+ /**
+ * Get the {@link SWTBotTreeItem} for the project.
+ *
+ * @return the {@link SWTBotTreeItem} for the project
+ */
+ public SWTBotTreeItem getProjectTreeItem() {
+ final SWTBot projectExplorerBot = bot.viewById(IModelExplorerView.ID).bot();
+
+ final SWTBotTree projectExplorerTree = projectExplorerBot.tree();
+ final SWTBotTreeItem treeItem = projectExplorerTree.getTreeItem(getName());
+
+ TreeItemExpanded treeItemExpanded = new TreeItemExpanded(treeItem, getName());
+ treeItem.expand();
+
+ bot.waitUntil(treeItemExpanded);
+
+ return treeItem;
+ }
+
+ /**
+ * Select a UI resource.
+ *
+ * @param uiResource
+ * UI resource to select.
+ * @return Current {@link UIProject}.
+ */
+ public UIProject selectResource(final UIResource uiResource) {
+
+ final SWTBotTreeItem treeItem = getUIItemFromResource(uiResource);
+ treeItem.setFocus();
+ treeItem.select();
+ bot.waitUntil(new TreeItemSelected(treeItem));
+ return this;
+ }
+
+ /**
+ * Return ui tree item corresponding to a UI resource in a project.
+ *
+ * @param uiResource
+ * UI resource to select.
+ * @return UI tree item.
+ */
+ public SWTBotTreeItem getUIItemFromResource(final UIResource uiResource) {
+ SWTBotTreeItem treeItem = getProjectTreeItem();
+
+ for (final String node : uiResource.getNodePath()) {
+ treeItem = treeItem.expandNode(node);
+ bot.waitUntil(new TreeItemExpanded(treeItem, node));
+
+ }
+ // Wait that the parent contains at least one child (indeed sometimes,
+ // the TreeItemExpanded is OK but the tree is not really expanded).
+ bot.waitUntil(new TreeItemContainsAtLeastOneChild(treeItem));
+ try {
+ treeItem = treeItem.getNode(uiResource.getName());
+ } catch (WidgetNotFoundException e) {
+ // It should be here (just wait 2 seconds)
+ bot.sleep(2000);
+ treeItem = treeItem.getNode(uiResource.getName());
+ }
+
+ treeItem.setFocus();
+ treeItem.select();
+ bot.waitUntil(new TreeItemSelected(treeItem));
+ return treeItem;
+ }
+
+ /**
+ * Double-click on a resource.
+ *
+ * @param uiResource
+ * Resource where to double-click.
+ * @param contextualMenuLabel
+ * Contextual menu label.
+ * @return Current {@link UIProject}.
+ */
+ public UIProject mouseRigthClickOnResource(final UIResource uiResource, String contextualMenuLabel) {
+ final SWTBotTreeItem treeItem = getUIItemFromResource(uiResource);
+ SWTBotUtils.clickContextMenu(treeItem, contextualMenuLabel);
+ return this;
+ }
+
+ /**
+ * Double-click on a resource.
+ *
+ * @param uiResource
+ * Resource where to double-click.
+ * @return Cuurent {@link UIProject}.
+ */
+ public UIProject mouseDoubleClickOnResource(final UIResource uiResource) {
+ final SWTBotTreeItem treeItem = getUIItemFromResource(uiResource);
+ treeItem.doubleClick();
+ return this;
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return The name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Convert the current project to a Modeling Project using the configure
+ * contextual menu.
+ */
+ public void convertToModelingProject() {
+ getProjectTreeItem().select();
+ SWTBotUtils.clickContextMenu(getProjectTreeItem(), "Convert to Modeling Project");
+ }
+
+ /**
+ * Save the Modeling Project.
+ */
+ public void save() {
+ SWTBot projectExplorerBot = bot.viewById(IModelExplorerView.ID).bot();
+ SWTBotTree projectExplorerTree = projectExplorerBot.tree();
+ SWTBotTreeItem treeItem = projectExplorerTree.getTreeItem("*" + getName());
+ SWTBotUtils.clickContextMenu(treeItem, "Save");
+ }
+
+ /**
+ * Select the project.
+ */
+ public void select() {
+ getProjectTreeItem().select();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIResource.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIResource.java
new file mode 100644
index 0000000000..afa0907c73
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UIResource.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.sirius.ui.tools.internal.actions.session.OpenSessionAction;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.junit.Assert;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Object to manage graphical resources.
+ *
+ * @author dlecan
+ */
+public class UIResource {
+
+ private final UIProject project;
+
+ private final String path;
+
+ private final List<String> nodePath;
+
+ private final String name;
+
+ /**
+ * Constructor for a resource at the root of the project.
+ *
+ * @param pUIProject
+ * Project where is located resource.
+ * @param name
+ * Name of resource.
+ */
+ public UIResource(final UIProject pUIProject, final String name) {
+ this(pUIProject, "", name);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pUIProject
+ * Project where is located resource.
+ * @param pPath
+ * Path in the project to the resource.
+ * @param name
+ * Name of resource.
+ */
+ public UIResource(final UIProject pUIProject, final String pPath, final String name) {
+ project = pUIProject;
+ path = pPath;
+ this.name = name;
+ if (pPath == null || pPath.length() == 0) {
+ nodePath = Lists.newArrayList();
+ } else {
+ nodePath = Lists.newArrayList(pPath.split("/"));
+ }
+ }
+
+ /**
+ * Create {@link UIResource} from {@link Resource}.
+ *
+ * @param resource
+ * Resource to use.
+ * @return New {@link UIResource}.
+ */
+ public static UIResource createFromResource(final Resource resource) {
+ return UIResource.createFromURI(resource.getURI());
+ }
+
+ /**
+ * Create {@link UIResource} from {@link URI} of a {@link Resource}.
+ *
+ * @param uri
+ * URi of resource to use.
+ * @return New {@link UIResource}.
+ */
+ public static UIResource createFromURI(final URI uri) {
+ UIResource uiResource = null;
+
+ if (uri.isPlatform()) {
+ final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true)));
+ final IProject project = file.getProject();
+
+ // removeLastSegments meth. removes file name in relative path.
+ final String resourcePath = file.getProjectRelativePath().removeLastSegments(1).toOSString();
+
+ uiResource = new UIResource(new UIProject(project.getName()), resourcePath, file.getName());
+ }
+ return uiResource;
+ }
+
+ /**
+ * Returns the project.
+ *
+ * @return The project.
+ */
+ public UIProject getProject() {
+ return project;
+ }
+
+ /**
+ * Returns the path.
+ *
+ * @return The path.
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Returns the long name of this resource, including path and name, relative
+ * to {@link #getProject()} project.
+ *
+ * @return The long name of this resource.
+ */
+ public String getLongName() {
+ String longName = "";
+ final String separator = "/";
+ final String thePath = getPath();
+ if (!"".equals(thePath) && !separator.equals(thePath)) {
+ longName += getPath() + separator;
+ }
+ return longName + getName();
+ }
+
+ /**
+ * Returns the full path of this file (that path is relative to the
+ * containing workspace).
+ *
+ * @return a workspace relative path
+ */
+ public String getFullPath() {
+ return getProject().getName() + File.separator + getLongName();
+ }
+
+ /**
+ * Returns the nodePath.
+ *
+ * @return The nodePath.
+ */
+ public List<String> getNodePath() {
+ return nodePath;
+ }
+
+ /**
+ * Returns the name.
+ *
+ * @return The name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Launch to "Open Session" action on the file corresponding to this
+ * UIResource.
+ */
+ public void openSession() {
+ final IFile fileToOpen = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(getFullPath()));
+ if (!fileToOpen.exists()) {
+ Assert.fail("The session could not be open on " + fileToOpen.getFullPath() + ", because this file does not exist.");
+ }
+ UIThreadRunnable.syncExec(SWTUtils.display(), new VoidResult() {
+ @Override
+ public void run() {
+ OpenSessionAction action = new OpenSessionAction("Open session");
+ action.selectionChanged(new StructuredSelection(fileToOpen));
+ action.run();
+ }
+ });
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UISessionCreationWizardFlow.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UISessionCreationWizardFlow.java
new file mode 100644
index 0000000000..9fbd0f8234
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UISessionCreationWizardFlow.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+/**
+ * Class grouping every step of the workflow used during a session creation
+ * operation with the wizard.
+ *
+ * @author cbrun
+ *
+ */
+public class UISessionCreationWizardFlow {
+ /**
+ * Wizard page to decide to go with a new empty session, a session picking a
+ * semantic resource or a session using the already selected semantic
+ * resource.
+ *
+ * @author cbrun
+ *
+ */
+ public interface SessionChoice {
+ /**
+ * Decide to create an empty session.
+ *
+ * @return next step.
+ */
+ AirdPickingChoice emptySession();
+
+ /**
+ * Decide to pick a semantic resource.
+ *
+ * @return the next step.
+ */
+ SemanticModelPage fromSemanticResource();
+
+ /**
+ * decide to use the workspace selected semantic resource.
+ *
+ * @return the next step.
+ */
+ AirdPickingChoice fromAlreadySelectedSemanticResource();
+
+ /**
+ * Configure this {@link SessionChoice} to create a session resource in
+ * the uiProject.
+ *
+ * @param uiProject
+ * the ui wrapper of the project where the session resource
+ * should be created.
+ *
+ * @return self
+ */
+ SessionChoice in(UIProject uiProject);
+
+ }
+
+ /**
+ * Wizard page to pick a semantic resource.
+ *
+ * @author cbrun
+ *
+ */
+ public interface SemanticModelPage {
+ /**
+ * Select a semantic resource.
+ *
+ * @param res
+ * semantic resource to pick.
+ * @return the next step.
+ */
+ AirdPickingChoice select(UIResource res);
+
+ }
+
+ /**
+ * Wizard page to pick an .aird resource.
+ *
+ * @author cbrun
+ *
+ */
+ public interface AirdPickingChoice {
+ /**
+ * Select an Aird resource.
+ *
+ * @param res
+ * aird resource to select in the wizard.
+ * @return the next step.
+ */
+ WizardOk select(UIResource res);
+
+ /**
+ * consider the .aird file is the default one.
+ *
+ * @return the next step considering the .aird file will be the default
+ * one.
+ */
+ WizardOk withDefaultSessionName();
+
+ /**
+ * consider the .aird file is the default one.
+ *
+ * @return the created session wrapped in {@link UILocalSession}.
+ */
+ UILocalSession withDefaultSessionNameWithoutViewpointSelection();
+ }
+
+ /**
+ * The wizard is ok and the user might press finish.
+ *
+ * @author cbrun
+ *
+ */
+ public interface WizardOk {
+ /**
+ * end the wizard.
+ *
+ * @return the next step.
+ */
+ VpSelectionAfterWizard finish();
+ }
+
+ /**
+ * The viewpoints selection window poping up after the session creation
+ * wizard.
+ *
+ * @author cbrun
+ *
+ */
+ public interface VpSelectionAfterWizard {
+ /**
+ * Select no viewpoint.
+ *
+ * @return the next step.
+ */
+ UILocalSession selectNoViewpoint();
+
+ /**
+ * Select some viewpoints.
+ *
+ * @param vps
+ * names of the viewpoints to select.
+ * @return the next step.
+ */
+ UILocalSession selectViewpoints(String... vps);
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITableRepresentation.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITableRepresentation.java
new file mode 100644
index 0000000000..a049592ff0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITableRepresentation.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Object to manage diagram representations.
+ *
+ * @author dlecan
+ */
+public class UITableRepresentation extends AbstractUIRepresentation<SWTBotEditor> {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item.
+ *
+ * @param representationName
+ * Representation name.
+ */
+ public UITableRepresentation(final SWTBotTreeItem treeItem, final String representationName) {
+ super(treeItem, representationName);
+ }
+
+ /**
+ * Open current representation. Does nothing if current diagram was created
+ * in this test session instead of being simply opened.
+ *
+ * @return Current representation.
+ */
+ public UITableRepresentation open() {
+ super.doOpen();
+ return this;
+ }
+
+ /**
+ * save current representation.
+ *
+ * @return Current representation.
+ */
+ public UITableRepresentation save() {
+ super.doSave();
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SWTBotEditor getEditor() {
+ final SWTBotEditor editorByTitle = designerBot.editorByTitle(getRepresentationName());
+ // As of 2009-12-18, SWTBotEditor#setFocus() doesn't do anything
+ editorByTitle.show();
+ return editorByTitle;
+ }
+
+ /**
+ * Get table.
+ *
+ * @return Current table.
+ */
+ public SWTBotTree getTable() {
+ return getEditorBot().tree();
+ }
+
+ /**
+ * Get editor bot.
+ *
+ * @return Editor bot.
+ */
+ public SWTBot getEditorBot() {
+ return getEditor().bot();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITreeRepresentation.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITreeRepresentation.java
new file mode 100644
index 0000000000..736ebbfc7b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/UITreeRepresentation.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business;
+
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Object to manage tree.
+ *
+ * @author jdupont
+ */
+public class UITreeRepresentation extends AbstractUIRepresentation<SWTBotEditor> {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item.
+ *
+ * @param representationName
+ * Representation name.
+ */
+ public UITreeRepresentation(final SWTBotTreeItem treeItem, final String representationName) {
+ super(treeItem, representationName);
+ }
+
+ /**
+ * Open current representation. Does nothing if current tree was created in
+ * this test session instead of being simply opened.
+ *
+ * @return Current representation.
+ */
+ public UITreeRepresentation open() {
+ super.doOpen();
+ return this;
+ }
+
+ /**
+ * save current representation.
+ *
+ * @return Current representation.
+ */
+ public UITreeRepresentation save() {
+ super.doSave();
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SWTBotEditor getEditor() {
+ final SWTBotEditor editorByTitle = designerBot.editorByTitle(getRepresentationName());
+ // As of 2009-12-18, SWTBotEditor#setFocus() doesn't do anything
+ editorByTitle.show();
+ return editorByTitle;
+ }
+
+ /**
+ * Get tree.
+ *
+ * @return Current tree.
+ */
+ public SWTBotTree getTree() {
+ return getEditorBot().tree();
+ }
+
+ /**
+ * Get editor bot.
+ *
+ * @return Editor bot.
+ */
+ public SWTBot getEditorBot() {
+ return getEditor().bot();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithNextTreeItem.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithNextTreeItem.java
new file mode 100644
index 0000000000..a27a6cf1f3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithNextTreeItem.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * UI element which can handle a next element in the tree.
+ *
+ * @author dlecan
+ */
+public abstract class AbstractUIElementWithNextTreeItem extends AbstractUIElementWithTreeItem {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public AbstractUIElementWithNextTreeItem(final SWTBotTreeItem treeItem) {
+ super(treeItem);
+ }
+
+ /**
+ * Return the next node. Return <code>null</code> if internal tree item is
+ * <code>null</code>.
+ *
+ * @param nodeLabel
+ * Node label.
+ * @return Next node.
+ */
+ protected SWTBotTreeItem getNextNode(final String nodeLabel) {
+ if (getTreeItem() != null) {
+ return getTreeItem().expandNode(nodeLabel);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithTreeItem.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithTreeItem.java
new file mode 100644
index 0000000000..720a24de82
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/AbstractUIElementWithTreeItem.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Element with tree item.
+ *
+ * @author dlecan
+ */
+public abstract class AbstractUIElementWithTreeItem {
+
+ private final SWTBotTreeItem treeItem;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public AbstractUIElementWithTreeItem(final SWTBotTreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Returns the treeItem.
+ *
+ * @return the treeItem
+ */
+ public SWTBotTreeItem getTreeItem() {
+ return treeItem;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSCategoryBrowser.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSCategoryBrowser.java
new file mode 100644
index 0000000000..ba3b435220
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSCategoryBrowser.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Category browser.
+ *
+ * @author dlecan
+ */
+public class UILSCategoryBrowser extends AbstractUIElementWithNextTreeItem {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public UILSCategoryBrowser(final SWTBotTreeItem treeItem) {
+ super(treeItem);
+ }
+
+ /**
+ * Select viewpoint in local session.
+ *
+ * @param viewpointName
+ * Viewpoint name to select.
+ * @return viewpoint browser.
+ */
+ public UILSViewpointBrowser selectViewpoint(final String viewpointName) {
+ return new UILSViewpointBrowser(getNextNode(viewpointName));
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSRepresentationBrowser.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSRepresentationBrowser.java
new file mode 100644
index 0000000000..6d7c46cc18
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSRepresentationBrowser.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.sirius.tests.swtbot.support.api.business.AbstractUIRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UITableRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UITreeRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.utils.business.UIRepresentationUtils;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Representation browser.
+ *
+ * @author dlecan
+ */
+public class UILSRepresentationBrowser extends AbstractUIElementWithNextTreeItem {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public UILSRepresentationBrowser(final SWTBotTreeItem treeItem) {
+ super(treeItem);
+ }
+
+ /**
+ * Select an instance of representation, <i>ie</i> a diagram or a table.
+ *
+ * @param <R>
+ * Type of representation.
+ * @param representationInstanceLabelName
+ * Representation instance label name.
+ * @param representationType
+ * Representation type.
+ * @return A representation.
+ */
+ public <R extends AbstractUIRepresentation<?>> R selectRepresentationInstance(final String representationInstanceLabelName, final Class<R> representationType) {
+ return UIRepresentationUtils.buildRepresentation(getNextNode(representationInstanceLabelName), representationInstanceLabelName, representationType);
+ }
+
+ /**
+ * Select an instance of diagram.
+ *
+ * @param diagramInstanceLabelName
+ * Diagram instance label name.
+ * @return A diagram.
+ */
+ public UIDiagramRepresentation selectDiagramInstance(final String diagramInstanceLabelName) {
+ return selectRepresentationInstance(diagramInstanceLabelName, UIDiagramRepresentation.class);
+ }
+
+ /**
+ * Select an instance of table.
+ *
+ * @param tableInstanceLabelName
+ * Table instance label name.
+ * @return A table.
+ */
+ public UITableRepresentation selectTableInstance(final String tableInstanceLabelName) {
+ return selectRepresentationInstance(tableInstanceLabelName, UITableRepresentation.class);
+ }
+
+ /**
+ * Select an instance of tree.
+ *
+ * @param treeInstanceLabelName
+ * Tree instance label name.
+ * @return A tree.
+ */
+ public UITreeRepresentation selectTreeInstance(final String treeInstanceLabelName) {
+ return selectRepresentationInstance(treeInstanceLabelName, UITreeRepresentation.class);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSResourceBrowser.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSResourceBrowser.java
new file mode 100644
index 0000000000..d86afa90cc
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSResourceBrowser.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Object to handle resource category browser.
+ *
+ * @author dlecan
+ *
+ */
+public class UILSResourceBrowser extends AbstractUIElementWithNextTreeItem {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public UILSResourceBrowser(final SWTBotTreeItem treeItem) {
+ super(treeItem);
+ }
+
+ // To complete
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSViewpointBrowser.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSViewpointBrowser.java
new file mode 100644
index 0000000000..60a41bba4f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILSViewpointBrowser.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Viewpoint browser.
+ *
+ * @author dlecan
+ */
+public class UILSViewpointBrowser extends AbstractUIElementWithNextTreeItem {
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * Tree item for this element.
+ */
+ public UILSViewpointBrowser(final SWTBotTreeItem treeItem) {
+ super(treeItem);
+ }
+
+ /**
+ * Selection representation by its name.
+ *
+ * @param representationLabelName
+ * Representation label name.
+ * @return Representation browser.
+ */
+ public UILSRepresentationBrowser selectRepresentation(final String representationLabelName) {
+ return new UILSRepresentationBrowser(getNextNode(representationLabelName));
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILocalSessionBrowser.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILocalSessionBrowser.java
new file mode 100644
index 0000000000..eadac9c2b4
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/business/sessionbrowser/UILocalSessionBrowser.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.business.sessionbrowser;
+
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Object "browse" local session view.
+ *
+ * @author dlecan
+ */
+public class UILocalSessionBrowser extends AbstractUIElementWithNextTreeItem {
+
+ /**
+ * Label.
+ */
+ public static final String PER_RESOURCE_LABEL = "Representations per resource";
+
+ /**
+ * Label.
+ */
+ public static final String PER_CATEGORY_LABEL = "Representations per category";
+
+ /**
+ * Constructor.
+ *
+ * @param rootTreeItem
+ * Root item
+ */
+ public UILocalSessionBrowser(final SWTBotTreeItem rootTreeItem) {
+ super(rootTreeItem);
+ }
+
+ /**
+ * (Optional) Per resource browse. Can be null if there is only one session
+ * resource.
+ *
+ * @return Per resource browser
+ */
+ public UILSResourceBrowser perResource() {
+ return new UILSResourceBrowser(getNextNode(UILocalSessionBrowser.PER_RESOURCE_LABEL));
+ }
+
+ /**
+ * Per category browse.
+ *
+ * @return Per category browser
+ */
+ public UILSCategoryBrowser perCategory() {
+ return new UILSCategoryBrowser(getNextNode(UILocalSessionBrowser.PER_CATEGORY_LABEL));
+ }
+
+ /**
+ * Select viewpoint in local session.
+ *
+ * @param viewpointName
+ * Viewpoint name to select.
+ * @return viewpoint browser.
+ */
+ public UILSViewpointBrowser selectViewpoint(final String viewpointName) {
+ return new UILSViewpointBrowser(getNextNode(viewpointName));
+ }
+
+ /**
+ * Per semantic browse.
+ *
+ * @return Per semantic browse node
+ */
+ public SWTBotTreeItem perSemantic() {
+
+ for (SWTBotTreeItem currentTreeItem : getTreeItem().getItems()) {
+ if ((!currentTreeItem.getText().equals(UILocalSessionBrowser.PER_CATEGORY_LABEL)) && (!currentTreeItem.getText().equals(UILocalSessionBrowser.PER_RESOURCE_LABEL))) {
+ return currentTreeItem.expand();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/AbstractOperationCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/AbstractOperationCondition.java
new file mode 100644
index 0000000000..0ead2aec0f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/AbstractOperationCondition.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.core.commands.operations.IOperationHistory;
+import org.eclipse.core.commands.operations.IOperationHistoryListener;
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.operations.IWorkbenchOperationSupport;
+
+/**
+ * Abstract SWTBot condition to check that the last operation on the command
+ * stack has been changed.
+ *
+ * @author edugueperoux
+ */
+public abstract class AbstractOperationCondition extends DefaultCondition implements IOperationHistoryListener {
+
+ private boolean operationState;
+
+ private final IOperationHistory operationHistory;
+
+ private final int eventType;
+
+ /**
+ * Constructor to initialize hook on the CommandStack.
+ *
+ * @param eventType
+ * the type of event from the command stack to listens
+ */
+ public AbstractOperationCondition(int eventType) {
+ super();
+ this.eventType = eventType;
+ IWorkbenchOperationSupport operationSupport = PlatformUI.getWorkbench().getOperationSupport();
+ operationHistory = operationSupport.getOperationHistory();
+ operationHistory.addOperationHistoryListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return operationState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void historyNotification(OperationHistoryEvent event) {
+ if (event.getEventType() == eventType) {
+ this.operationState = true;
+ operationHistory.removeOperationHistoryListener(this);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckBoundsCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckBoundsCondition.java
new file mode 100644
index 0000000000..1f01d27f3b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckBoundsCondition.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.junit.ComparisonFailure;
+
+/**
+ * Class to check if the edit part has the expected bounds.
+ *
+ * @author lredor
+ */
+public class CheckBoundsCondition extends DefaultCondition {
+
+ /**
+ * True if the width of the bounds must be checked.
+ */
+ private boolean checkWidth = true;
+
+ /**
+ * True if the height of the bounds must be checked.
+ */
+ private boolean checkHeight = true;
+
+ /**
+ * the edit part to wait for its selection.
+ */
+ private final IGraphicalEditPart editPartToWaitForSelection;
+
+ /**
+ * the class of the edit part to wait for its selection.
+ */
+ private Class<? extends IGraphicalEditPart> editPartClass;
+
+ /**
+ * The expected bounds in absolute coordinates.
+ */
+ private final Rectangle expectedBounds;
+
+ /**
+ * Constructor.
+ *
+ * @param editPartToWaitForSelection
+ * the edit part to wait for its bounds.
+ * @param expectedAbsoluteBounds
+ * expected bounds in absolute coordinate
+ */
+ public CheckBoundsCondition(IGraphicalEditPart editPartToWaitForSelection, Rectangle expectedAbsoluteBounds) {
+ this.editPartToWaitForSelection = editPartToWaitForSelection;
+ this.expectedBounds = expectedAbsoluteBounds;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param editPartToWaitForSelection
+ * the edit part to wait for its bounds.
+ * @param expectedAbsoluteBounds
+ * expected bounds in absolute coordinate
+ * @param checkWidth
+ * True if the width of the bounds must be checked.
+ * @param checkHeight
+ * True if the height of the bounds must be checked.
+ */
+ public CheckBoundsCondition(IGraphicalEditPart editPartToWaitForSelection, Rectangle expectedAbsoluteBounds, boolean checkWidth, boolean checkHeight) {
+ this.editPartToWaitForSelection = editPartToWaitForSelection;
+ this.expectedBounds = expectedAbsoluteBounds;
+ this.checkWidth = checkWidth;
+ this.checkHeight = checkHeight;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ boolean result = false;
+ if (editPartToWaitForSelection != null) {
+ if (checkHeight && checkWidth) {
+ result = getCurrentAbsoluteBounds().equals(expectedBounds);
+ } else if (checkWidth) {
+ result = getCurrentAbsoluteBounds().width == expectedBounds.width;
+ } else if (checkHeight) {
+ result = getCurrentAbsoluteBounds().height == expectedBounds.height;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ String result = null;
+ if (checkHeight && checkWidth) {
+ result = new ComparisonFailure("The expected bounds is not reached.", expectedBounds.toString(), getCurrentAbsoluteBounds().toString()).getMessage();
+ } else if (checkWidth) {
+ result = new ComparisonFailure("The expected width is not reached.", Integer.toString(expectedBounds.width), Integer.toString(getCurrentAbsoluteBounds().width)).getMessage();
+ } else if (checkHeight) {
+ result = new ComparisonFailure("The expected width is not reached.", Integer.toString(expectedBounds.height), Integer.toString(getCurrentAbsoluteBounds().height)).getMessage();
+ }
+ return result;
+ }
+
+ /**
+ * Return the absolute bounds of the edit part.
+ *
+ * @return The absolute bounds.
+ */
+ protected Rectangle getCurrentAbsoluteBounds() {
+ Rectangle bounds = editPartToWaitForSelection.getFigure().getBounds().getCopy();
+ editPartToWaitForSelection.getFigure().translateToAbsolute(bounds);
+ return bounds;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckContextMenuAvailableCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckContextMenuAvailableCondition.java
new file mode 100644
index 0000000000..b60c0f6f27
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckContextMenuAvailableCondition.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Class to availability of a context menu on a {@link SWTBotTreeItem}.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class CheckContextMenuAvailableCondition extends DefaultCondition {
+
+ private final SWTBotTreeItem treeItem;
+
+ private final String menuName;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * {@link SWTBotTreeItem} to check context menu existence
+ *
+ * @param menuName
+ * name of the expected context menu
+ *
+ */
+ public CheckContextMenuAvailableCondition(SWTBotTreeItem treeItem, String menuName) {
+ this.treeItem = treeItem;
+ this.menuName = menuName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swtbot.swt.finder.waits.ICondition#test()
+ */
+ @Override
+ public boolean test() throws Exception {
+ return SWTBotUtils.hasContextMenu(treeItem, menuName);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The SWTBotTreeItem named '" + treeItem.getText() + " has no context menu named " + menuName;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckDiagramSelected.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckDiagramSelected.java
new file mode 100644
index 0000000000..f77352bc36
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckDiagramSelected.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Check that no elements on the diagram are selected and therefore the
+ * selection of the editor is the diagram itself.
+ *
+ * @author pcdavid
+ */
+public class CheckDiagramSelected extends DefaultCondition {
+
+ /**
+ * Current editor.
+ */
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Default constructor.
+ *
+ * @param editor
+ * the current editor.
+ */
+ public CheckDiagramSelected(SWTBotDesignerEditor editor) {
+ super();
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ ISelection selection = editor.getSelection();
+ return selection instanceof IStructuredSelection && ((IStructuredSelection) selection).size() == 1 && ((IStructuredSelection) selection).getFirstElement() instanceof DiagramEditPart;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "Failed to select the diagram.";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEdgeLabelVisibility.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEdgeLabelVisibility.java
new file mode 100644
index 0000000000..44b876d26e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEdgeLabelVisibility.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Inner class to check if the label of this edge edit part is hidden.
+ *
+ * @author smonnier
+ */
+public class CheckEdgeLabelVisibility extends DefaultCondition {
+
+ private final String label;
+
+ private final SWTBotDesignerEditor editor;
+
+ private final boolean isVisible;
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * the current editor
+ * @param label
+ * name of the edit part to wait for its hiding.
+ * @param isVisible
+ * check is the label should be visible or hidden
+ */
+ public CheckEdgeLabelVisibility(SWTBotDesignerEditor editor, String label, boolean isVisible) {
+ this.label = label;
+ this.editor = editor;
+ this.isVisible = isVisible;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return ((AbstractGraphicalEditPart) editor.getEditPart(label).part()).getFigure().isVisible() == isVisible;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ if (isVisible) {
+ return "The label is still hidden.";
+ } else {
+ return "The label is still visible.";
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsDisplayed.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsDisplayed.java
new file mode 100644
index 0000000000..2955facceb
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsDisplayed.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Checks if a message edit part is displayed.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class CheckEditPartIsDisplayed extends DefaultCondition {
+
+ private final String label;
+
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param label
+ * label of the edit part to wait for.
+ *
+ * @param editor
+ * the editor containing the edit part we are looking for.
+ */
+ public CheckEditPartIsDisplayed(String label, SWTBotDesignerEditor editor) {
+ this.label = label;
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ try {
+ return editor.getEditPart(label) != null;
+ } catch (WidgetNotFoundException e) {
+ // The widget has not yet been found
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The widget with label '" + label + "' has not been found before timeout";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsNotDisplayed.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsNotDisplayed.java
new file mode 100644
index 0000000000..e8b70e25bd
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartIsNotDisplayed.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Checks if an edit part is not displayed.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class CheckEditPartIsNotDisplayed extends DefaultCondition {
+
+ private final String label;
+
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param label
+ * label of the edit part to wait for not being displayed
+ * anymore.
+ *
+ * @param editor
+ * the editor containing the edit part.
+ */
+ public CheckEditPartIsNotDisplayed(String label, SWTBotDesignerEditor editor) {
+ this.label = label;
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ try {
+ return editor.getEditPart(label) == null;
+ } catch (WidgetNotFoundException e) {
+ // The widget has not been found
+ return true;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The widget with label '" + label + "' is still displayed at timeout";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartMoved.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartMoved.java
new file mode 100644
index 0000000000..db5e75897d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartMoved.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * A Condition to test if a SWTBotGefEditPart's view has moved.
+ *
+ * @author edugueperoux
+ */
+public class CheckEditPartMoved extends DefaultCondition {
+
+ /**
+ * the edit part to wait for its move.
+ */
+ private IGraphicalEditPart graphicalEditPart;
+
+ /**
+ * Initial position of the edit part
+ */
+ private final Point initialLocation;
+
+ /**
+ * Current editor.
+ */
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * name of the edit part to wait for its selection.
+ */
+ private String labelOfEditPart;
+
+ /**
+ * the class of the edit part to wait for its selection.
+ */
+ private Class<? extends IGraphicalEditPart> editPartClass;
+
+ /**
+ * Default Constructor.
+ *
+ * @param editPartBot
+ * bot to check if moved
+ */
+ public CheckEditPartMoved(SWTBotGefEditPart editPartBot) {
+ this.graphicalEditPart = (IGraphicalEditPart) editPartBot.part();
+ this.initialLocation = graphicalEditPart.getFigure().getBounds().getLocation().getCopy();
+ this.editor = null;
+ }
+
+ /**
+ * Default Constructor.
+ *
+ * @param editor
+ * the current editor
+ *
+ * @param labelOfEditPart
+ * name of the edit part to wait for its selection.
+ *
+ * @param editPartClass
+ * edit part class to wait for its selection.
+ * @param initialLocation
+ * Initial position of the edit part
+ */
+ public CheckEditPartMoved(SWTBotDesignerEditor editor, String labelOfEditPart, Class<? extends IGraphicalEditPart> editPartClass, Point initialLocation) {
+ this.labelOfEditPart = labelOfEditPart;
+ this.editPartClass = editPartClass;
+ this.initialLocation = initialLocation;
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ Point location;
+ if (editor != null) {
+ location = editor.getAbsoluteLocation((org.eclipse.gef.GraphicalEditPart) editor.getEditPart(labelOfEditPart, editPartClass).part());
+ } else {
+ location = graphicalEditPart.getFigure().getBounds().getLocation().getCopy();
+ }
+ return !initialLocation.equals(location);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "Failed to find " + graphicalEditPart.resolveSemanticElement() + " moved";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartResized.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartResized.java
new file mode 100644
index 0000000000..884eb1f782
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEditPartResized.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * A Condition to test if a SWTBotGefEditPart's view has resized.
+ *
+ * @author edugueperoux
+ */
+public class CheckEditPartResized extends DefaultCondition {
+
+ private final GraphicalEditPart graphicalEditPart;
+
+ private final Dimension initialSize;
+
+ /**
+ * Default Constructor.
+ *
+ * @param editPartBot
+ * bot to check if resized
+ */
+ public CheckEditPartResized(SWTBotGefEditPart editPartBot) {
+ this.graphicalEditPart = (GraphicalEditPart) editPartBot.part();
+ this.initialSize = graphicalEditPart.getFigure().getBounds().getSize().getCopy();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return !initialSize.equals(graphicalEditPart.getFigure().getBounds().getSize());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "Failed to find " + graphicalEditPart.resolveSemanticElement() + " resized";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEmptySelection.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEmptySelection.java
new file mode 100644
index 0000000000..f2a2486690
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckEmptySelection.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Check that no element are selected on editor.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ *
+ */
+public class CheckEmptySelection extends DefaultCondition {
+
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * current Editor
+ *
+ */
+ public CheckEmptySelection(SWTBotDesignerEditor editor) {
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ ISelection selection = editor.getSelection();
+ if (selection instanceof StructuredSelection) {
+ StructuredSelection structuredSelection = (StructuredSelection) selection;
+ return structuredSelection.size() == 1 && structuredSelection.getFirstElement() instanceof DiagramEditPart;
+
+ }
+ return selection.isEmpty();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "Couldn't evalutate selection before Timeout";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckNbVisibleElementsInTree.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckNbVisibleElementsInTree.java
new file mode 100644
index 0000000000..43f59667a1
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckNbVisibleElementsInTree.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+
+/**
+ * A condition for waiting that the tree displays the expected number of
+ * elements.
+ *
+ * @author lredor
+ */
+public class CheckNbVisibleElementsInTree extends DefaultCondition {
+
+ private final SWTBotTree tree;
+
+ private final int expected;
+
+ private String errorMessage;
+
+ /**
+ * Default Constructor.
+ *
+ * @param tree
+ * The tree to check.
+ * @param expected
+ * Number of elements that should be display in this tree.
+ *
+ */
+ public CheckNbVisibleElementsInTree(SWTBotTree tree, int expected) {
+ this.tree = tree;
+ this.expected = expected;
+ }
+
+ /**
+ * Constructor with error message.
+ *
+ * @param tree
+ * The tree to check.
+ * @param expected
+ * Number of elements that should be display in this tree.
+ * @param errorMessage
+ * The message to display in case of failure.
+ *
+ */
+ public CheckNbVisibleElementsInTree(SWTBotTree tree, int expected, String errorMessage) {
+ this.tree = tree;
+ this.expected = expected;
+ this.errorMessage = errorMessage;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return tree.visibleRowCount() == expected;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ String suffix = "(expected:<" + expected + "> but was:<" + tree.visibleRowCount() + ">)";
+ if (errorMessage == null) {
+ return "This tree does not display " + expected + " elements " + suffix + ".";
+ } else {
+ return errorMessage + suffix;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckSelectedCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckSelectedCondition.java
new file mode 100644
index 0000000000..484a592d32
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckSelectedCondition.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Class to check if the edit part is selected.
+ *
+ * @author smonnier
+ */
+public class CheckSelectedCondition extends DefaultCondition {
+
+ /**
+ * name of the edit part to wait for its selection.
+ */
+ private String labelOfEditPart;
+
+ /**
+ * the edit part to wait for its selection.
+ */
+ private IGraphicalEditPart editPartToWaitForSelection;
+
+ /**
+ * the class of the edit part to wait for its selection.
+ */
+ private Class<? extends IGraphicalEditPart> editPartClass;
+
+ /**
+ * Current editor.
+ */
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * the current editor.
+ *
+ * @param labelOfEditPart
+ * name of the edit part to wait for its selection.
+ */
+ public CheckSelectedCondition(SWTBotDesignerEditor editor, String labelOfEditPart) {
+ this.editor = editor;
+ this.labelOfEditPart = labelOfEditPart;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * the current editor.
+ *
+ * @param editPartToWaitForSelection
+ * the edit part to wait for its selection.
+ */
+ public CheckSelectedCondition(SWTBotDesignerEditor editor, IGraphicalEditPart editPartToWaitForSelection) {
+ this.editor = editor;
+ this.editPartToWaitForSelection = editPartToWaitForSelection;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * the current editor.
+ *
+ * @param labelOfEditPart
+ * name of the edit part to wait for its selection.
+ *
+ * @param editPartClass
+ * edit part class to wait for its selection.
+ */
+ public CheckSelectedCondition(SWTBotDesignerEditor editor, String labelOfEditPart, Class<? extends IGraphicalEditPart> editPartClass) {
+ this.editor = editor;
+ this.labelOfEditPart = labelOfEditPart;
+ this.editPartClass = editPartClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ boolean result = false;
+ if (editPartToWaitForSelection != null) {
+ result = editPartToWaitForSelection.getSelected() == EditPart.SELECTED_PRIMARY || editPartToWaitForSelection.getSelected() == EditPart.SELECTED;
+ } else if (labelOfEditPart != null) {
+ if (editPartClass != null) {
+ result = editor.getEditPart(labelOfEditPart, editPartClass).part().getSelected() == EditPart.SELECTED_PRIMARY
+ || editor.getEditPart(labelOfEditPart, editPartClass).part().getSelected() == EditPart.SELECTED;
+ } else {
+ result = editor.getEditPart(labelOfEditPart).part().getParent().getSelected() == EditPart.SELECTED_PRIMARY
+ || editor.getEditPart(labelOfEditPart).part().getParent().getSelected() == EditPart.SELECTED;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The edit part has not been selected";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckToolIsActivated.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckToolIsActivated.java
new file mode 100644
index 0000000000..bdaac259ca
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckToolIsActivated.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Inner class to check if the edit part is selected.
+ *
+ * @author smonnier
+ */
+public class CheckToolIsActivated extends DefaultCondition {
+
+ private final String toolLabel;
+
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param editor
+ * the {@link SWTBotDesignerEditor}.
+ *
+ * @param toolLabel
+ * the label of the tool
+ */
+ public CheckToolIsActivated(SWTBotDesignerEditor editor, String toolLabel) {
+ this.toolLabel = toolLabel;
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return toolLabel != null && editor.getActiveTool() != null && toolLabel.equals(editor.getActiveTool().getLabel());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckTreeItemEnabled.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckTreeItemEnabled.java
new file mode 100644
index 0000000000..b76ef10d4e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/CheckTreeItemEnabled.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Condition testing the a treeItem is enabled.
+ *
+ * @author smonnier
+ */
+public class CheckTreeItemEnabled extends DefaultCondition {
+
+ private final SWTBotTreeItem treeItem;
+
+ /**
+ * Default Constructor.
+ *
+ * @param treeItem
+ * the treeItem under investigation.
+ *
+ */
+ public CheckTreeItemEnabled(SWTBotTreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return treeItem.isEnabled();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The FontFormat of widget";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DiagramWithChildrensCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DiagramWithChildrensCondition.java
new file mode 100644
index 0000000000..9e253f80d3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DiagramWithChildrensCondition.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gef.RootEditPart;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.junit.ComparisonFailure;
+
+/**
+ * Condition testing the number of diagram elements is the expected one.
+ *
+ * @author smonnier
+ */
+public class DiagramWithChildrensCondition extends DefaultCondition {
+
+ private final SWTBotDesignerEditor editor;
+
+ private final int expectedChildrenOnDiagramLevel;
+
+ /**
+ * Default constructor.
+ *
+ * @param editor
+ * the current editor
+ * @param expectedChildrenOnDiagramLevel
+ * expected number of children on diagram level
+ */
+ public DiagramWithChildrensCondition(SWTBotDesignerEditor editor, int expectedChildrenOnDiagramLevel) {
+ super();
+ this.editor = editor;
+ this.expectedChildrenOnDiagramLevel = expectedChildrenOnDiagramLevel;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return ((RootEditPart) editor.rootEditPart().part()).getContents().getChildren().size() == expectedChildrenOnDiagramLevel;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return new ComparisonFailure("There is not the expected number of children on the diagram level", Integer.toString(expectedChildrenOnDiagramLevel), Integer.toString(((RootEditPart) editor
+ .rootEditPart().part()).getContents().getChildren().size())).getMessage();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DragAndDropCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DragAndDropCondition.java
new file mode 100644
index 0000000000..afef481cb1
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/DragAndDropCondition.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Validates that the element has been dropped in the expected container.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class DragAndDropCondition extends DefaultCondition {
+
+ private final String dropedElementName;
+
+ private final Class<? extends EditPart> droppedElementClass;
+
+ private final String targetContainerName;
+
+ private final Class<? extends EditPart> targetContainerClass;
+
+ private final SWTBotDesignerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param dropedElementName
+ * name of the dropped element
+ * @param droppedElementClass
+ * type of the dropped element
+ * @param targetContainerName
+ * name of the target container
+ * @param targetContainerClass
+ * type of the target container
+ * @param editor
+ * used editor for the drag and drop action
+ */
+ public DragAndDropCondition(String dropedElementName, Class<? extends EditPart> droppedElementClass, String targetContainerName, Class<? extends EditPart> targetContainerClass,
+ SWTBotDesignerEditor editor) {
+ this.dropedElementName = dropedElementName;
+ this.droppedElementClass = droppedElementClass;
+ this.targetContainerName = targetContainerName;
+ this.targetContainerClass = targetContainerClass;
+ this.editor = editor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The dropped element has not been found in the target container";
+ }
+
+ /**
+ * Validates that the element has been dropped in the expected container.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ SWTBotGefEditPart droppedEditPart = editor.getEditPart(dropedElementName, droppedElementClass);
+ SWTBotGefEditPart targetEditPart = editor.getEditPart(targetContainerName, targetContainerClass);
+ return droppedEditPart != null && droppedEditPart.parent() != null && droppedEditPart.parent().part() instanceof ShapeCompartmentEditPart
+ && droppedEditPart.parent().parent().equals(targetEditPart);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/EditorHasFocusCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/EditorHasFocusCondition.java
new file mode 100644
index 0000000000..5be75681af
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/EditorHasFocusCondition.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Condition that validates that an editor has the focus.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class EditorHasFocusCondition extends DefaultCondition {
+
+ private final SWTBotDesignerEditor swtbotEditor;
+
+ /**
+ * Default constructor.
+ *
+ * @param swtbotEditor
+ * the {@link SWTBotDesignerEditor} that should has the focus.
+ */
+ public EditorHasFocusCondition(SWTBotDesignerEditor swtbotEditor) {
+ super();
+ this.swtbotEditor = swtbotEditor;
+ }
+
+ /**
+ * test that the editor has the focus.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ IWorkbenchPart activePart = PlatformUI.getWorkbench().getWorkbenchWindows()[0].getActivePage().getActivePart();
+ IEditorPart editorPart = swtbotEditor.getReference().getEditor(false);
+ return editorPart != null && activePart != null && editorPart.equals(activePart);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The focus has not been set on the editor";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ItemEnabledCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ItemEnabledCondition.java
new file mode 100644
index 0000000000..9602aa31b7
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ItemEnabledCondition.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+
+/**
+ *
+ * This class helps to wait that a item is enabled.
+ *
+ * @author amartin
+ *
+ *
+ */
+public class ItemEnabledCondition extends DefaultCondition {
+
+ private final AbstractSWTBot<? extends Widget> item;
+
+ /**
+ * Constructor.
+ *
+ * @param item
+ * The item to wait to be enabled
+ */
+ public ItemEnabledCondition(final AbstractSWTBot<? extends Widget> item) {
+ this.item = item;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "item with text " + item.getText() + " is not enabled";
+ }
+
+ /**
+ * Test if the item is enabled.
+ *
+ * @throws Exception
+ * if the test fail.
+ * @return if the item is enabled
+ */
+ @Override
+ public boolean test() throws Exception {
+ return item.isEnabled();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NotifiedFromLockOperationCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NotifiedFromLockOperationCondition.java
new file mode 100644
index 0000000000..937a01d413
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NotifiedFromLockOperationCondition.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import java.util.Collection;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.ecore.extender.business.api.permission.IAuthorityListener;
+import org.eclipse.sirius.ecore.extender.business.api.permission.IPermissionAuthority;
+import org.eclipse.sirius.ecore.extender.business.api.permission.PermissionAuthorityRegistry;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * SWTBot condition to check that the current permission authority notify its
+ * listeners thaht some elements were locked/unlocked.
+ *
+ * @author mporhel
+ */
+public class NotifiedFromLockOperationCondition extends DefaultCondition implements IAuthorityListener {
+
+ private boolean notified;
+
+ private final IPermissionAuthority permissionAuthority;
+
+ /**
+ * Constructor.
+ *
+ * @param set
+ * the current resource set.
+ */
+ public NotifiedFromLockOperationCondition(ResourceSet set) {
+ super();
+ permissionAuthority = PermissionAuthorityRegistry.getDefault().getPermissionAuthority(set);
+ permissionAuthority.addAuthorityListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return notified;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "No lock/unlock notification launched by the permission authority to its listeners";
+ }
+
+ private void notified() {
+ notified = true;
+ permissionAuthority.removeAuthorityListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyIsLocked(EObject instance) {
+ notified();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyIsReleased(EObject instance) {
+ notified();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyIsLocked(Collection<EObject> instances) {
+ notified();
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyIsReleased(Collection<EObject> instances) {
+ notified();
+ }
+};
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NumberOfOpenedEditorsCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NumberOfOpenedEditorsCondition.java
new file mode 100644
index 0000000000..5047abe8c0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/NumberOfOpenedEditorsCondition.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * SWTBot condition to check the number of opened editor.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class NumberOfOpenedEditorsCondition extends DefaultCondition {
+ private final int expectedNumber;
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Constructor.
+ *
+ * @param bot
+ * Bot.
+ * @param expectedNumber
+ * number of expected opened editor
+ */
+ public NumberOfOpenedEditorsCondition(SWTWorkbenchBot bot, int expectedNumber) {
+ this.bot = bot;
+ this.expectedNumber = expectedNumber;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ int newNumberOfEditors = bot.editors().size();
+ return expectedNumber == newNumberOfEditors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getFailureMessage() {
+ return "The number of opened editors is " + bot.editors().size() + " instead of the expected " + expectedNumber;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OpenedSessionCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OpenedSessionCondition.java
new file mode 100644
index 0000000000..21edb62677
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OpenedSessionCondition.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.business.api.session.SessionManager;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+
+/**
+ * A condition to wait until the {@link SessionManager} return the expected
+ * number of sessions.
+ *
+ * @author <a href="mailto:maxime.porhel@obeo.fr">Maxime Porhel</a>
+ */
+public class OpenedSessionCondition extends DefaultCondition implements ICondition {
+
+ private final int expectedNumber;
+
+ /**
+ * Construct a condition to wait until a session is closed.
+ *
+ * @param expectedNumber
+ * the expected number of session
+ */
+ public OpenedSessionCondition(int expectedNumber) {
+ this.expectedNumber = expectedNumber;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean test() throws Exception {
+ return expectedNumber == SessionManager.INSTANCE.getSessions().size();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The expected number of session was not reached.";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationDoneCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationDoneCondition.java
new file mode 100644
index 0000000000..1e9a2b9411
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationDoneCondition.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+
+/**
+ * SWTBot condition to check that a operation on the command stack has been
+ * done.
+ *
+ * @author edugueperoux
+ */
+public class OperationDoneCondition extends AbstractOperationCondition {
+
+ /**
+ * Default constructor.
+ */
+ public OperationDoneCondition() {
+ super(OperationHistoryEvent.DONE);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "operation execution failed";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationRedoneCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationRedoneCondition.java
new file mode 100644
index 0000000000..590bb74d37
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationRedoneCondition.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+
+/**
+ * SWTBot condition to check that the last operation on the command stack has
+ * been redone.
+ *
+ * @author edugueperoux
+ */
+public class OperationRedoneCondition extends AbstractOperationCondition {
+
+ /**
+ * Default constructor.
+ */
+ public OperationRedoneCondition() {
+ super(OperationHistoryEvent.REDONE);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "Redo of operation failed";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationUndoneCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationUndoneCondition.java
new file mode 100644
index 0000000000..d13f1e1b43
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/OperationUndoneCondition.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+
+/**
+ * SWTBot condition to check that the last operation on the command stack has
+ * been undone.
+ *
+ * @author edugueperoux
+ */
+public class OperationUndoneCondition extends AbstractOperationCondition {
+
+ /**
+ * Default constructor.
+ */
+ public OperationUndoneCondition() {
+ super(OperationHistoryEvent.UNDONE);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "Undo of operation failed";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PaletteToolsAvailabilityCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PaletteToolsAvailabilityCondition.java
new file mode 100644
index 0000000000..978a820236
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PaletteToolsAvailabilityCondition.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.gef.palette.PaletteContainer;
+import org.eclipse.gef.ui.palette.PaletteViewer;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.junit.Assert;
+
+/**
+ * A condition on tools availability on the palette.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class PaletteToolsAvailabilityCondition extends DefaultCondition {
+
+ /**
+ * The current {@link UIDiagramRepresentation}.
+ */
+ private final UIDiagramRepresentation diagram;
+
+ /**
+ * Tool availability on the palette expectation
+ */
+ private final boolean shouldHaveDisplayedTools;
+
+ /**
+ * Default constructor.
+ *
+ * @param diagram
+ * current {@link UIDiagramRepresentation}
+ * @param shouldHaveDisplayedTools
+ * Tool availability on the palette expectation
+ */
+ public PaletteToolsAvailabilityCondition(UIDiagramRepresentation diagram, boolean shouldHaveDisplayedTools) {
+ super();
+ this.diagram = diagram;
+ this.shouldHaveDisplayedTools = shouldHaveDisplayedTools;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ PaletteViewer paletteViewer = diagram.getEditor().rootEditPart().part().getViewer().getEditDomain().getPaletteViewer();
+ PaletteContainer viewpointPaletteContainer = (PaletteContainer) paletteViewer.getPaletteRoot().getChildren().get(1);
+ int nbToolInThePalette = viewpointPaletteContainer.getChildren().size();
+ Assert.assertEquals("The palette was expected to be empty", 0, nbToolInThePalette);
+ if (shouldHaveDisplayedTools) {
+ return nbToolInThePalette > 0;
+ } else {
+ return nbToolInThePalette == 0;
+ }
+ }
+
+ @Override
+ public String getFailureMessage() {
+ if (shouldHaveDisplayedTools) {
+ return "It was expected to have tools in the palette";
+ } else {
+ return "It was expected to have no tool in the palette";
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PerspectiveActivatedCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PerspectiveActivatedCondition.java
new file mode 100644
index 0000000000..2ce01a1aab
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/PerspectiveActivatedCondition.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Checks if an edit part is not displayed.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class PerspectiveActivatedCondition extends DefaultCondition {
+
+ private final SWTWorkbenchBot bot;
+
+ private final String perspectiveName;
+
+ /**
+ * Default constructor.
+ *
+ * @param bot
+ * current Bot
+ * @param perspectiveName
+ * name of the perspective that we are waiting for activation
+ */
+ public PerspectiveActivatedCondition(SWTWorkbenchBot bot, String perspectiveName) {
+ this.bot = bot;
+ this.perspectiveName = perspectiveName;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return bot.activePerspective().getLabel().equals(perspectiveName);
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The perspective " + perspectiveName + " has not yet been activated";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ProjectDependenciesItemDisplayed.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ProjectDependenciesItemDisplayed.java
new file mode 100644
index 0000000000..74522cfa5d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ProjectDependenciesItemDisplayed.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * A condition to wait until the project dependencies item is diplayed.
+ *
+ * @author <a href="mailto:maxime.porhel@obeo.fr">Maxime Porhel</a>
+ */
+public class ProjectDependenciesItemDisplayed extends DefaultCondition implements ICondition {
+
+ private final SWTBot modelExplorerViewBot;
+
+ private final String projectName;
+
+ /**
+ * Constructor.
+ *
+ * @param modelExplorerViewBot
+ * the view bot
+ * @param projectName
+ * the project to check
+ */
+ public ProjectDependenciesItemDisplayed(SWTBot modelExplorerViewBot, String projectName) {
+ this.modelExplorerViewBot = modelExplorerViewBot;
+ this.projectName = projectName;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ SWTBotTree tree = modelExplorerViewBot.tree();
+ SWTBotTreeItem swtBotTreeItem = tree.expandNode(projectName);
+ SWTBotTreeItem firstNode = swtBotTreeItem.getNode(0);
+ return "Project Dependencies".equals(firstNode.getText());
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The project dependencies item was not diplayed for " + projectName;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionClosedCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionClosedCondition.java
new file mode 100644
index 0000000000..3d0c7d2346
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionClosedCondition.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+
+/**
+ * A condition to wait until a session is closed.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class SessionClosedCondition extends DefaultCondition implements ICondition {
+
+ private final Session session;
+
+ /**
+ * Construct a condition to wait until a session is closed.
+ *
+ * @param session
+ * the session on which do the test
+ */
+ public SessionClosedCondition(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return !session.isOpen();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "session not closed";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionCondition.java
new file mode 100644
index 0000000000..18746bb15d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionCondition.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UILocalSession;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Test session is correctly opened.
+ *
+ * @author jdupont
+ *
+ */
+public class SessionCondition extends DefaultCondition {
+
+ private final UILocalSession session;
+
+ private final String viewpointName;
+
+ private final String representationName;
+
+ private final String representationInstanceName;
+
+ /**
+ * Constructor for SessionCondition.
+ *
+ * @param session
+ * the UILocalSession.
+ * @param viewpointName
+ * the viewpoint name.
+ * @param representationName
+ * the name of representation.
+ * @param representationInstanceName
+ * the name of representation instance.
+ *
+ */
+ public SessionCondition(UILocalSession session, String viewpointName, String representationName, String representationInstanceName) {
+ this.session = session;
+ this.viewpointName = viewpointName;
+ this.representationName = representationName;
+ this.representationInstanceName = representationInstanceName;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The session " + session + "is not correctly opened";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ boolean sessionOpenedCorectly;
+ try {
+ session.getLocalSessionBrowser().perCategory().selectViewpoint(viewpointName).selectRepresentation(representationName)
+ .selectRepresentationInstance(representationInstanceName, UIDiagramRepresentation.class).open();
+ sessionOpenedCorectly = true;
+ } catch (WidgetNotFoundException wnfe) {
+ sessionOpenedCorectly = false;
+ }
+ return sessionOpenedCorectly;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionSavedCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionSavedCondition.java
new file mode 100644
index 0000000000..03a22083b1
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/SessionSavedCondition.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.business.api.session.SessionStatus;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * Condition to check that the Session has {@link SessionStatus#SYNC} status.
+ *
+ * @author edugueperoux
+ */
+public class SessionSavedCondition extends DefaultCondition {
+
+ private final Session session;
+
+ /**
+ * Default Constructor.
+ *
+ * @param session
+ * the Session
+ */
+ public SessionSavedCondition(Session session) {
+ this.session = session;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return SessionStatus.SYNC == session.getStatus();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "Session not saved. Session status is " + session.getStatus();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TableHasRowCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TableHasRowCondition.java
new file mode 100644
index 0000000000..f0906ecfca
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TableHasRowCondition.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+
+/**
+ * A {@link DefaultCondition} to test that a {@link SWTBotTable} has rows.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TableHasRowCondition extends DefaultCondition {
+
+ private final SWTBotTable swtBotTable;
+
+ /**
+ * Default constructor.
+ *
+ * @param swtBotTable
+ * the {@link SWTBotTable} to test
+ */
+ public TableHasRowCondition(SWTBotTable swtBotTable) {
+ this.swtBotTable = swtBotTable;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return swtBotTable.rowCount() > 0;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "There is no row on the table";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TextWidgetCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TextWidgetCondition.java
new file mode 100644
index 0000000000..a8cac6e157
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TextWidgetCondition.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+
+/**
+ * A {@link DefaultCondition} to test the text of a {@link AbstractSWTBot}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TextWidgetCondition extends DefaultCondition {
+
+ private final AbstractSWTBot<? extends Widget> abstractSWTBot;
+
+ private final String expectedText;
+
+ /**
+ * Default constructor.
+ *
+ * @param abstractSWTBot
+ * the bot on which check the condition
+ * @param expectedText
+ * the expected text
+ */
+ public TextWidgetCondition(AbstractSWTBot<? extends Widget> abstractSWTBot, String expectedText) {
+ this.abstractSWTBot = abstractSWTBot;
+ this.expectedText = expectedText;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return expectedText.equals(abstractSWTBot.getText());
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The bot " + abstractSWTBot + " has not the expected text : " + expectedText;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TransactionClosedCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TransactionClosedCondition.java
new file mode 100644
index 0000000000..137c5d526d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TransactionClosedCondition.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomain.Lifecycle;
+import org.eclipse.emf.transaction.TransactionalEditingDomainEvent;
+import org.eclipse.emf.transaction.TransactionalEditingDomainListenerImpl;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.waits.ICondition;
+
+/**
+ * A {@link ICondition} to wait that a transaction is closed.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TransactionClosedCondition extends DefaultCondition implements ICondition {
+
+ private final TransactionListener transactionListener;
+
+ private boolean transactionClosed;
+
+ /**
+ * Default constructor.
+ *
+ * @param domain
+ * The {@link TransactionalEditingDomain} on which listens
+ * Tranasaction's close.
+ */
+ public TransactionClosedCondition(TransactionalEditingDomain domain) {
+ Lifecycle lifecycle = TransactionUtil.getAdapter(domain, Lifecycle.class);
+ transactionListener = new TransactionListener();
+ lifecycle.addTransactionalEditingDomainListener(transactionListener);
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return transactionClosed;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "Transaction close haven't happend";
+ }
+
+ private class TransactionListener extends TransactionalEditingDomainListenerImpl {
+ @Override
+ public void transactionClosed(TransactionalEditingDomainEvent event) {
+ transactionClosed = true;
+ Lifecycle lifecycle = TransactionUtil.getAdapter(event.getSource(), Lifecycle.class);
+ lifecycle.removeTransactionalEditingDomainListener(transactionListener);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemAvailableCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemAvailableCondition.java
new file mode 100644
index 0000000000..dfefe8c2c0
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemAvailableCondition.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Condition on tree item availability status.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class TreeItemAvailableCondition extends DefaultCondition {
+
+ private SWTBotTree tree;
+
+ private SWTBotTreeItem treeItem;
+
+ private final String treeItemName;
+
+ private final boolean expectedToBeFound;
+
+ /**
+ * Default constructor.
+ *
+ * @param tree
+ * the parent tree
+ * @param treeItemName
+ * the tree item name that we are looking for availability
+ * @param expectedToBeFound
+ * the expected availability status
+ */
+ public TreeItemAvailableCondition(SWTBotTree tree, String treeItemName, boolean expectedToBeFound) {
+ this.tree = tree;
+ this.treeItemName = treeItemName;
+ this.expectedToBeFound = expectedToBeFound;
+ }
+
+ /**
+ * Default constructor.
+ *
+ * @param treeItem
+ * the parent tree item
+ * @param treeItemName
+ * the tree item name that we are looking for availability
+ * @param expectedToBeFound
+ * the expected availability status
+ */
+ public TreeItemAvailableCondition(SWTBotTreeItem treeItem, String treeItemName, boolean expectedToBeFound) {
+ this.treeItem = treeItem;
+ this.treeItemName = treeItemName;
+ this.expectedToBeFound = expectedToBeFound;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The tree item " + treeItemName + " has not been found";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ try {
+ if (tree != null) {
+ tree.getTreeItem(treeItemName);
+ } else {
+ treeItem.getNode(treeItemName);
+ }
+ return expectedToBeFound;
+ } catch (WidgetNotFoundException e) {
+ return !expectedToBeFound;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemChildrenNumberCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemChildrenNumberCondition.java
new file mode 100644
index 0000000000..6818759d37
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemChildrenNumberCondition.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * A condition testing the number of children items of a {@link SWTBotTreeItem}.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class TreeItemChildrenNumberCondition extends DefaultCondition {
+
+ private final SWTBotTreeItem treeItem;
+
+ private final int expectedNumberOfChild;
+
+ private boolean forceTreeItemExpand;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * The {@link SWTBotTreeItem} to test its children
+ * @param expectedNumberOfChild
+ * The number of children expected for treeItem
+ */
+ public TreeItemChildrenNumberCondition(SWTBotTreeItem treeItem, int expectedNumberOfChild) {
+ this.treeItem = treeItem;
+ this.expectedNumberOfChild = expectedNumberOfChild;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * The {@link SWTBotTreeItem} to test its children
+ * @param expectedNumberOfChild
+ * The number of children expected for treeItem
+ * @param forceTreeItemExpand
+ * should expand treeItem before running test
+ */
+ public TreeItemChildrenNumberCondition(SWTBotTreeItem treeItem, int expectedNumberOfChild, boolean forceTreeItemExpand) {
+ this.treeItem = treeItem;
+ this.expectedNumberOfChild = expectedNumberOfChild;
+ this.forceTreeItemExpand = forceTreeItemExpand;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The TreeItem " + treeItem.getText() + " has " + treeItem.getItems().length + " children instead of the expected " + expectedNumberOfChild;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ if (forceTreeItemExpand) {
+ treeItem.expand();
+ }
+ return treeItem.getItems().length == expectedNumberOfChild;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemContainsAtLeastOneChild.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemContainsAtLeastOneChild.java
new file mode 100644
index 0000000000..2b4c8527da
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemContainsAtLeastOneChild.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to wait that a tree item is expanded AND its children are
+ * visible.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class TreeItemContainsAtLeastOneChild extends DefaultCondition {
+ private final SWTBotTreeItem treeItem;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * The treeItem to wait to be expanded and contains at least one
+ * visible child
+ */
+ public TreeItemContainsAtLeastOneChild(SWTBotTreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "tree item does not contains child";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ RunnableWithResult<Boolean> runnable = new RunnableWithResult.Impl<Boolean>() {
+ @Override
+ public void run() {
+ treeItem.widget.getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ setResult(treeItem.getItems().length > 0);
+ }
+ });
+ }
+ };
+ treeItem.widget.getDisplay().syncExec(runnable);
+ return ((Boolean) runnable.getResult()).booleanValue();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemExpanded.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemExpanded.java
new file mode 100644
index 0000000000..d3819e2f71
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemExpanded.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to wait that a tree item is expanded.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class TreeItemExpanded extends DefaultCondition {
+ private final TreeItem widget;
+
+ private final String name;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * The {@link SWTBotTreeItem} to wait to be expanded
+ * @param name
+ * The name of the tree item
+ */
+ public TreeItemExpanded(final SWTBotTreeItem treeItem, String name) {
+ this.widget = treeItem.widget;
+ this.name = name;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "tree item with text " + name + " is not expanded";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ RunnableWithResult<Boolean> runnable = new RunnableWithResult.Impl<Boolean>() {
+ @Override
+ public void run() {
+ widget.getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ setResult(widget.getExpanded());
+ }
+ });
+ }
+ };
+ widget.getDisplay().syncExec(runnable);
+ return runnable.getResult().booleanValue();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemSelected.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemSelected.java
new file mode 100644
index 0000000000..56cc746703
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemSelected.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to wait that a tree item is selected.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class TreeItemSelected extends DefaultCondition {
+ private final SWTBotTreeItem item;
+
+ /**
+ * Constructor.
+ *
+ * @param item
+ * The item to wait to be selected
+ */
+ public TreeItemSelected(final SWTBotTreeItem item) {
+ this.item = item;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "tree item with text " + item.getText() + " is not selected";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ RunnableWithResult<Boolean> runnable = new RunnableWithResult.Impl<Boolean>() {
+ @Override
+ public void run() {
+ item.display.syncExec(new Runnable() {
+ @Override
+ public void run() {
+ setResult(item.isSelected());
+ }
+ });
+ }
+ };
+ item.display.syncExec(runnable);
+ return ((Boolean) runnable.getResult()).booleanValue();
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemTextCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemTextCondition.java
new file mode 100644
index 0000000000..49a8b91ed8
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/TreeItemTextCondition.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * This class helps to wait that a tree item is renamed.
+ *
+ * @author mporhel
+ */
+public class TreeItemTextCondition extends DefaultCondition {
+
+ private final SWTBotTreeItem treeItem;
+
+ private final String expectedName;
+
+ /**
+ * Constructor.
+ *
+ * @param treeItem
+ * the item to check
+ * @param expectedName
+ * the expected new name.
+ */
+ public TreeItemTextCondition(SWTBotTreeItem treeItem, String expectedName) {
+ this.treeItem = treeItem;
+ this.expectedName = expectedName;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return expectedName.equals(treeItem.getText());
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "tree item with text " + treeItem.getText() + " was not renamed into " + expectedName;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ViewpointSelectionCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ViewpointSelectionCondition.java
new file mode 100644
index 0000000000..5464a5f348
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/ViewpointSelectionCondition.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.sirius.business.api.session.Session;
+import org.eclipse.sirius.viewpoint.description.Viewpoint;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+
+/**
+ * A condition waiting for a viewpoints selection.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class ViewpointSelectionCondition extends DefaultCondition {
+
+ private final Session session;
+
+ private final String viewpointName;
+
+ /**
+ * Constructor.
+ *
+ * @param session
+ * the current {@link Session}
+ * @param viewpointName
+ * the name of the viewpoint we are waiting for its selection
+ */
+ public ViewpointSelectionCondition(final Session session, final String viewpointName) {
+ this.session = session;
+ this.viewpointName = viewpointName;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The expected viewpoint has not been selected";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ for (Viewpoint viewpoint : session.getSelectedViewpoints(false)) {
+ if (viewpoint.getName().equals(viewpointName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsDisabledCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsDisabledCondition.java
new file mode 100644
index 0000000000..63b0424d53
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsDisabledCondition.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+
+/**
+ * A Condition to test if a widget is disabled.
+ *
+ * @author hmarchadour
+ */
+public class WidgetIsDisabledCondition extends DefaultCondition {
+
+ private final AbstractSWTBot<? extends Widget> widget;
+
+ /**
+ * Default Constructor.
+ *
+ * @param widget
+ * the widget to test
+ */
+ public WidgetIsDisabledCondition(AbstractSWTBot<? extends Widget> widget) {
+ this.widget = widget;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return !widget.isEnabled();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The widget " + widget + " was enabled.";
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsEnabledCondition.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsEnabledCondition.java
new file mode 100644
index 0000000000..3a6d9bf517
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/condition/WidgetIsEnabledCondition.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.condition;
+
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+
+/**
+ * A Condition to test if a widget is enable.
+ *
+ * @author hmarchadour
+ */
+public class WidgetIsEnabledCondition extends DefaultCondition {
+
+ private final AbstractSWTBot<? extends Widget> widget;
+
+ /**
+ * Default Constructor.
+ *
+ * @param widget
+ * the widget to test
+ */
+ public WidgetIsEnabledCondition(AbstractSWTBot<? extends Widget> widget) {
+ this.widget = widget;
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return widget.isEnabled();
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "The widget " + widget + " was not enabled.";
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ExportAsImageHelper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ExportAsImageHelper.java
new file mode 100644
index 0000000000..c9f3933ff9
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ExportAsImageHelper.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.dialog;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin;
+
+/**
+ * A class to allow cleaning of AbstractExportRepresentationsAsImagesDialog
+ * settings.
+ *
+ * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a>
+ */
+public class ExportAsImageHelper {
+
+ /**
+ * The id for the persistent settings for the export representations dialog.
+ */
+ private static final String DIALOG_SETTINGS_ID = "ExportRepresentationsAsImagesDialog"; //$NON-NLS-1$
+
+ /**
+ * The id for the persistent folder setting for the export representations
+ * dialog.
+ */
+ private static final String DIALOG_SETTINGS_FOLDER = "ExportRepresentationsAsImagesDialog.folder"; //$NON-NLS-1$
+
+ /**
+ * The id for the persistent file setting for the export representations
+ * dialog.
+ */
+ private static final String DIALOG_SETTINGS_FILE = "ExportRepresentationsAsImagesDialog.file"; //$NON-NLS-1$
+
+ /**
+ * Default constructor.
+ */
+ public ExportAsImageHelper() {
+ }
+
+ /**
+ * Retrieves the persistent settings for this dialog.
+ *
+ * @return the persistent settings for this dialog.
+ */
+ protected IDialogSettings getDialogSettings() {
+ IDialogSettings settings = SiriusEditPlugin.getPlugin().getDialogSettings();
+ settings = settings.getSection(ExportAsImageHelper.DIALOG_SETTINGS_ID);
+ if (settings == null) {
+ settings = SiriusEditPlugin.getPlugin().getDialogSettings().addNewSection(ExportAsImageHelper.DIALOG_SETTINGS_ID);
+ }
+ return settings;
+ }
+
+ /**
+ * Reset all dialog settings.
+ */
+ public void resetDialogSettings() {
+ final IDialogSettings dialogSettings = getDialogSettings();
+ if (dialogSettings != null) {
+ dialogSettings.put(ExportAsImageHelper.DIALOG_SETTINGS_FOLDER, new String[0]);
+ dialogSettings.put(ExportAsImageHelper.DIALOG_SETTINGS_FILE, new String[0]);
+ }
+ }
+
+ /**
+ * Reset all folders setting dialog.
+ */
+ public void resetDialogFolderSettings() {
+ final IDialogSettings dialogSettings = getDialogSettings();
+ if (dialogSettings != null) {
+ dialogSettings.put(ExportAsImageHelper.DIALOG_SETTINGS_FOLDER, new String[0]);
+ }
+ }
+
+ /**
+ * Reset file setting dialog.
+ */
+ public void resetDialogFileSettings() {
+ final IDialogSettings dialogSettings = getDialogSettings();
+ if (dialogSettings != null) {
+ dialogSettings.put(ExportAsImageHelper.DIALOG_SETTINGS_FILE, new String[0]);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ViewpointSelectionDialog.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ViewpointSelectionDialog.java
new file mode 100644
index 0000000000..e91fab8b54
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/dialog/ViewpointSelectionDialog.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.dialog;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
+import org.junit.Assert;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+
+/**
+ * Wrapper for viewpoints selection dialog.
+ *
+ * @author dlecan
+ */
+public class ViewpointSelectionDialog {
+ /**
+ * The title of the Viewpoints selection dialog.
+ */
+ public static final String VIEWPOINT_DIALOG_NAME = "Viewpoints Selection";
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Create a new instance.
+ *
+ * @param bot
+ * the SWT bot
+ */
+ public ViewpointSelectionDialog(final SWTWorkbenchBot bot) {
+ this.bot = bot;
+ }
+
+ /**
+ * "Select Viewpoints" operation (when creating a new local session, either
+ * via wizard or drag and drop of model in local session view).
+ * <p>
+ * If a viewpoint is provided in both sets, this viewpoint will be selected.
+ * Unselection action will be ignored.
+ * </p>
+ *
+ * @param viewpointToSelect
+ * Viewpoint to select.
+ * @param viewpointToDeselect
+ * Viewpoint to deselect.
+ */
+ public void selectViewpoint(final Set<String> viewpointToSelect, final Set<String> viewpointToDeselect) {
+ bot.waitUntil(Conditions.shellIsActive(ViewpointSelectionDialog.VIEWPOINT_DIALOG_NAME));
+
+ final SWTBotShell shellViewpointsSelection = bot.shell(ViewpointSelectionDialog.VIEWPOINT_DIALOG_NAME);
+
+ if (viewpointToSelect != null && viewpointToDeselect != null) {
+ final SetView<String> allViewpointNames = Sets.union(viewpointToSelect, viewpointToDeselect);
+
+ final Map<String, Boolean> viewpointSelection = Maps.newHashMap();
+
+ for (final String vpName : allViewpointNames) {
+ viewpointSelection.put(vpName, viewpointToSelect.contains(vpName));
+ }
+
+ if (!viewpointSelection.isEmpty()) {
+ for (int rowPosition = 0; rowPosition < bot.table().rowCount(); rowPosition++) {
+
+ final SWTBotTableItem item = bot.table().getTableItem(rowPosition);
+ final String text = item.getText(2);
+
+ if (viewpointSelection.containsKey(text)) {
+ bot.table().click(rowPosition, 0);
+ viewpointSelection.remove(text);
+ }
+ }
+ failIfMissingViewpoints(viewpointSelection);
+
+ final SWTBotButton okButton = bot.button("OK");
+
+ bot.waitUntil(new DefaultCondition() {
+
+ @Override
+ public String getFailureMessage() {
+ return "OK button is not enabled";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return okButton.isEnabled();
+ }
+
+ });
+ }
+ }
+ bot.button("OK").click();
+ SWTBotUtils.waitProgressMonitorClose("Progress Information");
+ bot.waitUntil(Conditions.shellCloses(shellViewpointsSelection));
+
+ SWTBotUtils.waitProgressMonitorClose("Apply new viewpoints selection");
+ }
+
+ private void failIfMissingViewpoints(final Map<String, Boolean> remainingViewpoints) {
+ final StringBuilder message = new StringBuilder();
+ for (final String vpName : remainingViewpoints.keySet()) {
+ message.append("\"");
+ message.append(vpName);
+ message.append("\" ");
+ }
+ if (message.length() > 0) {
+ message.append(" viewpoint(s) was/were not found");
+ Assert.fail(message.toString());
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerEditor.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerEditor.java
new file mode 100644
index 0000000000..151650c783
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerEditor.java
@@ -0,0 +1,1572 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.editor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.ConnectionEditPart;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.editparts.AbstractConnectionEditPart;
+import org.eclipse.gef.palette.ToolEntry;
+import org.eclipse.gef.requests.DirectEditRequest;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.AbstractBorderedShapeEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.internal.properties.WorkspaceViewerProperties;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.sirius.common.tools.api.util.ReflectionHelper;
+import org.eclipse.sirius.diagram.part.SiriusDiagramEditorPlugin;
+import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramPreferencesKeys;
+import org.eclipse.sirius.diagram.ui.business.internal.dialect.DiagramDialectUIServices;
+import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart;
+import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNameEditPart;
+import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNodeEditPart;
+import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeBeginNameEditPart;
+import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeEndNameEditPart;
+import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeNameEditPart;
+import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.ext.draw2d.figure.FigureUtilities;
+import org.eclipse.sirius.tests.support.api.TestsUtil;
+import org.eclipse.sirius.tests.swtbot.support.api.bot.SWTDesignerBot;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation.ZoomLevel;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.SWTBotSiriusFigureCanvas;
+import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.gef.finder.matchers.IsInstanceOf;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefConnectionEditPart;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefFigureCanvas;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.hamcrest.Matcher;
+import org.junit.Assert;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/**
+ * Override some methods to GEF editor.
+ *
+ * @author nlepine
+ */
+public class SWTBotDesignerEditor extends SWTBotGefEditor {
+ static final String EXPECTED_TO_FIND_WIDGET_S = "Expected to find widget %s";
+
+ private static final String EXPECTED_TO_FIND_WIDGET_X_Y = "Expected to find widget at %s, %s";
+
+ private static final String EXPECTED_TO_FIND_WIDGET_OF_TYPE_T = "Expected to find widget of type %s";
+
+ private static final String EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S = "Expected to find widget %s of type IGraphicalEditPart";
+
+ /**
+ * Inner special SWTBot.
+ */
+ protected SWTDesignerBot designerBot = new SWTDesignerBot();
+
+ /**
+ * Construct a new instance.
+ *
+ * @param reference
+ * the editor reference
+ * @param bot
+ * the workbench bot
+ * @throws WidgetNotFoundException
+ * if an exception occurs
+ */
+ public SWTBotDesignerEditor(final IEditorReference reference, final SWTWorkbenchBot bot) throws WidgetNotFoundException {
+ super(reference, bot);
+
+ GraphicalViewer graphicalViewer = UIThreadRunnable.syncExec(new Result<GraphicalViewer>() {
+ @Override
+ public GraphicalViewer run() {
+
+ final IEditorPart editor = partReference.getEditor(true);
+ return (GraphicalViewer) editor.getAdapter(GraphicalViewer.class);
+ }
+ });
+
+ ReflectionHelper.setFieldValueWithoutException(this, "viewer", new SWTBotDesignerGefViewer(graphicalViewer), this.getClass().getSuperclass());
+ }
+
+ /**
+ * Returns the canvas.
+ *
+ * @return the canvas.
+ */
+ public SWTBotGefFigureCanvas getCanvas() {
+ Option<Object> fieldValueWithoutException = ReflectionHelper.getFieldValueWithoutException(getSWTBotGefViewer(), "canvas", getSWTBotGefViewer().getClass().getSuperclass());
+ if (fieldValueWithoutException.some() && fieldValueWithoutException.get() instanceof SWTBotGefFigureCanvas) {
+ return (SWTBotGefFigureCanvas) fieldValueWithoutException.get();
+ }
+
+ return null;
+ }
+
+ @Override
+ public void click(final String label) {
+ final SWTBotGefEditPart selectedEP = getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ final Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) selectedEP.part()).getFigure().translateToAbsolute(bounds);
+ /* add height -1 for designer */
+ click(bounds.x, bounds.y + bounds.height - 1);
+ }
+
+ /**
+ * Click on the edit part (of correct type) which owns the specified label
+ * at the top left hand corner of its bounds.
+ *
+ * @param label
+ * the label to retrieve edit part to click on
+ * @param expectedEditPartType
+ * the type of the editPart to return if found one
+ */
+ public void click(final String label, final Class<? extends EditPart> expectedEditPartType) {
+ final SWTBotGefEditPart selectedEP = getEditPart(label, expectedEditPartType);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ final Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) selectedEP.part()).getFigure().translateToAbsolute(bounds);
+ /* add height - 1 for designer */
+ click(bounds.x, bounds.y + bounds.height - 1);
+ }
+
+ /**
+ * Helper to click with a Point as parameter.
+ *
+ * @param point
+ * the coordinate to click on described as a Point. This
+ * coordinates is relative to screen.
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#click(int,
+ * int)
+ */
+ public void click(final Point point) {
+ click(point.x, point.y);
+ }
+
+ /**
+ * Clicks on the center of the targeted GraphicalEditPart known by its
+ * label.
+ *
+ * @param label
+ * the label of the GraphicalEditPart to click on its center.
+ * @return The absolute bounds of the edit part
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#click(java.lang.String)
+ */
+ public Rectangle clickCentered(final String label) {
+ final SWTBotGefEditPart selectedEP = getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ final Rectangle bounds;
+ if (selectedEP.part() instanceof AbstractDiagramNameEditPart) {
+ bounds = ((GraphicalEditPart) selectedEP.part().getParent()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) selectedEP.part().getParent()).getFigure().translateToAbsolute(bounds);
+ } else {
+ bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) selectedEP.part()).getFigure().translateToAbsolute(bounds);
+ }
+ /* add height for designer */
+ click(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
+ return bounds;
+ }
+
+ /**
+ * Clicks on the center of the targeted GraphicalEditPart known by its
+ * label.
+ *
+ * @param label
+ * the label of the GraphicalEditPart to click on its center.
+ * @param expectedEditPartType
+ * the type of the editPart to return if found one
+ * @return The absolute bounds of the edit part
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#click(java.lang.String)
+ */
+ public Rectangle clickCentered(final String label, final Class<? extends EditPart> expectedEditPartType) {
+ // Get the corresponding edit part.
+ final SWTBotGefEditPart selectedEP = getEditPart(label, expectedEditPartType);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ return clickCentered(selectedEP);
+ }
+
+ /**
+ * Clicks on the center of the targeted GraphicalEditPart known by its label
+ * and then return its bounds.
+ *
+ * @param partToClick
+ * GraphicalEditPart to click on its center.
+ * @return The absolute bounds of the edit part
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#click(java.lang.String)
+ */
+ public Rectangle clickCentered(SWTBotGefEditPart partToClick) {
+ // Get the absolute bounds of the edit part.
+ Assert.assertTrue("This editPart should be a GraphicalEditPart.", partToClick.part() instanceof GraphicalEditPart);
+ Rectangle bounds = ((GraphicalEditPart) partToClick.part()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) partToClick.part()).getFigure().translateToAbsolute(bounds);
+ // Click on its center
+ click(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
+ // Return the absolute bounds.
+ return bounds;
+ }
+
+ /**
+ * Clicks just below (+1 pixel) of the middle of the north side of the
+ * targeted GraphicalEditPart and then return its bounds.
+ *
+ * @param partToClick
+ * GraphicalEditPart to click on its center.
+ * @return The absolute bounds of the edit part
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#click(java.lang.String)
+ */
+ public Rectangle clickNorth(SWTBotGefEditPart partToClick) {
+ // Get the absolute bounds of the edit part.
+ Assert.assertTrue("This editPart should be a GraphicalEditPart.", partToClick.part() instanceof GraphicalEditPart);
+ Rectangle bounds = ((GraphicalEditPart) partToClick.part()).getFigure().getBounds().getCopy();
+ ((GraphicalEditPart) partToClick.part()).getFigure().translateToAbsolute(bounds);
+ // Click on its center
+ click(bounds.getTop().x, bounds.getTop().y + 1);
+ // Return the absolute bounds.
+ return bounds;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#drag(java.lang.String,
+ * int, int)
+ */
+ @Override
+ public void drag(final String label, final int toXPosition, final int toYPosition) {
+ final SWTBotGefEditPart selectedEP = getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ final Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds();
+ drag(bounds.x, bounds.y + bounds.height / 2, toXPosition, toYPosition);
+ }
+
+ /**
+ *
+ * Uses the generic mouseDrag functionality to drag the item from its
+ * center.
+ *
+ * @param label
+ * the label
+ * @param toXPosition
+ * the relative x position within the graphical viewer to drag to
+ * @param toYPosition
+ * the relative y position within the graphical viewer to drag to
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#drag(java.lang.String,
+ * int, int)
+ */
+ public void dragCentered(final String label, final int toXPosition, final int toYPosition) {
+ final SWTBotGefEditPart selectedEP = getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ final Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds();
+ drag(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, toXPosition, toYPosition);
+ }
+
+ /**
+ * Get the EditPartBot representing the EditPart at this location.
+ *
+ * @param location
+ * the Point where to search a EditPart. This coordinates is
+ * logical (not relative to screen).
+ * @param expectedEditPartType
+ * the type of the editPart to return if found one
+ * @return the EditPartBot representing the EditPart at this location
+ */
+ public SWTBotGefEditPart getEditPart(Point location, Class<? extends EditPart> expectedEditPartType) {
+ return getEditPart(mainEditPart(), location, expectedEditPartType);
+ }
+
+ /**
+ * Get the EditPartBot representing the EditPart at this location.
+ *
+ * @param editPartBotWhereToSearch
+ * the EditPartBot where to search.
+ * @param location
+ * the Point where to search a EditPart
+ * @param expectedEditPartType
+ * the type of the editPart to return if found one
+ * @return the EditPartBot representing the EditPart at this location
+ */
+ public SWTBotGefEditPart getEditPart(SWTBotGefEditPart editPartBotWhereToSearch, Point location, Class<? extends EditPart> expectedEditPartType) {
+ SWTBotGefEditPart result = null;
+ if (!editPartBotWhereToSearch.children().isEmpty()) {
+ for (SWTBotGefEditPart childEditPartBot : editPartBotWhereToSearch.children()) {
+ SWTBotGefEditPart candidate = getEditPart(childEditPartBot, location, expectedEditPartType);
+ if (candidate == null) {
+ if (getBounds(childEditPartBot).contains(location) && expectedEditPartType.isInstance(childEditPartBot.part())) {
+ candidate = childEditPartBot;
+ }
+ }
+ if (candidate != null && result != null) {
+ boolean sameParent = result.part().getParent().equals(candidate.part().getParent());
+ boolean indexSuperior = candidate.part().getParent().getChildren().indexOf(candidate.part()) > result.part().getParent().getChildren().indexOf(result.part());
+ if (sameParent && indexSuperior) {
+ result = candidate;
+ }
+ } else if (result == null) {
+ result = candidate;
+ }
+ }
+ } else {
+ if (getBounds(editPartBotWhereToSearch).contains(location) && expectedEditPartType.isInstance(editPartBotWhereToSearch.part())) {
+ result = editPartBotWhereToSearch;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SWTBotGefEditPart getEditPart(final String label) {
+ final SWTBotGefEditPart selectedEP = super.getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ return selectedEP;
+ }
+
+ /**
+ * Get the edit part with the label as a singleton selection. If the edit
+ * part corresponding to the label is not of the expected type, we searched
+ * in the parent hierarchy of this edit part.
+ *
+ * @param label
+ * The searched label
+ * @param expectedEditPartType
+ * The type of the expected edit part
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getEditPart(final String label, final Class<? extends EditPart> expectedEditPartType) {
+ SWTBotGefEditPart selectedEP = super.getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ if (!expectedEditPartType.isInstance(selectedEP.part())) {
+ selectedEP = getParentEditPart(selectedEP, expectedEditPartType);
+ }
+ return selectedEP;
+ }
+
+ /**
+ * Search in the parent hierarchy of <code>editPart</code>, the first one of
+ * type <code>expectedEditPartType</code>.
+ *
+ * @param editPart
+ * The start editPart
+ * @param expectedEditPartType
+ * The type of the expected edit part
+ * @return the corresponding SWTBotGefEditPart
+ */
+ private SWTBotGefEditPart getParentEditPart(SWTBotGefEditPart editPart, final Class<? extends EditPart> expectedEditPartType) {
+ SWTBotGefEditPart parent = editPart.parent();
+ if (parent == null || parent.part() == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_OF_TYPE_T, expectedEditPartType.getCanonicalName()));
+ }
+ if (!expectedEditPartType.isInstance(parent.part())) {
+ parent = getParentEditPart(parent, expectedEditPartType);
+ }
+ return parent;
+ }
+
+ /**
+ * Get the RootEditPart bot for the palette.
+ *
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getPaletteRootEditPartBot() {
+ return ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).getPaletteRootEditPartBot();
+ }
+
+ /**
+ * Get the GroupEditPart bot for the palette corresponding to tool provided
+ * by *.odesign modeler.
+ *
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getSiriusPaletteGroupEditPartBot() {
+ return ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).getSiriusPaletteGroupEditPartBot();
+ }
+
+ /**
+ * Get all {@link SWTBotGefConnectionEditPart} between the edit parts.
+ *
+ * @param sourceEditPart
+ * Source edit part.
+ * @param targetEditPart
+ * Target edit part.
+ * @return All connection edit parts (cannot be <code>null</code>)
+ */
+ public List<SWTBotGefConnectionEditPart> getConnectionEditPart(final SWTBotGefEditPart sourceEditPart, final SWTBotGefEditPart targetEditPart) {
+ final Set<SWTBotGefConnectionEditPart> sourceConnections = new HashSet<SWTBotGefConnectionEditPart>(sourceEditPart.sourceConnections());
+ final Set<SWTBotGefConnectionEditPart> targetConnections = new HashSet<SWTBotGefConnectionEditPart>(targetEditPart.targetConnections());
+
+ sourceConnections.retainAll(targetConnections);
+
+ return new ArrayList<SWTBotGefConnectionEditPart>(sourceConnections);
+ }
+
+ /**
+ * Get all {@link SWTBotGefConnectionEditPart}.
+ *
+ * @return All connection edit parts (cannot be <code>null</code>)
+ */
+ public List<SWTBotGefConnectionEditPart> getConnectionsEditPart() {
+ Set<SWTBotGefConnectionEditPart> resultList = new HashSet<SWTBotGefConnectionEditPart>();
+ resultList.addAll(mainEditPart().sourceConnections());
+ resultList.addAll(mainEditPart().targetConnections());
+ Iterator<SWTBotGefEditPart> iteratorchildren = getAllChildrenSWTBotGefEditPart(mainEditPart()).iterator();
+
+ while (iteratorchildren.hasNext()) {
+ SWTBotGefEditPart currentEditPart = iteratorchildren.next();
+ resultList.addAll(currentEditPart.sourceConnections());
+ resultList.addAll(currentEditPart.targetConnections());
+ }
+
+ return new ArrayList<SWTBotGefConnectionEditPart>(resultList);
+ }
+
+ /**
+ * Returns the current selection in the active part. If the selection in the
+ * active part is <em>undefined</em> (the active part has no selection
+ * provider) the result will be <code>null</code>.
+ *
+ * @return the current selection, or <code>null</code> if undefined
+ */
+ public ISelection getSelection() {
+ return partReference.getPage().getSelection();
+ }
+
+ /**
+ * Do direct edit part for nodes.
+ *
+ * @param editPartLabel
+ * Label of edit part to edit text.
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directNodeEditType(final String editPartLabel, final String text) {
+ directEditType(text, getEditPart(editPartLabel));
+ }
+
+ /**
+ * Tells if direct edit is possible on the specified
+ * {@link SWTBotGefEditPart}.
+ *
+ * @param swtBotGefEditPart
+ * the specified {@link SWTBotGefEditPart}
+ * @return true if direct edit is possible on the specified
+ * {@link SWTBotGefEditPart}, false else
+ */
+ public boolean isDirectEditPossible(SWTBotGefEditPart swtBotGefEditPart) {
+ boolean isDirectEditPossible = false;
+ final EditPart editPart = swtBotGefEditPart.part();
+ final DirectEditRequest request = new DirectEditRequest();
+
+ /*
+ * Workaround for GMF based modelers -> need to be in a SWTBotGMFEditor
+ */
+ request.getExtendedData().put(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR, '_');
+
+ if (editPart instanceof GraphicalEditPart) {
+ // Sets the location to avoid having NPE later
+ GraphicalEditPart gep = (GraphicalEditPart) editPart;
+ request.setLocation(gep.getFigure().getBounds().getLocation());
+ }
+
+ isDirectEditPossible = UIThreadRunnable.syncExec(new Result<Boolean>() {
+ @Override
+ public Boolean run() {
+ editPart.performRequest(request);
+ Matcher<Text> matcher = WidgetMatcherFactory.allOf(WidgetMatcherFactory.widgetOfType(Text.class));
+ List<Text> findControls = bot().getFinder().findControls(matcher);
+ return !findControls.isEmpty();
+ }
+ });
+ return isDirectEditPossible;
+ }
+
+ /**
+ * Do direct edit for {@link SWTBotGefEditPart}'s editPart.
+ *
+ * @param text
+ * text to put
+ * @param swtBotGefEditPart
+ * bot editPart to edit
+ */
+ public void directEditType(final String text, final SWTBotGefEditPart swtBotGefEditPart) {
+ final EditPart editPart = swtBotGefEditPart.part();
+ final DirectEditRequest request = new DirectEditRequest();
+
+ /*
+ * Workaround for GMF based modelers -> need to be in a SWTBotGMFEditor
+ */
+ request.getExtendedData().put(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR, '_');
+
+ if (editPart instanceof GraphicalEditPart) {
+ // Sets the location to avoid having NPE later
+ GraphicalEditPart gep = (GraphicalEditPart) editPart;
+ request.setLocation(gep.getFigure().getBounds().getLocation());
+ }
+
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ editPart.performRequest(request);
+ directEditType(text);
+ }
+ });
+
+ }
+
+ private void directEditType(final String text, final EditPart editPart) {
+ final Request request = new DirectEditRequest();
+
+ /*
+ * Workaround for GMF based modelers -> need to be in a SWTBotGMFEditor
+ */
+ request.getExtendedData().put(RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR, '_');
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ editPart.performRequest(request);
+ directEditType(text);
+ }
+ });
+ }
+
+ /**
+ * Do direct edit part for edges.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditType(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditType(sourceEditPartLabel, targetEditPartLabel, text, 0, DEdgeNameEditPart.class);
+ }
+
+ /**
+ * Do direct edit part for edges.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditTypeBeginLabel(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditType(sourceEditPartLabel, targetEditPartLabel, text, 0, DEdgeBeginNameEditPart.class);
+ }
+
+ /**
+ * Do direct edit part for edges.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditTypeCenterLabel(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditType(sourceEditPartLabel, targetEditPartLabel, text);
+ }
+
+ /**
+ * Do direct edit part for edges.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditTypeEndLabel(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditType(sourceEditPartLabel, targetEditPartLabel, text, 0, DEdgeEndNameEditPart.class);
+ }
+
+ /**
+ * Do direct edit part for edges connected on nodes or its border nodes with
+ * label sourceEditPartLabel and targetEditPartLabel.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditTypeExtendedToBorderNodes(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditTypeExtendedToBorderNodes(sourceEditPartLabel, targetEditPartLabel, text, 0);
+ }
+
+ /**
+ * Do direct edit part for edges connected on border nodes of the nodes with
+ * label sourceEditPartLabel and targetEditPartLabel.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ */
+ public void directEdgeEditTypeOnBorderNodesOnly(final String sourceEditPartLabel, final String targetEditPartLabel, final String text) {
+ directEdgeEditTypeOnBorderNodesOnly(sourceEditPartLabel, targetEditPartLabel, text, 0);
+ }
+
+ /**
+ * Do direct edit part for edges.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ * @param index
+ * Position of edge to edit.
+ * @param labelClass
+ * used to choose between begin, center and end label
+ */
+ public void directEdgeEditType(final String sourceEditPartLabel, final String targetEditPartLabel, final String text, final int index, Class<? extends EditPart> labelClass) {
+ final List<SWTBotGefConnectionEditPart> connectionEditPart = getConnectionEditPart(getEditPart(sourceEditPartLabel).parent(), getEditPart(targetEditPartLabel).parent());
+ final SWTBotGefConnectionEditPart swtBotGefConnectionEditPart = connectionEditPart.get(index);
+
+ // Retreive first children, as this is this edit part which owns edge
+ // label
+
+ // directEditType(text, (EditPart)
+ // swtBotGefConnectionEditPart.part().getChildren().get(0));
+ directEditType(text, Iterables.getOnlyElement(Iterables.filter(swtBotGefConnectionEditPart.part().getChildren(), labelClass)));
+ }
+
+ /**
+ * Do direct edit part for edges connected on border nodes of the nodes with
+ * label sourceEditPartLabel and targetEditPartLabel.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ * @param index
+ * Position of edge to edit.
+ */
+ public void directEdgeEditTypeOnBorderNodesOnly(final String sourceEditPartLabel, final String targetEditPartLabel, final String text, final int index) {
+ final List<SWTBotGefConnectionEditPart> connectionEditPart = new ArrayList<SWTBotGefConnectionEditPart>();
+ SWTBotGefEditPart parentSource = getEditPart(sourceEditPartLabel).parent();
+ SWTBotGefEditPart parentTarget = getEditPart(targetEditPartLabel).parent();
+ List<SWTBotGefEditPart> sourceChildren = getAllChildrenSWTBotGefEditPart(parentSource);
+ List<SWTBotGefEditPart> targetChildren = getAllChildrenSWTBotGefEditPart(parentTarget);
+ for (SWTBotGefEditPart sourceChild : sourceChildren) {
+ for (SWTBotGefEditPart targetChild : targetChildren) {
+ connectionEditPart.addAll(getConnectionEditPart(sourceChild, targetChild));
+ }
+ }
+
+ final SWTBotGefConnectionEditPart swtBotGefConnectionEditPart = connectionEditPart.get(index);
+
+ // Retreive first children, as this is this edit part which owns edge
+ // label
+ directEditType(text, (EditPart) swtBotGefConnectionEditPart.part().getChildren().get(0));
+ }
+
+ /**
+ * Do direct edit part for edges connected on nodes or its border nodes with
+ * label sourceEditPartLabel and targetEditPartLabel.
+ *
+ * @param sourceEditPartLabel
+ * Source edit part label
+ * @param targetEditPartLabel
+ * Target edit part label
+ *
+ * @param text
+ * New text to use to edit edit part name.
+ * @param index
+ * Position of edge to edit.
+ */
+ public void directEdgeEditTypeExtendedToBorderNodes(final String sourceEditPartLabel, final String targetEditPartLabel, final String text, final int index) {
+ SWTBotGefEditPart parentSource = getEditPart(sourceEditPartLabel).parent();
+ SWTBotGefEditPart parentTarget = getEditPart(targetEditPartLabel).parent();
+ final List<SWTBotGefConnectionEditPart> connectionEditPart = getConnectionEditPart(parentSource, parentTarget);
+ List<SWTBotGefEditPart> sourceChildren = getAllChildrenSWTBotGefEditPart(parentSource);
+ List<SWTBotGefEditPart> targetChildren = getAllChildrenSWTBotGefEditPart(parentTarget);
+ for (SWTBotGefEditPart sourceChild : sourceChildren) {
+ connectionEditPart.addAll(getConnectionEditPart(sourceChild, parentTarget));
+ for (SWTBotGefEditPart targetChild : targetChildren) {
+ connectionEditPart.addAll(getConnectionEditPart(parentSource, targetChild));
+ connectionEditPart.addAll(getConnectionEditPart(sourceChild, targetChild));
+ }
+ }
+
+ final SWTBotGefConnectionEditPart swtBotGefConnectionEditPart = connectionEditPart.get(index);
+
+ // Retreive first children, as this is this edit part which owns edge
+ // label
+ directEditType(text, (EditPart) swtBotGefConnectionEditPart.part().getChildren().get(0));
+ }
+
+ /**
+ * finds all SWTBotGefEditPart children in a SWTBotGefEditPart.
+ *
+ * @param swtbotGefEditPart
+ * the parent
+ * @return all SWTBotGefEditPart children
+ */
+ private List<SWTBotGefEditPart> getAllChildrenSWTBotGefEditPart(SWTBotGefEditPart swtbotGefEditPart) {
+ ArrayList<SWTBotGefEditPart> swtbotGefEditPartList = Lists.newArrayList();
+ swtbotGefEditPartList.addAll(swtbotGefEditPart.children());
+ for (SWTBotGefEditPart swtBotGefEditPartChild : swtbotGefEditPart.children()) {
+ swtbotGefEditPartList.addAll(getAllChildrenSWTBotGefEditPart(swtBotGefEditPartChild));
+ }
+ return swtbotGefEditPartList;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditor#clickContextMenu(java.lang.String)
+ */
+ @Override
+ public SWTBotGefEditor clickContextMenu(String text) throws WidgetNotFoundException {
+ SWTBotGefEditor swtBotGefEditor = super.clickContextMenu(text);
+ SWTBotUtils.waitAllUiEvents();
+ return swtBotGefEditor;
+ }
+
+ /**
+ * Right click at the specified location and choose the specified button.
+ *
+ * @param rightClickLocation
+ * the location of the click
+ * @param text
+ * the label of the button to click
+ *
+ * @throws WidgetNotFoundException
+ * thrown if not button with the specified label is found
+ */
+ public void clickContextMenu(final Point rightClickLocation, String text) throws WidgetNotFoundException {
+ // 1. Simulate the move
+ // 1.1 one click to select the correct editPart
+ click(rightClickLocation);
+ // 1.1 and set the real location
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ FigureCanvas control = (FigureCanvas) rootEditPart().part().getRoot().getViewer().getControl();
+ org.eclipse.swt.graphics.Point relativeSWTPoint = control.toDisplay(rightClickLocation.x, rightClickLocation.y);
+ bot.getDisplay().setCursorLocation(relativeSWTPoint);
+
+ }
+ });
+ SWTBotUtils.waitAllUiEvents();
+
+ // 2. Click on the action on the contextual menu^M
+ super.clickContextMenu(text);
+ SWTBotUtils.waitAllUiEvents();
+ }
+
+ /**
+ * Refresh the diagram (F5).
+ *
+ * @throws WidgetNotFoundException
+ * if an exception occurs
+ */
+ public void refresh() throws WidgetNotFoundException {
+ if (TestsUtil.isEclipse4xPlatform()) {
+ clickContextMenu("Refresh");
+ } else {
+ bot.toolbarButtonWithTooltip(DiagramDialectUIServices.REFRESH_DIAGRAM).click();
+ }
+ }
+
+ /**
+ * Mouse drag.
+ *
+ * @param from
+ * From point
+ * @param to
+ * To point
+ * @see #drag(int, int, int, int)
+ */
+ public void drag(Point from, Point to) {
+ super.drag(from.x, from.y, to.x, to.y);
+ }
+
+ /**
+ * Mouse drag.
+ *
+ * @param from
+ * From point
+ * @param toXPosition
+ * the relative x position within the graphical viewer to drag to
+ * @param toYPosition
+ * the relative y position within the graphical viewer to drag to
+ * @see #drag(int, int, int, int)
+ */
+ public void drag(Point from, final int toXPosition, final int toYPosition) {
+ super.drag(from.x, from.y, toXPosition, toYPosition);
+ }
+
+ /**
+ * Drag and drop the specified edit part to the specified location.
+ *
+ * @param editPartBot
+ * the edit part to drag and drop
+ * @param toPosition
+ * the relative location
+ */
+ public void drag(final SWTBotGefEditPart editPartBot, final Point toPosition) {
+ drag(editPartBot, toPosition.x, toPosition.y);
+ }
+
+ /**
+ * Reveal the edit part with the label as a single selection.
+ *
+ * @param label
+ * The label of the searched edit part
+ */
+ public void reveal(String label) {
+ ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).reveal(label);
+ }
+
+ /**
+ * Reveal the edit part as a single selection.
+ *
+ * @param revealedEP
+ * the searched edit part
+ */
+ public void reveal(final EditPart revealedEP) {
+ ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).reveal(revealedEP);
+ }
+
+ /**
+ * Scrolls the contents to the new location.
+ *
+ * @param location
+ * The location to scroll to (the new origin)
+ */
+ public void scrollTo(Point location) {
+ ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).scrollTo(location);
+ }
+
+ /**
+ * Scrolls the contents to the new x and y location.
+ *
+ * @param x
+ * the x coordinate to scroll to
+ * @param y
+ * the y coordinate to scroll to
+ */
+ public void scrollTo(final int x, final int y) {
+ ((SWTBotDesignerGefViewer) getSWTBotGefViewer()).scrollTo(x, y);
+ }
+
+ /**
+ * Double-click with {@link #doubleClick(String)}, but on edit part with
+ * specified name.
+ *
+ * @param label
+ * Label of edit part
+ * @param editPartClass
+ * Class of edit part
+ * @see #doubleClick(String)
+ */
+ public void doubleClick(String label, Class<? extends EditPart> editPartClass) {
+ SWTBotGefEditPart selectedEP = getEditPart(label, editPartClass);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds();
+ // 3 = MOVE in overridden code
+ doubleClick(bounds.x, bounds.y + 3);
+ }
+
+ /**
+ * Double-click with {@link #doubleClick(String)}, but on edit part with
+ * specified name.
+ *
+ * @param label
+ * Label of edit part
+ * @param editPartClass
+ * Class of edit part
+ * @see #doubleClick(String)
+ */
+ public void doubleClickCentered(String label, Class<? extends EditPart> editPartClass) {
+ SWTBotGefEditPart selectedEP = getEditPart(label, editPartClass);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds();
+ // 3 = MOVE in overridden code
+ doubleClick(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2 + 3);
+ }
+
+ /**
+ * Get the figure location corresponding to that name and to the editPart
+ * type. The location is relative to the screen.<BR>
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (40, 40)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 40)</LI>
+ * </UL>
+ *
+ * @param editPartName
+ * The searched name
+ * @param expectedEditPartType
+ * The expected type of edit part (go up in the parent hierarchy
+ * to find this type).
+ * @return A location
+ */
+ public Point getLocation(final String editPartName, final Class<? extends EditPart> expectedEditPartType) {
+ final SWTBotGefEditPart editPartBot = getEditPart(editPartName, expectedEditPartType);
+ if (editPartBot == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, editPartName));
+ }
+ return getLocation(editPartBot);
+ }
+
+ /**
+ * Get the figure location corresponding to that <code>editPart</code>. The
+ * location is relative to the screen.<BR>
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (40, 40)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 40)</LI>
+ * </UL>
+ *
+ * @param editPart
+ * The edit part we are looking for location.
+ * @return A location
+ */
+ public Point getLocation(SWTBotGefEditPart editPart) {
+ return getBounds(editPart).getLocation();
+ }
+
+ /**
+ * Get the figure bounds corresponding to that editPart bot. The location is
+ * relative to the screen.<BR>
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (40, 40)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 40)</LI>
+ * </UL>
+ *
+ * @param swtBotGefEditPart
+ * the editPart bot
+ * @return A bound
+ */
+ public Rectangle getBounds(final SWTBotGefEditPart swtBotGefEditPart) {
+ if (swtBotGefEditPart == null) {
+ throw new NullPointerException();
+ }
+ final EditPart editPart = swtBotGefEditPart.part();
+ if (!(editPart instanceof IGraphicalEditPart)) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, swtBotGefEditPart));
+ }
+ IGraphicalEditPart part = (IGraphicalEditPart) editPart;
+ Rectangle figureLocation = part.getFigure().getBounds().getCopy();
+ part.getFigure().translateToAbsolute(figureLocation);
+ return figureLocation;
+ }
+
+ /**
+ * Get the figure bounds corresponding to that connectionEditPart bot. The
+ * location is relative to the screen.<BR>
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (40, 40)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 40)</LI>
+ * </UL>
+ *
+ * @param swtBotGefConnectionEditPart
+ * the editPart bot
+ * @return A bound
+ */
+ public Rectangle getBounds(final SWTBotGefConnectionEditPart swtBotGefConnectionEditPart) {
+ if (swtBotGefConnectionEditPart == null) {
+ throw new NullPointerException();
+ }
+ final ConnectionEditPart connectionEditPart = swtBotGefConnectionEditPart.part();
+ if (!(connectionEditPart instanceof AbstractConnectionEditPart)) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, swtBotGefConnectionEditPart));
+ }
+ AbstractConnectionEditPart part = (AbstractConnectionEditPart) connectionEditPart;
+ Rectangle figureLocation = part.getConnectionFigure().getPoints().getBounds();
+ part.getFigure().translateToAbsolute(figureLocation);
+ return figureLocation;
+ }
+
+ /**
+ * Get the figure dimension corresponding to that name and to the editPart
+ * type.<BR>
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a dimension of (80, 80) return (40, 40)</LI>
+ * </UL>
+ *
+ * @param editPartName
+ * The searched name
+ * @param expectedEditPartType
+ * The expected type of edit part (go up in the parent hierarchy
+ * to find this type).
+ * @return A dimension
+ */
+ public Dimension getDimension(final String editPartName, final Class<? extends EditPart> expectedEditPartType) {
+ final SWTBotGefEditPart editPartBot = getEditPart(editPartName, expectedEditPartType);
+ if (editPartBot == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, editPartName));
+ }
+ final EditPart editPart = editPartBot.part();
+ if (!(editPart instanceof IGraphicalEditPart)) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, editPartName));
+ }
+ IGraphicalEditPart part = (IGraphicalEditPart) editPart;
+ Dimension figureDimension = part.getFigure().getBounds().getSize();
+ part.getFigure().translateToAbsolute(figureDimension);
+ return figureDimension;
+ }
+
+ /**
+ * Get the absolute bounds of the Figure of corresponding to a
+ * {@link SWTBotGefEditPart}.
+ *
+ * @param swtBotGefEditPart
+ * the {@link SWTBotGefEditPart}
+ * @return the absolute bounds
+ */
+ public Rectangle getAbsoluteBounds(SWTBotGefEditPart swtBotGefEditPart) {
+ if (swtBotGefEditPart == null) {
+ throw new NullPointerException();
+ }
+ final EditPart editPart = swtBotGefEditPart.part();
+ if (!(editPart instanceof IGraphicalEditPart)) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, swtBotGefEditPart));
+ }
+ IGraphicalEditPart part = (IGraphicalEditPart) editPart;
+ Rectangle figureBounds = part.getFigure().getBounds().getCopy();
+ return figureBounds;
+ }
+
+ /**
+ * Get the figure location corresponding to that name and to the editPart
+ * type. The location is in absolute coordinate (from the origin 0,0).
+ * Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (80, 80)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 80)</LI>
+ * </UL>
+ *
+ * @param editPartName
+ * The searched name
+ * @param expectedEditPartType
+ * The expected type of edit part (go up in the parent hierarchy
+ * to find this type).
+ * @return A location
+ */
+ public Point getAbsoluteLocation(final String editPartName, final Class<? extends EditPart> expectedEditPartType) {
+ final SWTBotGefEditPart editPartBot = getEditPart(editPartName, expectedEditPartType);
+ if (editPartBot == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, editPartName));
+ }
+ final EditPart editPart = editPartBot.part();
+ if (!(editPart instanceof IGraphicalEditPart)) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, editPartName));
+ }
+ IGraphicalEditPart part = (IGraphicalEditPart) editPart;
+ return getAbsoluteLocation(part);
+ }
+
+ /**
+ * Get the figure location corresponding to that editPart type. The location
+ * is in absolute coordinate (from the origin 0,0). Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (80, 80)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 80)</LI>
+ * </UL>
+ *
+ * @param editPart
+ * The concerned edit part
+ * @return A location
+ */
+ public Point getAbsoluteLocation(final GraphicalEditPart editPart) {
+ Point figureLocation = editPart.getFigure().getBounds().getLocation();
+ FigureUtilities.translateToAbsoluteByIgnoringScrollbar(editPart.getFigure(), figureLocation);
+ return figureLocation;
+ }
+
+ /**
+ * Get the figure center corresponding to that editPart type. The center is
+ * in absolute coordinate (from the origin 0,0). Examples :
+ * <UL>
+ * <LI>If the zoom is set to 50% a position at (80, 80) return (80, 80)</LI>
+ * <LI>If the vertical scroll bar is set to 40 a position at (80, 80) return
+ * (80, 80)</LI>
+ * </UL>
+ *
+ * @param editPart
+ * The concerned edit part
+ * @return The center of the figure
+ */
+ public Point getAbsoluteCenter(final GraphicalEditPart editPart) {
+ Point figureCenter = editPart.getFigure().getBounds().getCenter();
+ FigureUtilities.translateToAbsoluteByIgnoringScrollbar(editPart.getFigure(), figureCenter);
+ return figureCenter;
+ }
+
+ /**
+ * Searched in all editPart (excepted the connection).
+ *
+ * @param xPosition
+ * the relative x position within the graphical viewer
+ * @param yPosition
+ * the relative y position within the graphical viewer
+ * @return The nearest edit part from this coordinates.
+ */
+ protected SWTBotGefEditPart getNearestEditPart(final int xPosition, final int yPosition) {
+ List<SWTBotGefEditPart> allEditParts = mainEditPart().children();
+ allEditParts.addAll(mainEditPart().sourceConnections());
+ return getNearestEditPart(new Point(xPosition, yPosition), allEditParts);
+ }
+
+ /**
+ * Searched in <code>allEditParts</code>, the nearest from the
+ * <code>searchedPosition</code>.
+ *
+ * @param searchedPosition
+ * The searched position
+ * @param allEditParts
+ * The edit parts in which search
+ * @return The nearest edit part from this point.
+ */
+ protected SWTBotGefEditPart getNearestEditPart(final Point searchedPosition, List<SWTBotGefEditPart> allEditParts) {
+ SWTBotGefEditPart nearest = null;
+ int distance = Integer.MAX_VALUE;
+ for (SWTBotGefEditPart child : allEditParts) {
+ IFigure figure = ((GraphicalEditPart) child.part()).getFigure();
+ if (distance > figure.getBounds().getCenter().getDistance2(searchedPosition)) {
+ distance = figure.getBounds().getCenter().getDistance2(searchedPosition);
+ nearest = child;
+ }
+ }
+ if (nearest.children().size() > 0) {
+ nearest = getNearestEditPart(searchedPosition, nearest.children());
+ }
+ return nearest;
+ }
+
+ /**
+ * This method emits mouse events that handle a mouse move and left click to
+ * the left bottom corner of the nearest edit part of the coordinates
+ * <code>{xPosition, yPosition}</code> .
+ *
+ * @param xPosition
+ * the relative x position within the graphical viewer
+ * @param yPosition
+ * the relative y position within the graphical viewer
+ */
+ public void clickNearest(final int xPosition, final int yPosition) {
+ final SWTBotGefEditPart selectedEP = getNearestEditPart(xPosition, yPosition);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_X_Y, xPosition, yPosition));
+ }
+ final Rectangle bounds = ((GraphicalEditPart) selectedEP.part()).getFigure().getBounds();
+ ((GraphicalEditPart) selectedEP.part()).getFigure().translateToAbsolute(bounds);
+ /* add height for designer */
+ click(bounds.x, bounds.y + bounds.height);
+ }
+
+ /**
+ * This method emits mouse events that handle a mouse move and left click to
+ * the center of the folding figure that is nearest of the coordinates
+ * <code>{xPosition, yPosition}</code> .
+ *
+ * @param xPosition
+ * the relative x position within the graphical viewer
+ * @param yPosition
+ * the relative y position within the graphical viewer
+ */
+ public void clickNearestFoldingFigure(final int xPosition, final int yPosition) {
+ final IFigure foldingFigure = getNearestFoldingFigure(new Point(xPosition, yPosition));
+ if (foldingFigure == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_X_Y, xPosition, yPosition));
+ }
+ final Rectangle bounds = foldingFigure.getBounds();
+ // ((GraphicalEditPart)
+ // selectedEP.part()).getFigure().translateToAbsolute(bounds);
+ /* add height for designer */
+ click(bounds.getCenter().x, bounds.getCenter().y);
+ }
+
+ /**
+ * Searched in all editParts, the nearest folding figure from the
+ * <code>searchedPosition</code>.
+ *
+ * @param searchedPosition
+ * The searched position
+ * @return The nearest folding figure from this point.
+ */
+ protected IFigure getNearestFoldingFigure(Point searchedPosition) {
+ List<SWTBotGefEditPart> allEditParts = mainEditPart().children();
+ allEditParts.addAll(mainEditPart().sourceConnections());
+ return getNearestFoldingFigure(searchedPosition, allEditParts);
+ }
+
+ /**
+ * Searched in <code>allEditParts</code>, the nearest folding figure from
+ * the <code>searchedPosition</code>.
+ *
+ * @param searchedPosition
+ * The searched position
+ * @param allEditParts
+ * The edit parts in which search
+ * @return The nearest folding figure from this point.
+ */
+ protected IFigure getNearestFoldingFigure(final Point searchedPosition, List<SWTBotGefEditPart> allEditParts) {
+ IFigure nearestFoldingFigure = null;
+ SWTBotGefEditPart nearestEditPart = null;
+ int distance = Integer.MAX_VALUE;
+ for (SWTBotGefEditPart child : allEditParts) {
+ IFigure figure = ((GraphicalEditPart) child.part()).getFigure();
+ if (distance > figure.getBounds().getCenter().getDistance2(searchedPosition)) {
+ distance = figure.getBounds().getCenter().getDistance2(searchedPosition);
+ nearestEditPart = child;
+ }
+ }
+ if (nearestEditPart != null
+ && (!((GraphicalEditPart) nearestEditPart.part()).getSourceConnections().isEmpty() || !((GraphicalEditPart) nearestEditPart.part()).getTargetConnections().isEmpty())) {
+ List connections = new ArrayList();
+ GraphicalEditPart graphicalEditPart = (GraphicalEditPart) nearestEditPart.part();
+ connections.addAll(graphicalEditPart.getSourceConnections());
+ connections.addAll(graphicalEditPart.getTargetConnections());
+ nearestFoldingFigure = getNearestFoldingFigureInConnections(searchedPosition, connections);
+ }
+ return nearestFoldingFigure;
+ }
+
+ /**
+ * Searched in <code>connections</code>, the nearest folding figure from the
+ * <code>searchedPosition</code>.
+ *
+ * @param searchedPosition
+ * The searched position
+ * @param connections
+ * The connections in which search
+ * @return The nearest folding figure from this point
+ */
+ protected IFigure getNearestFoldingFigureInConnections(final Point searchedPosition, final List connections) {
+ return null;
+ // IFigure nearest = null;
+ // int distance = Integer.MAX_VALUE;
+ // for (Iterator iterator = connections.iterator(); iterator.hasNext();
+ // /* */) {
+ // Object object = (Object) iterator.next();
+ // if (object instanceof AbstractDiagramEdgeEditPart) {
+ // ViewEdgeFigure viewEdgeFigure = (ViewEdgeFigure)
+ // ((AbstractDiagramEdgeEditPart) object).getFigure();
+ // if (distance >
+ // viewEdgeFigure.getFoldingFigure().getBounds().getCenter().getDistance2(searchedPosition))
+ // {
+ // distance =
+ // viewEdgeFigure.getFoldingFigure().getBounds().getCenter().getDistance2(searchedPosition);
+ // nearest = viewEdgeFigure.getFoldingFigure();
+ // }
+ // }
+ // }
+ // return nearest;
+ }
+
+ /**
+ * Finds the currently active tool on the Palette.
+ *
+ * @return the active {@link ToolEntry}
+ */
+ @Override
+ public ToolEntry getActiveTool() {
+ return getSWTBotGefViewer().getActiveTool();
+ }
+
+ /**
+ * Maximize this editor. Eclipse API is used for that.
+ */
+ public void maximize() {
+ UIThreadRunnable.syncExec(SWTUtils.display(), new VoidResult() {
+ @Override
+ public void run() {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().setPartState(partReference, IWorkbenchPage.STATE_MAXIMIZED);
+ }
+ });
+ }
+
+ /**
+ * Restore the editors state (if it was maximed).
+ */
+ public void restore() {
+ UIThreadRunnable.syncExec(SWTUtils.display(), new VoidResult() {
+ @Override
+ public void run() {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().setPartState(partReference, IWorkbenchPage.STATE_RESTORED);
+ }
+ });
+ }
+
+ /**
+ * Disable the snapToGrid option for this editor.
+ */
+ public void disableSnapToGrid() {
+ ((DiagramGraphicalViewer) getDiagramGraphicalViewer()).getWorkspaceViewerPreferenceStore().setValue(WorkspaceViewerProperties.SNAPTOGRID, false);
+ }
+
+ /**
+ * A utility method to return the active part if it implements or adapts to
+ * the <code>IDiagramWorkbenchPart</code> interface.
+ *
+ * @return The current part if it implements or adapts to
+ * <code>IDiagramWorkbenchPart</code>; <code>null</code> otherwise
+ */
+ protected IDiagramWorkbenchPart getDiagramWorkbenchPart() {
+ IDiagramWorkbenchPart diagramPart = null;
+ IEditorPart editorPart = partReference.getEditor(false);
+
+ if (editorPart instanceof IDiagramWorkbenchPart) {
+ diagramPart = (IDiagramWorkbenchPart) editorPart;
+
+ } else if (editorPart != null) {
+ diagramPart = (IDiagramWorkbenchPart) editorPart.getAdapter(IDiagramWorkbenchPart.class);
+ }
+
+ return diagramPart;
+ }
+
+ /**
+ * A utility method to return the active <code>DiagramEditPart</code> if the
+ * current part implements <code>IDiagramWorkbenchPart</code>.
+ *
+ * @return The current diagram if the parts implements
+ * <code>IDiagramWorkbenchPart</code>; <code>null</code> otherwise
+ */
+ protected IDiagramGraphicalViewer getDiagramGraphicalViewer() {
+ IDiagramWorkbenchPart part = getDiagramWorkbenchPart();
+ return part != null ? part.getDiagramGraphicalViewer() : null;
+ }
+
+ /**
+ * Zoom to next zoom value.
+ *
+ * @param zoomLevel
+ * Zoom level
+ *
+ * @return Current representation.
+ */
+ public SWTBotDesignerEditor zoom(final ZoomLevel zoomLevel) {
+ final ToolItem item = designerBot.toolbarSpecialDropDownButtonWithTooltip("&Zoom");
+
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ final Combo control = (Combo) item.getControl();
+ control.setFocus();
+ control.setText(zoomLevel.getLevel());
+ control.select(control.indexOf(zoomLevel.getLevel()));
+ if (useTabbar()) {
+ control.notifyListeners(SWT.DefaultSelection, new Event());
+ } else {
+ control.notifyListeners(SWT.KeyDown, createCarriageReturnKeyPressedEvent(control));
+ }
+
+ }
+
+ private Event createCarriageReturnKeyPressedEvent(final Widget control) {
+ final Event keyEvent = new Event();
+ keyEvent.time = (int) System.currentTimeMillis();
+ keyEvent.widget = control;
+ keyEvent.display = designerBot.getDisplay();
+ keyEvent.stateMask = SWT.NONE;
+ keyEvent.character = SWT.CR;
+ keyEvent.keyCode = SWT.Selection;
+ return keyEvent;
+ }
+
+ });
+
+ return this;
+ }
+
+ /**
+ * Zoom to default zoom value.
+ *
+ * @return Current representation.
+ */
+ public SWTBotDesignerEditor zoomDefault() {
+ return zoom(UIDiagramRepresentation.ZOOM_DEFAULT);
+ }
+
+ private boolean useTabbar() {
+ Preferences prefs = SiriusDiagramEditorPlugin.getInstance().getPluginPreferences();
+ return !prefs.getBoolean(SiriusDiagramPreferencesKeys.PREF_OLD_UI.name());
+ }
+
+ /**
+ * Get the selectable edit part with the label as a singleton selection. If
+ * the edit part corresponding to the label is not selectable, we searched
+ * in the parent hierarchy of this edit part.
+ *
+ * @param label
+ * The searched label The type of the expected edit part
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getSelectableEditPart(final String label) {
+ SWTBotGefEditPart selectedEP = super.getEditPart(label);
+ if (selectedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+
+ if (!isSelectableEditPart(selectedEP.part())) {
+ selectedEP = getSelectableParentEditPart(selectedEP);
+ }
+ return selectedEP;
+ }
+
+ private boolean isSelectableEditPart(EditPart editPart) {
+ return editPart instanceof AbstractBorderedShapeEditPart || editPart instanceof AbstractDiagramNodeEditPart || editPart instanceof AbstractDiagramBorderNodeEditPart;
+ }
+
+ /**
+ * Search in the parent hierarchy of <code>editPart</code>, the first one of
+ * selectable.
+ *
+ * @param editPart
+ * The start editPart
+ * @param expectedEditPartType
+ * The type of the expected edit part
+ * @return the corresponding SWTBotGefEditPart
+ */
+ private SWTBotGefEditPart getSelectableParentEditPart(SWTBotGefEditPart editPart) {
+ SWTBotGefEditPart parent = editPart.parent();
+ if (parent == null || parent.part() == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_GRAPHICAL_EDIT_PART_S, editPart));
+ }
+ if (!isSelectableEditPart(parent.part())) {
+ parent = getSelectableParentEditPart(parent);
+ }
+ return parent;
+ }
+
+ /**
+ * Type the given text into the graphical editor, presuming that it is
+ * already in 'direct edit' mode. The given text is added at the end of the
+ * existing one.<BR>
+ * This method is duplicated from SWTBotGefEditor to avoid to call a
+ * textControl.setText(""); before typing the new one.<BR>
+ * Use the new method
+ * {@link SWTBotSiriusFigureCanvas#typeSuffixText(Text, String)}.
+ *
+ * @param text
+ * the text to type.
+ * @throws WidgetNotFoundException
+ * When widget is not found.
+ */
+ public void directEditTypeSuffix(String text) throws WidgetNotFoundException {
+ /*
+ * we use 'bot()' and not 'bot' to scope the widget search to the
+ * editor. Otherwise if another widget of the same type is present in
+ * the workspace and is found first, the code after will fail.
+ */
+
+ /* wait until text widget appears */
+ bot().text();
+ /* find it now */
+ List<Text> controls = bot().getFinder().findControls(getWidget(), new IsInstanceOf<Text>(Text.class), true);
+ if (controls.size() == 1) {
+ final Text textControl = controls.get(0);
+ SWTBotGefFigureCanvas canvas = getCanvas();
+ if (canvas instanceof SWTBotSiriusFigureCanvas) {
+ ((SWTBotSiriusFigureCanvas) canvas).typeSuffixText(textControl, text);
+ } else {
+ canvas.typeText(textControl, text);
+ }
+ } else {
+ throw new WidgetNotFoundException(String.format("Expected to find one text control, but found %s. Is the editor in direct-edit mode?", controls.size()));
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerGefViewer.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerGefViewer.java
new file mode 100644
index 0000000000..3a447659f4
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerGefViewer.java
@@ -0,0 +1,301 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.editor;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Label;
+import org.eclipse.draw2d.LightweightSystem;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.text.TextFlow;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.GraphicalEditPart;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.sirius.diagram.ui.tools.api.figure.SiriusWrapLabel;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.SWTBotSiriusFigureCanvas;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefFigureCanvas;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefViewer;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.junit.Assert;
+
+/**
+ * SWTBotGefViewer for Sirius.
+ *
+ * @author nlepine
+ *
+ */
+public class SWTBotDesignerGefViewer extends SWTBotGefViewer {
+
+ /**
+ *
+ * Construct a new instance.
+ *
+ * @param graphicalViewer
+ * GraphicalViewer
+ * @throws WidgetNotFoundException
+ * Exception
+ */
+ public SWTBotDesignerGefViewer(GraphicalViewer graphicalViewer) throws WidgetNotFoundException {
+ super(graphicalViewer);
+ init();
+ }
+
+ /**
+ * init.
+ *
+ * @throws WidgetNotFoundException
+ * if widget not found
+ */
+ @Override
+ protected void init() throws WidgetNotFoundException {
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ final Control control = graphicalViewer.getControl();
+ if (control instanceof FigureCanvas) {
+ canvas = new SWTBotSiriusFigureCanvas((FigureCanvas) control);
+ } else if (control instanceof Canvas) {
+ if (control instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) control;
+ Object adapter = adaptable.getAdapter(LightweightSystem.class);
+ if (adapter instanceof LightweightSystem) {
+ canvas = new SWTBotSiriusFigureCanvas((Canvas) control, (LightweightSystem) adapter);
+ }
+ }
+ }
+ editDomain = graphicalViewer.getEditDomain();
+ }
+ });
+
+ if (graphicalViewer == null) {
+ throw new WidgetNotFoundException("Editor does not adapt to a GraphicalViewer");
+ }
+ }
+
+ @Override
+ public SWTBotGefFigureCanvas getCanvas() {
+ return super.getCanvas();
+ }
+
+ /**
+ * Get the RootEditPart bot for the palette.
+ *
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getPaletteRootEditPartBot() {
+ Object o = UIThreadRunnable.syncExec(new Result<Object>() {
+ @Override
+ public Object run() {
+ return createEditPart(editDomain.getPaletteViewer().getRootEditPart());
+ }
+ });
+ if (o instanceof WidgetNotFoundException) {
+ throw (WidgetNotFoundException) o;
+ }
+ return (SWTBotGefEditPart) o;
+ }
+
+ /**
+ * Get the GroupEditPart bot for the palette corresponding to tool provided
+ * by *.odesign modeler.
+ *
+ * @return the corresponding SWTBotGefEditPart
+ */
+ public SWTBotGefEditPart getSiriusPaletteGroupEditPartBot() {
+ SWTBotGefEditPart viewpointPaletteGrouEditPartBot = null;
+ Object o = UIThreadRunnable.syncExec(new Result<Object>() {
+ @Override
+ public Object run() {
+ return createEditPart(editDomain.getPaletteViewer().getRootEditPart());
+ }
+ });
+ if (o instanceof WidgetNotFoundException) {
+ throw (WidgetNotFoundException) o;
+ }
+ SWTBotGefEditPart paletteRootEditPartBot = (SWTBotGefEditPart) o;
+ Assert.assertFalse("The rootEditPart of the palette should contains a SlidablePaletteEditPart", paletteRootEditPartBot.children().isEmpty());
+ SWTBotGefEditPart slidablePaletteEditPartBot = paletteRootEditPartBot.children().get(0);
+ if (slidablePaletteEditPartBot.children().size() >= 2) {
+ viewpointPaletteGrouEditPartBot = slidablePaletteEditPartBot.children().get(1);
+ }
+ return viewpointPaletteGrouEditPartBot;
+ }
+
+ /**
+ * Reveal the edit part with the label as a single selection.
+ *
+ * @param label
+ * The label of the searched edit part
+ */
+ public void reveal(String label) {
+ final SWTBotGefEditPart revealedEP = getEditPart(label);
+ if (revealedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, label));
+ }
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ graphicalViewer.reveal(revealedEP.part());
+ }
+ });
+ }
+
+ /**
+ * Reveal the edit part as a single selection.
+ *
+ * @param revealedEP
+ * the searched edit part
+ */
+ public void reveal(final EditPart revealedEP) {
+ if (revealedEP == null) {
+ throw new WidgetNotFoundException(String.format(SWTBotDesignerEditor.EXPECTED_TO_FIND_WIDGET_S, revealedEP));
+ }
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ graphicalViewer.reveal(revealedEP);
+ }
+ });
+ }
+
+ /**
+ * Scrolls the contents to the new location.
+ *
+ * @param location
+ * The location to scroll to (the new origin)
+ */
+ public void scrollTo(Point location) {
+ scrollTo(location.x, location.y);
+ }
+
+ /**
+ * Scrolls the contents to the new x and y location.
+ *
+ * @param x
+ * the x coordinate to scroll to
+ * @param y
+ * the y coordinate to scroll to
+ */
+ public void scrollTo(final int x, final int y) {
+ if (graphicalViewer.getControl() instanceof FigureCanvas) {
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ ((FigureCanvas) graphicalViewer.getControl()).scrollTo(x, y);
+ }
+ });
+ }
+ }
+
+ /**
+ * Override method to manage SiriusWrapLabel.
+ *
+ * @param figure
+ * The figure to check
+ * @param label
+ * The searched label
+ * @return true if the figure is a label, false otherwise
+ */
+ private boolean isLabel(IFigure figure, String label) {
+ boolean result = false;
+
+ if (figure instanceof Label && ((Label) figure).getText().equals(label)) {
+ // case 1 : gef label
+ result = true;
+ } else if (figure instanceof TextFlow && ((TextFlow) figure).getText().equals(label)) {
+ // case 2 : no gef label
+ result = true;
+ } else if (figure instanceof SiriusWrapLabel && ((SiriusWrapLabel) figure).getText().equals(label)) {
+ // case 3 : Sirius specific wrap label
+ result = true;
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Override to deal with Sirius WrapLabel.
+ */
+ @Override
+ public SWTBotGefEditPart getEditpart(String label, List<SWTBotGefEditPart> allEditParts) {
+ SWTBotGefEditPart result = null;
+ for (Iterator<SWTBotGefEditPart> iterator = allEditParts.iterator(); iterator.hasNext() && result == null; /* */) {
+ SWTBotGefEditPart child = iterator.next();
+ IFigure figure = ((GraphicalEditPart) child.part()).getFigure();
+
+ if (isLabel(figure, label)) {
+ result = child;
+ } else {
+ SWTBotGefEditPart childEditPart = getEditPart(child, label);
+ if (childEditPart != null) {
+ result = childEditPart;
+ } else
+
+ if (findLabelFigure(figure, label)) {
+ result = child;
+ }
+ }
+
+ }
+ return result;
+ }
+
+ /**
+ * Duplicate method because method isLabel is private.
+ *
+ * @param figure
+ * The figure to check
+ * @param label
+ * The figure to check
+ * @return true if this figure corresponds to the searched label
+ */
+ private boolean findLabelFigure(IFigure figure, String label) {
+ boolean result = false;
+ if (isLabel(figure, label)) {
+ result = true;
+ } else {
+ for (Iterator<Object> iteratorFigureChildren = figure.getChildren().iterator(); iteratorFigureChildren.hasNext() && !result; /* */) {
+ Object figureChild = iteratorFigureChildren.next();
+ if (isLabel((IFigure) figureChild, label) || findLabelFigure((IFigure) figureChild, label)) {
+ result = true;
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Duplicate method because method isLabel is private. <BR>
+ * get this edit part with the label as a single selection
+ */
+ private SWTBotGefEditPart getEditPart(SWTBotGefEditPart editPart, String label) {
+ if (editPart.children().isEmpty() && findLabelFigure(((GraphicalEditPart) editPart.part()).getFigure(), label)) {
+ return editPart;
+ }
+
+ List<SWTBotGefEditPart> allEditParts = editPart.children();
+ allEditParts.addAll(editPart.sourceConnections());
+ return getEditpart(label, allEditParts);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerHelper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerHelper.java
new file mode 100644
index 0000000000..2ee06ac594
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotDesignerHelper.java
@@ -0,0 +1,396 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.sirius.common.tools.api.util.ReflectionHelper;
+import org.eclipse.sirius.diagram.ui.tools.api.editor.DDiagramEditor;
+import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.ext.base.Options;
+import org.eclipse.sirius.table.ui.tools.api.editor.DTableEditor;
+import org.eclipse.sirius.tree.ui.tools.api.editor.DTreeEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.waits.Conditions;
+import org.eclipse.swtbot.eclipse.finder.waits.WaitForEditor;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.eclipse.gef.finder.matchers.IsInstanceOf;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.results.StringResult;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.eclipse.swtbot.swt.finder.waits.WaitForObjectCondition;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList;
+import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList.ListElement;
+import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyTitle;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+
+/**
+ *
+ * SWTBot designer helper.
+ *
+ * @author nlepine
+ *
+ */
+@SuppressWarnings("restriction")
+public final class SWTBotDesignerHelper {
+ /**
+ * SWTWorkbenchBot
+ */
+ private static SWTWorkbenchBot bot = new SWTWorkbenchBot();
+
+ private SWTBotDesignerHelper() {
+ // Nothing
+ }
+
+ /**
+ * Get the tabbed property sheet title in the properties view.
+ *
+ * @return the tabbed property sheet title. Label to find.
+ */
+ @SuppressWarnings({ "unchecked" })
+ public static Option<String> getPropertyItemTitle() {
+ final Matcher<TabbedPropertyTitle> matcher = Matchers.allOf(WidgetMatcherFactory.widgetOfType(TabbedPropertyTitle.class));
+ final List<TabbedPropertyTitle> widgets = SWTBotDesignerHelper.widget(matcher);
+
+ String result = UIThreadRunnable.syncExec(SWTUtils.display(), new StringResult() {
+ @Override
+ public String run() {
+ for (final TabbedPropertyTitle tabbedProperty : widgets) {
+ Option<Object> title = ReflectionHelper.getFieldValueWithoutException(tabbedProperty, "text");
+ if (title.some()) {
+ return (String) title.get();
+ }
+ }
+ return null;
+ }
+ });
+
+ return Options.newSome(result);
+ }
+
+ /**
+ * Select the tab with the name label in the property views.
+ *
+ * @param label
+ * Label to find.
+ */
+ @SuppressWarnings({ "unchecked" })
+ public static void selectPropertyTabItem(final String label) {
+ final Matcher<TabbedPropertyList> matcher = Matchers.allOf(WidgetMatcherFactory.widgetOfType(TabbedPropertyList.class));
+ final List<TabbedPropertyList> widgets = SWTBotDesignerHelper.widget(matcher);
+
+ UIThreadRunnable.syncExec(SWTUtils.display(), new VoidResult() {
+ @Override
+ public void run() {
+ for (final TabbedPropertyList tabbedProperty : widgets) {
+ final ListElement tabItem = SWTBotDesignerHelper.getTabItem(label, tabbedProperty);
+ if (tabItem != null) {
+ final Event mouseEvent = SWTBotDesignerHelper.createEvent(tabItem, tabItem.getBounds().x, tabItem.getBounds().y, 1, SWT.BUTTON1, 1);
+ tabItem.notifyListeners(SWT.MouseUp, mouseEvent);
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Find widget.
+ *
+ * @param matcher
+ * the matcher used to match widgets.
+ * @param <T>
+ * the type of the {@link Widget} to match
+ * @return all the widgets matching the matcher.
+ */
+ public static <T extends Widget> List<T> widget(final Matcher<T> matcher) {
+ final WaitForObjectCondition<T> waitForWidget = org.eclipse.swtbot.swt.finder.waits.Conditions.waitForWidget(matcher);
+ SWTBotDesignerHelper.bot.waitUntilWidgetAppears(waitForWidget);
+ return waitForWidget.getAllMatches();
+ }
+
+ /**
+ * Create a event <br>
+ *
+ * @param x
+ * the x coordinate of the mouse event.
+ * @param y
+ * the y coordinate of the mouse event.
+ * @param button
+ * the mouse button that was clicked.
+ * @param stateMask
+ * the state of the keyboard modifier keys.
+ * @param count
+ * the number of times the mouse was clicked.
+ * @return an event that encapsulates {@link #widget} and {@link #display}
+ */
+ private static Event createEvent(final Widget widget, final int x, final int y, final int button, final int stateMask, final int count) {
+ final Event event = new Event();
+ event.time = (int) System.currentTimeMillis();
+ event.widget = widget;
+ event.display = SWTBotDesignerHelper.bot.getDisplay();
+ event.x = x;
+ event.y = y;
+ event.button = button;
+ event.stateMask = stateMask;
+ event.count = count;
+ return event;
+ }
+
+ /**
+ * Select the tab with the name label in the property views
+ *
+ * @param label
+ */
+ private static ListElement getTabItem(final String label, final TabbedPropertyList tabbedProperty) {
+ for (final Object listElement : tabbedProperty.getTabList()) {
+ if (listElement instanceof ListElement && ((ListElement) listElement).getTabItem().getText().equals(label)) {
+ return (ListElement) listElement;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Attempts to locate the Gef editor matching the given name. If no match is
+ * found an exception will be thrown. The name is the name as displayed on
+ * the editor's tab in eclipse.
+ *
+ * @param fileName
+ * the name of the file.
+ * @return an editor for the specified fileName.
+ * @throws WidgetNotFoundException
+ * if the editor is not found.
+ */
+ public static SWTBotDesignerEditor getDesignerEditor(final String fileName) throws WidgetNotFoundException {
+ SWTBotDesignerHelper.bot.editorByTitle(fileName).show();
+ return SWTBotDesignerHelper.getDesignerEditor(fileName, 0);
+ }
+
+ /**
+ * Attempts to locate the Gef editor matching the partial given name. If no
+ * match is found an exception will be thrown. The name is the name as
+ * displayed on the editor's tab in eclipse.
+ *
+ * @param partialFileName
+ * the partial name of the file.
+ * @return an editor for the specified fileName.
+ * @throws WidgetNotFoundException
+ * if the editor is not found.
+ */
+ public static SWTBotDesignerEditor getDesignerEditorContainingName(final String partialFileName) throws WidgetNotFoundException {
+ final Matcher<IEditorReference> withPartName = org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName(Matchers.containsString(partialFileName));
+ return SWTBotDesignerHelper.getDesignerEditor(withPartName, 0);
+ }
+
+ /**
+ * Get the first {@link SWTBotEditor} corresponding to a Diagram
+ * DialectEditor with <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return the first {@link SWTBotEditor} corresponding to a Diagram
+ * DialectEditor with <code>title</code> has title
+ */
+ public static SWTBotEditor getDiagramDialectEditorBot(String title) {
+ SWTBotEditor swtBotEditor = SWTBotDesignerHelper.getDiagramDialectEditorBots(title).get(0);
+ return swtBotEditor;
+ }
+
+ /**
+ * Get all {@link SWTBotEditor} corresponding to a Diagram DialectEditor
+ * with <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return all {@link SWTBotEditor} corresponding to a Diagram DialectEditor
+ * with <code>title</code> has title
+ */
+ public static List<SWTBotEditor> getDiagramDialectEditorBots(String title) {
+ List<SWTBotEditor> diagramDialectEditorBots = new ArrayList<SWTBotEditor>();
+ Matcher<IEditorReference> withPartName = org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName(title);
+ final Matcher<IEditorReference> matcher = Matchers.allOf(IsInstanceOf.instanceOf(IEditorReference.class), withPartName);
+ final WaitForEditor waitForEditor = Conditions.waitForEditor(matcher);
+ SWTBotDesignerHelper.bot.waitUntilWidgetAppears(waitForEditor);
+ List<IEditorReference> editorReferences = waitForEditor.getAllMatches();
+ for (IEditorReference editorReference : editorReferences) {
+ IEditorPart editorPart = editorReference.getEditor(false);
+ if (editorPart instanceof DDiagramEditor) {
+ SWTBotEditor swtBotEditor = new SWTBotEditor(editorReference, SWTBotDesignerHelper.bot);
+ diagramDialectEditorBots.add(swtBotEditor);
+ }
+ }
+ return diagramDialectEditorBots;
+ }
+
+ /**
+ * Get the first {@link SWTBotEditor} corresponding to a Tree DialectEditor
+ * with <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return the first {@link SWTBotEditor} corresponding to a Tree
+ * DialectEditor with <code>title</code> has title
+ */
+ public static SWTBotEditor getTreeDialectEditorBot(String title) {
+ SWTBotDesignerHelper.bot.editorByTitle(title).show();
+ SWTBotEditor swtBotEditor = SWTBotDesignerHelper.getTreeDialectEditorBots(title).get(0);
+ return swtBotEditor;
+ }
+
+ /**
+ * Get all {@link SWTBotEditor} corresponding to a Tree DialectEditor with
+ * <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return all {@link SWTBotEditor} corresponding to a Tree DialectEditor
+ * with <code>title</code> has title
+ */
+ public static List<SWTBotEditor> getTreeDialectEditorBots(String title) {
+ List<SWTBotEditor> treeDialectEditorBots = new ArrayList<SWTBotEditor>();
+ Matcher<IEditorReference> withPartName = org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName(title);
+ final Matcher<IEditorReference> matcher = Matchers.allOf(IsInstanceOf.instanceOf(IEditorReference.class), withPartName);
+ final WaitForEditor waitForEditor = Conditions.waitForEditor(matcher);
+ SWTBotDesignerHelper.bot.waitUntilWidgetAppears(waitForEditor);
+ List<IEditorReference> editorReferences = waitForEditor.getAllMatches();
+ for (IEditorReference editorReference : editorReferences) {
+ IEditorPart editorPart = editorReference.getEditor(false);
+ if (editorPart instanceof DTreeEditor) {
+ SWTBotEditor swtBotEditor = new SWTBotEditor(editorReference, SWTBotDesignerHelper.bot);
+ treeDialectEditorBots.add(swtBotEditor);
+ }
+ }
+ return treeDialectEditorBots;
+ }
+
+ /**
+ * Get the first {@link SWTBotEditor} corresponding to a Table DialectEditor
+ * with <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return the first {@link SWTBotEditor} corresponding to a Table
+ * DialectEditor with <code>title</code> has title
+ */
+ public static SWTBotEditor getTableDialectEditorBot(String title) {
+ SWTBotDesignerHelper.bot.editorByTitle(title).show();
+ SWTBotEditor swtBotEditor = SWTBotDesignerHelper.getTableDialectEditorBots(title).get(0);
+ return swtBotEditor;
+ }
+
+ /**
+ * Get all {@link SWTBotEditor} corresponding to a Table DialectEditor with
+ * <code>title</code> has title.
+ *
+ * @param title
+ * the title of the searched editor
+ *
+ * @return all {@link SWTBotEditor} corresponding to a Table DialectEditor
+ * with <code>title</code> has title
+ */
+ public static List<SWTBotEditor> getTableDialectEditorBots(String title) {
+ List<SWTBotEditor> tableDialectEditorBots = new ArrayList<SWTBotEditor>();
+ Matcher<IEditorReference> withPartName = org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName(title);
+ final Matcher<IEditorReference> matcher = Matchers.allOf(IsInstanceOf.instanceOf(IEditorReference.class), withPartName);
+ final WaitForEditor waitForEditor = Conditions.waitForEditor(matcher);
+ SWTBotDesignerHelper.bot.waitUntilWidgetAppears(waitForEditor);
+ List<IEditorReference> editorReferences = waitForEditor.getAllMatches();
+ for (IEditorReference editorReference : editorReferences) {
+ IEditorPart editorPart = editorReference.getEditor(false);
+ if (editorPart instanceof DTableEditor) {
+ SWTBotEditor swtBotEditor = new SWTBotEditor(editorReference, SWTBotDesignerHelper.bot);
+ tableDialectEditorBots.add(swtBotEditor);
+ }
+ }
+ return tableDialectEditorBots;
+ }
+
+ /**
+ * Attempts to locate the editor matching the given name. If no match is
+ * found an exception will be thrown. The name is the name as displayed on
+ * the editor's tab in eclipse.
+ *
+ * @param fileName
+ * the name of the file.
+ * @param index
+ * in case of multiple views with the same fileName.
+ * @return an editor for the specified fileName.
+ * @throws WidgetNotFoundException
+ * if the editor is not found.
+ */
+ public static SWTBotDesignerEditor getDesignerEditor(final String fileName, final int index) throws WidgetNotFoundException {
+ final Matcher<IEditorReference> withPartName = org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory.withPartName(fileName);
+ return SWTBotDesignerHelper.getDesignerEditor(withPartName, index);
+ }
+
+ private static SWTBotDesignerEditor getDesignerEditor(final Matcher<IEditorReference> withPartName, final int index) throws WidgetNotFoundException {
+ SWTBotDesignerEditor swtBotDesignerEditor = null;
+ final Matcher<IEditorReference> matcher = Matchers.allOf(IsInstanceOf.instanceOf(IEditorReference.class), withPartName);
+ final WaitForEditor waitForEditor = Conditions.waitForEditor(matcher);
+ SWTBotDesignerHelper.bot.waitUntilWidgetAppears(waitForEditor);
+ IEditorReference editorReference = waitForEditor.get(index);
+ if (editorReference.getEditor(false) instanceof DDiagramEditor) {
+ swtBotDesignerEditor = new SWTBotDesignerEditor(waitForEditor.get(index), SWTBotDesignerHelper.bot);
+ }
+ return swtBotDesignerEditor;
+ }
+
+ /**
+ * Close the specified {@link SWTBotEditor}.
+ *
+ * @param swtBotEditor
+ * the specified {@link SWTBotEditor}
+ * @param save
+ * tells if the editor to close must be saved or not
+ */
+ public static void close(final SWTBotEditor swtBotEditor, final boolean save) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ swtBotEditor.getReference().getPage().closeEditor(swtBotEditor.getReference().getEditor(false), save);
+ }
+ });
+ }
+
+ /**
+ * Close all opened {@link SWTBotEditor}s.
+ *
+ * @param save
+ * tells if the editor to close must be saved or not
+ */
+ public static void closeAllEditors(final boolean save) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ List<? extends SWTBotEditor> editors = SWTBotDesignerHelper.bot.editors();
+ for (SWTBotEditor swtBotEditor : editors) {
+ swtBotEditor.getReference().getPage().closeEditor(swtBotEditor.getReference().getEditor(false), save);
+ }
+ }
+ });
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMEditor.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMEditor.java
new file mode 100644
index 0000000000..fd905ef391
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMEditor.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.editor;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.sirius.tests.swtbot.support.api.bot.description.GroupBot;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusPropertiesView;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.PartInitException;
+
+/**
+ *
+ * Help to manipulate an odesign editor.
+ *
+ * @author amartin
+ *
+ */
+public class SWTBotVSMEditor extends SWTBotEditor {
+
+ // private UIResource sessionResource;
+ private IPath odesignPath;
+
+ private SiriusPropertiesView propertiesView;
+
+ /**
+ * The constructor.
+ *
+ * @param reference
+ * the editor reference.
+ * @param bot
+ * the bot.
+ * @param sessionResource
+ * the URI of the session.
+ * @param propertiesView
+ * the properties view.
+ * @throws WidgetNotFoundException
+ * the error.
+ */
+ public SWTBotVSMEditor(IEditorReference reference, SWTWorkbenchBot bot, UIResource sessionResource, SiriusPropertiesView propertiesView) throws WidgetNotFoundException {
+ super(reference, bot);
+ // this.sessionResource = sessionResource;
+ this.propertiesView = propertiesView;
+ }
+
+ /**
+ * Construct a new instance.
+ *
+ * @param reference
+ * the editor reference
+ * @param bot
+ * the workbench bot
+ * @throws WidgetNotFoundException
+ * if an exception occurs
+ */
+ public SWTBotVSMEditor(final IEditorReference reference, final SWTWorkbenchBot bot) throws WidgetNotFoundException {
+ super(reference, bot);
+ try {
+ IEditorInput input = reference.getEditorInput();
+ odesignPath = getPath(input);
+ } catch (PartInitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private IPath getPath(IEditorInput input) {
+ IPath path = null;
+ if (input instanceof IFileEditorInput) {
+ path = ((IFileEditorInput) input).getFile().getFullPath();
+ } else if (input instanceof IPathEditorInput) {
+ path = ((IPathEditorInput) input).getPath();
+ }
+ return path;
+ }
+
+ /**
+ * Get Group of session tree odesign.
+ *
+ * @return Root of session tree.
+ */
+ public GroupBot getGroup() {
+
+ SWTBotTree tree = bot.treeWithLabel("Resource Set");
+
+ final URI diagramURI = URI.createPlatformResourceURI(odesignPath.toString(), true);
+
+ tree.setFocus();
+
+ // return new GroupBot(bot, new SWTBotTreeItem(tree.widget.getItem(0))
+ // .getNode(0).expand(), propertiesView);
+
+ final SWTBotTreeItem treeItem = tree.getTreeItem(diagramURI.toString());
+
+ bot.sleep(250);
+ return new GroupBot(bot, treeItem.getNode(0).expand(), propertiesView);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMHelper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMHelper.java
new file mode 100644
index 0000000000..62b29faf1a
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/editor/SWTBotVSMHelper.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.editor;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.eclipse.finder.waits.Conditions;
+import org.eclipse.swtbot.eclipse.finder.waits.WaitForEditor;
+import org.eclipse.swtbot.eclipse.gef.finder.matchers.IsInstanceOf;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.ui.IEditorReference;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+
+/**
+ * SWTBot VSM helper.
+ *
+ * @author amartin
+ */
+public final class SWTBotVSMHelper {
+
+ /**
+ * SWTWorkbenchBot
+ */
+ private static SWTWorkbenchBot bot = new SWTWorkbenchBot();
+
+ private SWTBotVSMHelper() {
+
+ }
+
+ /**
+ * get the odesign editor.
+ *
+ * @param partialFileName
+ * the name of the edited odesign
+ * @return the odesign editor.
+ * @throws WidgetNotFoundException
+ * if it fails.
+ */
+ public static SWTBotVSMEditor getVSMEditorContainingName(final String partialFileName) throws WidgetNotFoundException {
+ final Matcher<IEditorReference> withPartName = WidgetMatcherFactory.withPartName(Matchers.containsString(partialFileName));
+ return SWTBotVSMHelper.getVSMEditor(withPartName, 0);
+ }
+
+ /**
+ * Retrieve the Odesign Editor with the name.
+ *
+ * @param fileName
+ * the file name of the odesign edited.
+ * @param index
+ * the index.
+ * @return the new editor
+ * @throws WidgetNotFoundException
+ * if it fails.
+ */
+ public static SWTBotVSMEditor getVSMEditor(final String fileName, final int index) throws WidgetNotFoundException {
+ final Matcher<IEditorReference> withPartName = WidgetMatcherFactory.withPartName(fileName);
+ return SWTBotVSMHelper.getVSMEditor(withPartName, index);
+ }
+
+ private static SWTBotVSMEditor getVSMEditor(final Matcher<IEditorReference> withPartName, final int index) throws WidgetNotFoundException {
+ final Matcher<IEditorReference> matcher = Matchers.allOf(IsInstanceOf.instanceOf(IEditorReference.class), withPartName);
+ final WaitForEditor waitForEditor = Conditions.waitForEditor(matcher);
+ SWTBotVSMHelper.bot.waitUntilWidgetAppears(waitForEditor);
+ return new SWTBotVSMEditor(waitForEditor.get(index), SWTBotVSMHelper.bot);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/AbstractDecoratorMatcher.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/AbstractDecoratorMatcher.java
new file mode 100644
index 0000000000..c93aef806b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/AbstractDecoratorMatcher.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoration;
+import org.eclipse.gmf.runtime.draw2d.ui.internal.figures.ImageFigureEx;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swtbot.swt.finder.matchers.AbstractMatcher;
+
+/**
+ *
+ * This class is used to check if a graphical element has a decorator.
+ *
+ * @author amartin
+ */
+public abstract class AbstractDecoratorMatcher extends AbstractMatcher<EditPart> {
+
+ /**
+ * return the image of the targeted decorator.
+ *
+ * @return the image of te decorator
+ */
+ protected abstract Image getImage();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean doMatch(final Object item) {
+ if (item instanceof EditPart) {
+ EditPart part = (EditPart) item;
+ EditPartViewer viewer = part.getViewer();
+ Map<IFigure, EditPart> mapDecorator = viewer.getVisualPartMap();
+
+ for (final Entry<IFigure, EditPart> entry : mapDecorator.entrySet()) {
+ final EditPart currentPart = entry.getValue();
+ final IFigure visual = entry.getKey();
+ if (currentPart.equals(part) && visual instanceof IDecoration) {
+ return isTheRightDecoration(visual);
+ }
+
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isTheRightDecoration(final IFigure item) {
+ final IFigure decoration = item;
+ if (!decoration.getChildren().isEmpty() && decoration.getChildren().get(0) instanceof ImageFigureEx) {
+ return ((ImageFigureEx) decoration.getChildren().get(0)).getImage().equals(getImage());
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/DeletedDecoratorMatcher.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/DeletedDecoratorMatcher.java
new file mode 100644
index 0000000000..a7899a5253
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/DeletedDecoratorMatcher.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.hamcrest.Description;
+
+/**
+ * This class helps to check if the graphical element has a deleted decorator.
+ *
+ * @author amartin
+ */
+public class DeletedDecoratorMatcher extends AbstractDecoratorMatcher {
+ @Override
+ protected Image getImage() {
+
+ return AbstractUIPlugin.imageDescriptorFromPlugin("/org.eclipse.sirius.diagram", "/icons/delete.gif").createImage();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("conformance info decorator matcher '"); //$NON-NLS-1$
+
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/NoteEditPartMatcher.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/NoteEditPartMatcher.java
new file mode 100644
index 0000000000..d0216d20ce
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/NoteEditPartMatcher.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.NoteEditPart;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+
+/**
+ * A Matcher to get {@link NoteEditPart}'s bot.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class NoteEditPartMatcher extends BaseMatcher<EditPart> {
+ @Override
+ public boolean matches(Object item) {
+ boolean result = false;
+ if (item instanceof EditPart) {
+ EditPart editPart = (EditPart) item;
+ result = editPart instanceof NoteEditPart || editPart instanceof org.eclipse.sirius.diagram.ui.internal.edit.parts.NoteEditPart;
+ }
+ return result;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matcher to get all NoteEditPart (gmf or viewpoint)");
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithDRepresentationElementType.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithDRepresentationElementType.java
new file mode 100644
index 0000000000..b00c360303
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithDRepresentationElementType.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramNameEditPart;
+import org.eclipse.sirius.viewpoint.DRepresentationElement;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+
+/**
+ * A Matcher to get {@link EditPart} with a specified
+ * {@link DRepresentationElement} type.
+ *
+ * @param <T>
+ * the type of the {@link DRepresentationElement}
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class WithDRepresentationElementType<T extends DRepresentationElement> extends BaseMatcher<EditPart> {
+
+ private final Class<T> type;
+
+ /**
+ * Default constructor.
+ *
+ * @param type
+ * the type of the {@link DRepresentationElement}
+ */
+ public WithDRepresentationElementType(Class<T> type) {
+ this.type = type;
+ }
+
+ @Override
+ public boolean matches(Object item) {
+ boolean result = false;
+ if (item instanceof EditPart && !(item instanceof AbstractDiagramNameEditPart) && !(item instanceof CompartmentEditPart)) {
+ EditPart editPart = (EditPart) item;
+ Object model = editPart.getModel();
+ if (model instanceof View) {
+ View view = (View) model;
+ EObject element = view.getElement();
+ result = type.isInstance(element);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matcher to get all EditParts having a DRepresentationElement of the following type : " + type);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithSemantic.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithSemantic.java
new file mode 100644
index 0000000000..356c60237e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/WithSemantic.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.sirius.viewpoint.DSemanticDecorator;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * A Matcher to get {@link EditPart} with semantic in parameter.
+ *
+ * @author edugueperoux
+ */
+public class WithSemantic extends BaseMatcher<EditPart> {
+
+ private final EObject semantic;
+
+ /**
+ * Default constructor.
+ *
+ * @param semantic
+ * for which get a associated Bot
+ */
+ public WithSemantic(EObject semantic) {
+ this.semantic = semantic;
+ }
+
+ /**
+ * Get a default {@link WithSemantic}.
+ *
+ * @param semantic
+ * for which get a associated Bot
+ *
+ * @return a default {@link WithSemantic}
+ */
+ public static Matcher<EditPart> withSemantic(EObject semantic) {
+ Preconditions.checkNotNull(semantic, "Can't execute this matcher on a null semantic elt");
+ return new WithSemantic(semantic);
+ }
+
+ @Override
+ public boolean matches(Object item) {
+ boolean result = false;
+ if (item instanceof EditPart) {
+ EditPart editPart = (EditPart) item;
+ Object model = editPart.getModel();
+ if (model instanceof View) {
+ View view = (View) model;
+ EObject element = view.getElement();
+ if (element instanceof DSemanticDecorator) {
+ DSemanticDecorator dSemanticDecorator = (DSemanticDecorator) element;
+ EObject semanticTarget = dSemanticDecorator.getTarget();
+ result = semanticTarget != null && semanticTarget.equals(semantic);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matcher to get all EditParts referencing indirectly : " + semantic + ", which are child EditParts of contextual EditPart");
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/PointAround.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/PointAround.java
new file mode 100644
index 0000000000..3042fd5274
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/PointAround.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher.geometry;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+/**
+ * Matcher to check if a spcified point is "around" another expected point, that
+ * is to say, specified point is located in a circle centered on expected point
+ * and whom radius is equal to provided distance, edge of the circle included.
+ *
+ * @author dlecan
+ */
+public class PointAround extends BaseMatcher<Point> {
+
+ private final int distance;
+
+ private final Point expected;
+
+ /**
+ * Constructor.
+ *
+ * @param expected
+ * Expected point.
+ * @param distance
+ * Distance to use.
+ */
+ protected PointAround(Point expected, int distance) {
+ this.expected = expected;
+ this.distance = distance;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(Object item) {
+ if (item instanceof Point) {
+ return PointAround.isAround(expected, (Point) item, distance);
+ }
+ return false;
+ }
+
+ /**
+ * Check if a point is around another.
+ *
+ * @param expected
+ * Expected point.
+ * @param actual
+ * ctual point
+ * @param distance
+ * Distance to check.
+ * @return <code>true</code> if actual point is around expected point.
+ */
+ protected static boolean isAround(Point expected, Point actual, int distance) {
+ return actual.getDistance2(expected) <= distance * distance;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("A point around ");
+ description.appendValue(expected);
+ description.appendText("and whom distance from this point is less or equal to " + distance);
+ }
+
+ /**
+ * Create matcher.
+ *
+ * @param expected
+ * Expected point.
+ * @param distance
+ * Distance between.
+ * @return Matcher.
+ */
+ @Factory
+ public static Matcher<Point> around(Point expected, int distance) {
+ return new PointAround(expected, distance);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/RectangleAround.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/RectangleAround.java
new file mode 100644
index 0000000000..c94b9f5498
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/matcher/geometry/RectangleAround.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.matcher.geometry;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
+
+/**
+ * Matcher to check if a spcified rectangle is "around" another expected
+ * rectangle, that is to say, topleft point of the specified rectangle is
+ * located in a circle centered on topleft point of expected rectangle and whom
+ * radius is equal to provided distance, edge of the circle included. More over,
+ * both rectangles must have same heigh and width.
+ *
+ * @author dlecan
+ */
+public class RectangleAround extends BaseMatcher<Rectangle> {
+
+ private final int distance;
+
+ private final Rectangle expected;
+
+ /**
+ * Constructor.
+ *
+ * @param expected
+ * Expected rectangle.
+ * @param distance
+ * Distance to use.
+ */
+ protected RectangleAround(Rectangle expected, int distance) {
+ this.expected = expected;
+ this.distance = distance;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean matches(Object item) {
+ boolean result = false;
+ if (item instanceof Rectangle) {
+ Rectangle other = (Rectangle) item;
+ result = other.height == expected.height;
+ result = result && other.width == expected.width;
+ result = result && PointAround.isAround(expected.getTopLeft(), other.getTopLeft(), distance);
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("A rectangle around ");
+ description.appendValue(expected);
+ description.appendText("and whom distance from this rectangle is less or equal to " + distance);
+ }
+
+ /**
+ * Create matcher.
+ *
+ * @param expected
+ * Expected rectangle.
+ * @param distance
+ * Distance between.
+ * @return Matcher.
+ */
+ @Factory
+ public static Matcher<Rectangle> around(Rectangle expected, int distance) {
+ return new RectangleAround(expected, distance);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/perspective/DesignerPerspectives.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/perspective/DesignerPerspectives.java
new file mode 100644
index 0000000000..b121fc9a41
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/perspective/DesignerPerspectives.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.perspective;
+
+import org.eclipse.sirius.tests.swtbot.support.api.condition.PerspectiveActivatedCondition;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+
+/**
+ * A class to manage perspectives provided with Sirius.
+ *
+ * @author mchauvin
+ */
+public class DesignerPerspectives {
+
+ private static final String MODELING_PERSPECTIVE_NAME = "Modeling";
+
+ private static final String VIEWPOINT_PERSPECTIVE_NAME = "Sirius";
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Construct a new instance.
+ *
+ * @param bot
+ * the workbench bot
+ */
+ public DesignerPerspectives(final SWTWorkbenchBot bot) {
+ this.bot = bot;
+ }
+
+ /**
+ * Open the design perspective.
+ */
+ public void openModelingPerspective() {
+ openPerspective(DesignerPerspectives.MODELING_PERSPECTIVE_NAME);
+ }
+
+ /**
+ * Open the Sirius perspective.
+ */
+ public void openSiriusPerspective() {
+ openPerspective(DesignerPerspectives.VIEWPOINT_PERSPECTIVE_NAME);
+ }
+
+ /**
+ * Open a perspective.
+ *
+ * @param perspectiveName
+ * the perspective to open.
+ */
+ public void openPerspective(final String perspectiveName) {
+ if (!bot.activePerspective().getLabel().equals(perspectiveName)) {
+ bot.perspectiveByLabel(perspectiveName).activate();
+ bot.waitUntil(new PerspectiveActivatedCondition(bot, perspectiveName));
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractMMEcoreBasedScenarioTestCase.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractMMEcoreBasedScenarioTestCase.java
new file mode 100644
index 0000000000..9a7070b711
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractMMEcoreBasedScenarioTestCase.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.test;
+
+import java.util.Collections;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase;
+
+/**
+ * Class to handle things on ecore model just before closing welcome page.
+ *
+ * @author amartin
+ */
+public abstract class AbstractMMEcoreBasedScenarioTestCase extends AbstractSiriusSwtBotGefTestCase {
+
+ /**
+ * Models forlder.
+ */
+ protected static final String MODELS_DIR = "Models";
+
+ private static final String SEPARATOR = "/";
+
+ /**
+ * Set up.
+ *
+ * @throws Exception
+ * the exception when error.
+ */
+ @Override
+ protected void onSetUpBeforeClosingWelcomePage() throws Exception {
+
+ final Resource ecoreRes = new ResourceSetImpl().createResource(URI.createPlatformResourceURI(AbstractMMEcoreBasedScenarioTestCase.SEPARATOR + getProjectName()
+ + AbstractMMEcoreBasedScenarioTestCase.SEPARATOR + AbstractMMEcoreBasedScenarioTestCase.MODELS_DIR + AbstractMMEcoreBasedScenarioTestCase.SEPARATOR + "Ecore.ecore", true));
+ ecoreRes.getContents().add(EcoreUtil.copy(EcorePackage.eINSTANCE));
+ ecoreRes.save(Collections.EMPTY_MAP);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractScenarioTestCase.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractScenarioTestCase.java
new file mode 100644
index 0000000000..380acad680
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/test/AbstractScenarioTestCase.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.test;
+
+import java.util.Collections;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase;
+
+/**
+ * Class to handle things on ecore model just before closing welcome page.
+ *
+ * @author cbrun
+ */
+public abstract class AbstractScenarioTestCase extends AbstractSiriusSwtBotGefTestCase {
+
+ /**
+ * Models folder.
+ */
+ protected static final String MODELS_DIR = "Models";
+
+ private static final String SEPARATOR = "/";
+
+ /**
+ * Setup.
+ *
+ * @throws Exception
+ * the error.
+ */
+ @Override
+ protected void onSetUpBeforeClosingWelcomePage() throws Exception {
+
+ final Resource ecoreRes = new ResourceSetImpl().createResource(URI.createPlatformResourceURI(AbstractScenarioTestCase.SEPARATOR + getProjectName() + AbstractScenarioTestCase.SEPARATOR
+ + AbstractScenarioTestCase.MODELS_DIR + AbstractScenarioTestCase.SEPARATOR + "Ecore.ecore", true));
+ EPackage packageRoot = EcoreFactory.eINSTANCE.createEPackage();
+ packageRoot.setName("ecore");
+ ecoreRes.getContents().add(packageRoot);
+ ecoreRes.save(Collections.EMPTY_MAP);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/DesignerViews.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/DesignerViews.java
new file mode 100644
index 0000000000..7b6095f1a3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/DesignerViews.java
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.view;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.junit.Assert;
+
+/**
+ * Utility class to open and get the Eclipse views.
+ *
+ * @author mchauvin
+ */
+public class DesignerViews {
+
+ private static final String OUTLINE = "Outline";
+
+ private static final String WINDOW = "Window";
+
+ private static final String SHOW_VIEW = "Show View";
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Construct a new instance.
+ *
+ * @param bot
+ * the workbench bot
+ */
+ public DesignerViews(final SWTWorkbenchBot bot) {
+ this.bot = bot;
+ }
+
+ /**
+ * Open a view with the Eclipse API.
+ *
+ * @param viewId
+ * The id of the view to open.
+ * @param viewTitle
+ * The title of the view
+ * @return The SWTBotView
+ */
+ public SWTBotView openViewByAPI(final String viewId, String viewTitle) {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(viewId);
+ } catch (PartInitException e) {
+ Assert.fail("Unable to open errorLog view : " + e.getMessage());
+ }
+ }
+ });
+ return bot.viewByTitle(viewTitle);
+ }
+
+ /**
+ * Open a view.
+ *
+ * @param categoryName
+ * The name of the category in the list of views
+ * @param viewName
+ * The name of the label in the list of views and the name of the
+ * opened view.
+ * @return The SWTBotView
+ */
+ public SWTBotView openView(String categoryName, String viewName) {
+ return openView(categoryName, viewName, viewName);
+ }
+
+ /**
+ * Open a view.
+ *
+ * @param categoryName
+ * The name of the category in the list of views
+ * @param labelInList
+ * The name of the label in the list of views
+ * @param viewTitle
+ * The title of the view
+ * @return The SWTBotView
+ */
+ public SWTBotView openView(String categoryName, String labelInList, String viewTitle) {
+ bot.menu(DesignerViews.WINDOW).menu(DesignerViews.SHOW_VIEW).menu("Other...").click();
+ bot.waitUntil(Conditions.shellIsActive("Show View"));
+
+ bot.text().setText(labelInList);
+ // Wait that the filter is apply on the tree and expand all the needed
+ // nodes
+ bot.sleep(500);
+ // The node is already expanded (so don't use expand method)
+ bot.tree().getTreeItem(categoryName).getNode(labelInList).select();
+ final SWTBotButton okButton = bot.button("OK");
+ bot.waitUntil(new OKButtonEnabledCondition(okButton));
+ okButton.click();
+ return bot.viewByTitle(viewTitle);
+ }
+
+ /**
+ * Open the outline view.
+ *
+ * @return the opened outline view
+ */
+ public SiriusOutlineView openOutlineView() {
+
+ bot.menu(DesignerViews.WINDOW).menu(DesignerViews.SHOW_VIEW).menu(DesignerViews.OUTLINE).click();
+ return getOutlineView();
+ }
+
+ /**
+ * Get the already opened outline view.
+ *
+ * @return the outline view
+ */
+ public SiriusOutlineView getOutlineView() {
+ return new SiriusOutlineView(bot, bot.viewByTitle(DesignerViews.OUTLINE));
+ }
+
+ /**
+ * A class to wait until a button is enabled.
+ *
+ * @author mchauvin
+ */
+ private class OKButtonEnabledCondition extends DefaultCondition {
+
+ private final SWTBotButton okButton;
+
+ public OKButtonEnabledCondition(final SWTBotButton okButton) {
+ this.okButton = okButton;
+ }
+
+ @Override
+ public String getFailureMessage() {
+ return "ok button is not enabled";
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return okButton.isEnabled();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusOutlineView.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusOutlineView.java
new file mode 100644
index 0000000000..b73d90a121
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusOutlineView.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.view;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTable;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
+
+/**
+ * The viewpoint outline view wrapper. it allows one to activate/deactivate
+ * layers, filters and play with reveal/hide commands.
+ *
+ * @author mchauvin
+ */
+public class SiriusOutlineView {
+
+ private static final int LAYER_TEXT_COLUMN_INDEX = 2;
+
+ private static final int FILTER_TEXT_COLUMN_INDEX = 1;
+
+ private final SWTBotView view;
+
+ private final SWTWorkbenchBot bot;
+
+ /**
+ * Create a new instance.
+ *
+ * @param bot
+ * the workbench bot
+ * @param view
+ * the outline view
+ */
+ public SiriusOutlineView(final SWTWorkbenchBot bot, final SWTBotView view) {
+ this.view = view;
+ this.bot = bot;
+ }
+
+ /**
+ * Activate the layer page.
+ *
+ * @return the layers page
+ */
+ public SiriusOutlineView layers() {
+ view.toolbarToggleButton("Layers").click();
+ return this;
+ }
+
+ /**
+ * Activate or deactivate a layer.
+ *
+ * @param layer
+ * the layer name
+ */
+ public void activateLayer(final String layer) {
+ activate(layer, SiriusOutlineView.LAYER_TEXT_COLUMN_INDEX);
+ }
+
+ /**
+ * Activate the filters page.
+ *
+ * @return the filters page
+ */
+ public SiriusOutlineView filters() {
+ view.toolbarToggleButton("Filters").click();
+ return this;
+ }
+
+ /**
+ * Activate or deactivate a filter.
+ *
+ * @param filter
+ * the filter name
+ */
+ public void activateFilter(final String filter) {
+ activate(filter, SiriusOutlineView.FILTER_TEXT_COLUMN_INDEX);
+ }
+
+ private void activate(final String id, final int textColumn) {
+ final SWTBot tableBot = view.bot();
+ final SWTBotTable table = tableBot.table();
+ for (int i = 0; i < table.rowCount(); i++) {
+ final int rowPosition = i;
+ final SWTBotTableItem item = table.getTableItem(rowPosition);
+ final String text = item.getText(textColumn);
+ if (id.equals(text)) {
+ table.click(rowPosition, 0);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusPropertiesView.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusPropertiesView.java
new file mode 100644
index 0000000000..cdfb5b01a8
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/view/SiriusPropertiesView.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.view;
+
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerHelper;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+
+/**
+ * Handle the Properties view of the odesign editor.
+ *
+ * @author amartin
+ *
+ */
+public class SiriusPropertiesView {
+
+ private final SWTBotView propertiesView;
+
+ private final SWTBot bot;
+
+ /**
+ *
+ * The constructor.
+ *
+ * @param bot
+ * the bot.
+ * @param view
+ * the view to handle.
+ */
+ public SiriusPropertiesView(SWTBot bot, SWTBotView view) {
+ this.bot = bot;
+ propertiesView = view;
+ }
+
+ /**
+ * Set the property Name in the properties view.
+ *
+ * @param name
+ * the name to input.
+ *
+ */
+ public void setName(String name) {
+ propertiesView.setFocus();
+ SWTBotDesignerHelper.selectPropertyTabItem("General");
+ bot.textWithLabel("Name").setText(name);
+ }
+
+ /**
+ * Retrieve the name in the properties view.
+ *
+ * @return the value in the field Name.
+ */
+ public String getName() {
+ propertiesView.setFocus();
+ SWTBotDesignerHelper.selectPropertyTabItem("General");
+ /*
+ * maybe will have pb, in other case there has a .setfocus before the
+ * getText
+ */
+ return bot.textWithLabel("Name").getText();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/BackgroundColorFigureGetter.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/BackgroundColorFigureGetter.java
new file mode 100644
index 0000000000..23b7982393
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/BackgroundColorFigureGetter.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.emf.transaction.RunnableWithResult.Impl;
+import org.eclipse.swt.graphics.Color;
+
+/**
+ * A {@link RunnableWithResult} to get a {@link IFigure#getBackgroundColor()}
+ * from a {@link IFigure}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class BackgroundColorFigureGetter extends Impl<Color> implements RunnableWithResult<Color> {
+
+ private final IFigure figure;
+
+ /**
+ * Default constructor.
+ *
+ * @param figure
+ * the {@link IFigure} for which get the
+ * {@link IFigure#getBackgroundColor()}
+ */
+ public BackgroundColorFigureGetter(IFigure figure) {
+ this.figure = figure;
+ }
+
+ /**
+ * Overridden to get the {@link IFigure#getBackgroundColor()} corresponding
+ * to the specified {@link IFigure}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ setResult(figure.getBackgroundColor());
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/ContextualMenuItemGetter.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/ContextualMenuItemGetter.java
new file mode 100644
index 0000000000..82b23ae498
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/ContextualMenuItemGetter.java
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swtbot.swt.finder.results.Result;
+
+/**
+ * {@link Result} to get a {@link MenuItem} .
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class ContextualMenuItemGetter implements Result<MenuItem> {
+
+ private final Control control;
+
+ private final String[] path;
+
+ /**
+ * Default constructor.
+ *
+ * @param control
+ * the {@link Control} of which to get the contextual
+ * {@link Menu}.
+ *
+ * @param path
+ * the path of string corresponding to {@link MenuItem} from the
+ * {@link Menu} of the contextual menu to the searched
+ * {@link MenuItem}
+ */
+ public ContextualMenuItemGetter(Control control, String[] path) {
+ this.control = control;
+ this.path = path;
+ }
+
+ /**
+ * Overridden to get a {@link MenuItem}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public MenuItem run() {
+ MenuItem result = null;
+
+ Menu menu = control.getMenu();
+ int i;
+ for (i = 0; i < path.length; i++) {
+ String menuItemText = path[i];
+ result = getMenuItem(menu, menuItemText);
+ if (result == null) {
+ break;
+ }
+ menu = result.getMenu();
+ }
+ if (result != null && !result.getText().equals(path[path.length - 1])) {
+ result = null;
+ }
+ return result;
+ }
+
+ private MenuItem getMenuItem(Menu menu, String menuItemText) {
+ MenuItem result = null;
+ menu.notifyListeners(SWT.Show, new Event());
+ MenuItem[] items = menu.getItems();
+ for (MenuItem menuItem : items) {
+ if (menuItem.getText().equals(menuItemText)) {
+ result = menuItem;
+ break;
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/NodeFigureGradientDataGetter.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/NodeFigureGradientDataGetter.java
new file mode 100644
index 0000000000..c2b1806c76
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/NodeFigureGradientDataGetter.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.emf.transaction.RunnableWithResult.Impl;
+import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
+import org.eclipse.gmf.runtime.notation.datatype.GradientData;
+
+/**
+ * A {@link RunnableWithResult} to get a {@link GradientData} from a
+ * {@link NodeFigure}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class NodeFigureGradientDataGetter extends Impl<GradientData> implements RunnableWithResult<GradientData> {
+
+ private final NodeFigure nodeFigure;
+
+ /**
+ * Default constructor.
+ *
+ * @param nodeFigure
+ * the {@link NodeFigure} for which to get the
+ * {@link GradientData}
+ */
+ public NodeFigureGradientDataGetter(NodeFigure nodeFigure) {
+ this.nodeFigure = nodeFigure;
+ }
+
+ /**
+ * Overridden to get the {@link GradientData} corresponding to the specified
+ * {@link NodeFigure}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ if (nodeFigure.isUsingGradient()) {
+ GradientData figureGradientData = new GradientData(nodeFigure.getGradientColor1(), nodeFigure.getGradientColor2(), nodeFigure.getGradientStyle());
+ setResult(figureGradientData);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotShellForTabbar.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotShellForTabbar.java
new file mode 100644
index 0000000000..01216ae9bc
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotShellForTabbar.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Decorations;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.ContextMenuFinder;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.results.ListResult;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+
+/**
+ * A specific version for popup menu in tab bar. use with care.
+ *
+ * @author mchauvin
+ */
+public class SWTBotShellForTabbar extends SWTBotShell {
+
+ /**
+ * Construct a new instance of this object.
+ *
+ * @param shell
+ * the widget
+ * @throws WidgetNotFoundException
+ * if the widget is <code>null</code> or widget has been
+ * disposed.
+ */
+ public SWTBotShellForTabbar(Shell shell) throws WidgetNotFoundException {
+ super(shell);
+ }
+
+ /**
+ * Gets the context menu on the given control, matching the text.
+ *
+ * @param control
+ * the control
+ * @param text
+ * the text on the context menu.
+ * @return the menu that has the given text.
+ * @throws WidgetNotFoundException
+ * if the widget is not found.
+ * @since 2.0
+ */
+ @Override
+ // varargs and generics doesn't mix well!
+ protected SWTBotMenu contextMenu(final Control control, final String text) throws WidgetNotFoundException {
+ Matcher<MenuItem> withMnemonic = WidgetMatcherFactory.withMnemonic(text);
+ final Matcher<MenuItem> matcher = Matchers.allOf(WidgetMatcherFactory.widgetOfType(MenuItem.class), withMnemonic);
+ final ContextMenuFinder menuFinder = new ContextMenuFinder(control) {
+ @Override
+ public List<MenuItem> findMenus(final Matcher<MenuItem> matcher) {
+ return UIThreadRunnable.syncExec(display, new ListResult<MenuItem>() {
+ @Override
+ public List<MenuItem> run() {
+ Menu[] menus = getMenus(widget);
+ for (int i = menus.length - 1; i >= 0; i--) {
+ if (menus[i] != null) {
+ for (MenuItem item : menus[i].getItems()) {
+ if (matcher.matches(item)) {
+ List<MenuItem> menuItems = new ArrayList<MenuItem>();
+ menuItems.add(item);
+ return menuItems;
+ }
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+ });
+ }
+ };
+
+ new SWTBot().waitUntil(new DefaultCondition() {
+ @Override
+ public String getFailureMessage() {
+ return "Could not find context menu with text: " + text; //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ return !menuFinder.findMenus(matcher).isEmpty();
+ }
+ });
+ return new SWTBotMenu(menuFinder.findMenus(matcher).get(0), matcher);
+ }
+
+ private Menu[] getMenus(final Shell shell) {
+ try {
+ Field field = Decorations.class.getDeclaredField("menus"); //$NON-NLS-1$
+ field.setAccessible(true);
+ return (Menu[]) field.get(shell);
+ } catch (final SecurityException e) {
+ // Cannot happen here
+ } catch (final IllegalArgumentException e) {
+ // // Cannot happen here
+ } catch (final IllegalAccessException e) {
+ // // Cannot happen here
+ } catch (final NoSuchFieldException e) {
+ // Cannot happen here
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotSiriusFigureCanvas.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotSiriusFigureCanvas.java
new file mode 100644
index 0000000000..374e27d474
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/SWTBotSiriusFigureCanvas.java
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.LightweightSystem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefFigureCanvas;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+
+/**
+ * Specific FigureCanvas to:
+ * <UL>
+ * <LI>override mouseMoveLeftClick method to avoid to pass SWT.BUTTON1 in mouse
+ * button down event. Indeed this disable the direct edit because the test
+ * getCurrentInput().getModifiers() == 0 fails in SelectEditPartTracker l.168
+ * (NoCopyDragEditPartsTrackerEx.performConditionalSelection)</LI>
+ * <LI>add typeSuffixText method to allow to edit by adding text at the end of
+ * the existing one.</LI>
+ * <UL>
+ *
+ * @author lredor
+ */
+public class SWTBotSiriusFigureCanvas extends SWTBotGefFigureCanvas {
+
+ /**
+ * Constructs a new instance from a {@link FigureCanvas}.
+ *
+ * @param canvas
+ * the canvas to wrap
+ * @throws WidgetNotFoundException
+ * if the widget is <code>null</code> or widget has been
+ * disposed.
+ */
+ public SWTBotSiriusFigureCanvas(FigureCanvas canvas) throws WidgetNotFoundException {
+ super(canvas);
+ }
+
+ /**
+ * Constructs a new instance from a {@link Canvas} and a
+ * {@link LightweightSystem}. If the canvas is an instance of
+ * {@link FigureCanvas}, use
+ * {@link SWTBotGefFigureCanvas#SWTBotGefFigureCanvas(FigureCanvas)}
+ * instead.
+ *
+ * @param canvas
+ * the canvas to wrap
+ * @param lightweightSystem
+ * the lightweight system to use
+ * @throws WidgetNotFoundException
+ * if the widget is <code>null</code> or widget has been
+ * disposed.
+ */
+ public SWTBotSiriusFigureCanvas(Canvas canvas, LightweightSystem lightweightSystem) throws WidgetNotFoundException {
+ super(canvas, lightweightSystem);
+ }
+
+ /**
+ * Duplicate : Only SWT.None is passed instead of SWT.BUTTON1 in mouse down
+ * event.
+ *
+ * @param xPosition
+ * the relative x position
+ * @param yPosition
+ * the relative y position
+ *
+ * @see org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefFigureCanvas#mouseMoveLeftClick(int,
+ * int)
+ */
+ @Override
+ public void mouseMoveLeftClick(final int xPosition, final int yPosition) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ org.eclipse.swt.events.MouseEvent meMove = wrapMouseEvent(xPosition, yPosition, 0, 0, 0);
+ eventDispatcher.dispatchMouseMoved(meMove);
+ org.eclipse.swt.events.MouseEvent meDown = wrapMouseEvent(xPosition, yPosition, 1, SWT.None, 1);
+ eventDispatcher.dispatchMousePressed(meDown);
+ org.eclipse.swt.events.MouseEvent meUp = wrapMouseEvent(xPosition, yPosition, 1, SWT.BUTTON1, 1);
+ eventDispatcher.dispatchMouseReleased(meUp);
+ }
+ });
+ }
+
+ private org.eclipse.swt.events.MouseEvent wrapMouseEvent(int x, int y, int button, int stateMask, int count) {
+ return new org.eclipse.swt.events.MouseEvent(createMouseEvent(x, y, button, stateMask, count));
+ }
+
+ /**
+ * Type the given text at the end of the given textControl.
+ *
+ * @param textControl
+ * The Text field to modify
+ * @param text
+ * The suffix to add
+ */
+ public void typeSuffixText(final Text textControl, final String text) {
+ for (int x = 0; x < text.length(); ++x) {
+ final char c = text.charAt(x);
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ textControl.setFocus();
+ textControl.notifyListeners(SWT.KeyDown, keyEvent(SWT.NONE, c, 0));
+ textControl.notifyListeners(SWT.KeyUp, keyEvent(SWT.NONE, c, 0));
+ textControl.setText(textControl.getText() + c);
+ }
+ });
+ try {
+ Thread.sleep(50L);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ }
+
+ // apply the value with a default selection event
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ textControl.setFocus();
+ textControl.notifyListeners(SWT.DefaultSelection, createEvent());
+ }
+ });
+ }
+
+ private Event keyEvent(int modificationKey, char c, int keyCode) {
+ Event keyEvent = createEvent();
+ keyEvent.stateMask = modificationKey;
+ keyEvent.character = c;
+ keyEvent.keyCode = keyCode;
+ return keyEvent;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemBackgroundColorQuery.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemBackgroundColorQuery.java
new file mode 100644
index 0000000000..b6e1d0a6e2
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemBackgroundColorQuery.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.sirius.ui.tools.api.color.VisualBindingManager;
+import org.eclipse.sirius.viewpoint.RGBValues;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that get the background color of a {@link TreeItem} , i.e.
+ * {@link TreeItem#getBackground()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemBackgroundColorQuery extends RunnableWithResult.Impl<RGBValues> {
+
+ private final TreeItem treeItem;
+
+ private int index;
+
+ /**
+ * Construct a {@link TreeItemBackgroundColorQuery} to get the background
+ * color of a {@link TreeItem} .
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ */
+ public TreeItemBackgroundColorQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Construct a {@link TreeItemBackgroundColorQuery} to get the background
+ * color of a {@link TreeItem} .
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param index
+ * the index in the {@link TreeItem} for which to get the
+ * background color
+ */
+ public TreeItemBackgroundColorQuery(TreeItem treeItem, int index) {
+ this.treeItem = treeItem;
+ this.index = index;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getExpanded()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ Color background = treeItem.getBackground(index);
+ RGBValues backgroundRGBvalues = VisualBindingManager.getDefault().createRGBvalues(background.getRGB());
+ setResult(backgroundRGBvalues);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpandedQuery.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpandedQuery.java
new file mode 100644
index 0000000000..9e61f4e6ec
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpandedQuery.java
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that tells if a {@link TreeItem} is expanded, i.e.
+ * {@link TreeItem#getExpanded()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemExpandedQuery extends RunnableWithResult.Impl<Boolean> {
+
+ private final TreeItem treeItem;
+
+ /**
+ * Construct a {@link TreeItemExpandedQuery} to see if a {@link TreeItem} is
+ * expanded.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to check expansion
+ */
+ public TreeItemExpandedQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getExpanded()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ boolean expanded = treeItem.getExpanded();
+ setResult(expanded);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpander.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpander.java
new file mode 100644
index 0000000000..692c58e813
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemExpander.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Expands/Collapses a {@link TreeItem}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemExpander implements Runnable {
+
+ private final TreeItem treeItem;
+
+ private final boolean expand;
+
+ /**
+ * Construct a {@link TreeItemExpander} to expand or collapse a
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param expand
+ * true if we should expand, false if we should collapse
+ */
+ public TreeItemExpander(TreeItem treeItem, boolean expand) {
+ this.treeItem = treeItem;
+ this.expand = expand;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getExpanded()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ treeItem.setExpanded(expand);
+ Event event = new Event();
+ event.item = treeItem;
+ treeItem.getParent().notifyListeners(expand ? SWT.Expand : SWT.Collapse, event);
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelColorQuery.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelColorQuery.java
new file mode 100644
index 0000000000..a03d23ebd9
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelColorQuery.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.sirius.ui.tools.api.color.VisualBindingManager;
+import org.eclipse.sirius.viewpoint.RGBValues;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that get the label color of a {@link TreeItem} , i.e.
+ * {@link TreeItem#getForeground()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemLabelColorQuery extends RunnableWithResult.Impl<RGBValues> {
+
+ private final TreeItem treeItem;
+
+ private int index;
+
+ /**
+ * Construct a {@link TreeItemLabelColorQuery} to get the label color.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to get the label color
+ */
+ public TreeItemLabelColorQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Construct a {@link TreeItemLabelColorQuery} to get the label color.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to get the label color
+ * @param index
+ * the index in the {@link TreeItem} for which to get the
+ * background color
+ */
+ public TreeItemLabelColorQuery(TreeItem treeItem, int index) {
+ this.treeItem = treeItem;
+ this.index = index;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getForeground()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ Color foreground = treeItem.getForeground(index);
+ RGBValues foregroundRGBvalues = VisualBindingManager.getDefault().createRGBvalues(foreground.getRGB());
+ setResult(foregroundRGBvalues);
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelFontFormatQuery.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelFontFormatQuery.java
new file mode 100644
index 0000000000..bd35a22d9b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelFontFormatQuery.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.sirius.viewpoint.FontFormat;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that get the label font format of a {@link TreeItem} , i.e.
+ * {@link TreeItem#getFont()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemLabelFontFormatQuery extends RunnableWithResult.Impl<FontFormat> {
+
+ private final TreeItem treeItem;
+
+ private int index;
+
+ /**
+ * Construct a {@link TreeItemLabelFontFormatQuery} to get the font format
+ * of a TreeItem.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to get the font format
+ */
+ public TreeItemLabelFontFormatQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Construct a {@link TreeItemLabelFontFormatQuery} to get the font format
+ * of a TreeItem.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to get the font format
+ *
+ * @param index
+ * the index in the {@link TreeItem} for which to get the font
+ * format
+ */
+ public TreeItemLabelFontFormatQuery(TreeItem treeItem, int index) {
+ this.treeItem = treeItem;
+ this.index = index;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getExpanded()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ Font font = treeItem.getFont(index);
+ FontData[] fontData = font.getFontData();
+ if (fontData.length > 0) {
+ int style = fontData[0].getStyle();
+ switch (style) {
+ case SWT.NORMAL:
+ setResult(FontFormat.NORMAL_LITERAL);
+ break;
+ case SWT.BOLD:
+ setResult(FontFormat.BOLD_LITERAL);
+ break;
+ case SWT.ITALIC:
+ setResult(FontFormat.ITALIC_LITERAL);
+ break;
+ default:
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelSizeQuery.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelSizeQuery.java
new file mode 100644
index 0000000000..3d16a00fd7
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/TreeItemLabelSizeQuery.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2011, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Query that get the label size of a {@link TreeItem} , i.e.
+ * {@link TreeItem#getFont()}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public class TreeItemLabelSizeQuery extends RunnableWithResult.Impl<Integer> {
+
+ private final TreeItem treeItem;
+
+ private int index;
+
+ /**
+ * Construct a {@link TreeItemLabelSizeQuery} to see if a {@link TreeItem}
+ * is expanded.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to check expansion
+ */
+ public TreeItemLabelSizeQuery(TreeItem treeItem) {
+ this.treeItem = treeItem;
+ }
+
+ /**
+ * Construct a {@link TreeItemLabelSizeQuery} to see if a {@link TreeItem}
+ * is expanded.
+ *
+ * @param treeItem
+ * the {@link TreeItem} on which to check expansion
+ * @param index
+ * the index in the {@link TreeItem} for which to get the label
+ */
+ public TreeItemLabelSizeQuery(TreeItem treeItem, int index) {
+ this.treeItem = treeItem;
+ this.index = index;
+ }
+
+ /**
+ * Overridden to test {@link TreeItem#getExpanded()}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ Font font = treeItem.getFont(index);
+ FontData[] fontData = font.getFontData();
+ if (fontData.length > 0) {
+ int labelSize = fontData[0].getHeight();
+ setResult(labelSize);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/WrappedSWTBotRadio.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/WrappedSWTBotRadio.java
new file mode 100644
index 0000000000..4e0f02ac24
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/api/widget/WrappedSWTBotRadio.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.api.widget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio;
+
+/**
+ * A temporary class used to work around a bug (see
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=344484).
+ *
+ * @author alagarde
+ */
+public class WrappedSWTBotRadio extends SWTBotRadio {
+
+ /**
+ * Default constructor.
+ *
+ * @param wrapped
+ * The wrapped SWTBot radio to override click method.
+ */
+ public WrappedSWTBotRadio(SWTBotRadio wrapped) {
+ super(wrapped.widget);
+ }
+
+ // CHECKSTYLE:OFF
+ /**
+ * Selects the radio button.
+ */
+ @Override
+ public SWTBotRadio click() {
+ if (isSelected()) {
+ log.debug(MessageFormat.format("Widget {0} is already selected, not clicking again.", this)); //$NON-NLS-1$
+ return this;
+ }
+ waitForEnabled();
+ log.debug(MessageFormat.format("Clicking on {0}", this)); //$NON-NLS-1$
+ asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ deselectOtherRadioButtons();
+ log.debug(MessageFormat.format("Clicking on {0}", this)); //$NON-NLS-1$
+ widget.setSelection(true);
+ }
+
+ /**
+ * @see "http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet224.java?view=co"
+ */
+ private void deselectOtherRadioButtons() {
+ if (hasStyle(widget.getParent(), SWT.NO_RADIO_GROUP)) {
+ return;
+ }
+ Widget[] siblings = SWTUtils.siblings(widget);
+ for (Widget widget : siblings) {
+ if (widget instanceof Button && hasStyle(widget, SWT.RADIO)) {
+ ((Button) widget).setSelection(false);
+ }
+ }
+ }
+ });
+ notify(SWT.MouseEnter);
+ notify(SWT.MouseMove);
+ notify(SWT.Activate);
+ notify(SWT.FocusIn);
+ notify(SWT.MouseDown);
+ notify(SWT.MouseUp);
+ notify(SWT.Selection);
+ notify(SWT.MouseHover);
+ notify(SWT.MouseMove);
+ notify(SWT.MouseExit);
+ notify(SWT.Deactivate);
+ notify(SWT.FocusOut);
+ log.debug(MessageFormat.format("Clicked on {0}", this)); //$NON-NLS-1$
+ return this;
+ }
+ // CHECKSTYLE:ON
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/DesignerSWTBotTestsSupportPlugin.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/DesignerSWTBotTestsSupportPlugin.java
new file mode 100644
index 0000000000..f4166aa793
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/DesignerSWTBotTestsSupportPlugin.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.internal;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle.
+ *
+ * @author mchauvin
+ */
+public class DesignerSWTBotTestsSupportPlugin extends Plugin {
+
+ /** The plug-in ID. */
+ public static final String PLUGIN_ID = "org.eclipse.sirius.tests.swtbot.support";
+
+ // The shared instance
+ private static DesignerSWTBotTestsSupportPlugin plugin;
+
+ @Override
+ public void start(final BundleContext context) throws Exception {
+ super.start(context);
+ DesignerSWTBotTestsSupportPlugin.plugin = this;
+ }
+
+ @Override
+ public void stop(final BundleContext context) throws Exception {
+ DesignerSWTBotTestsSupportPlugin.plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ *
+ * @return the shared instance
+ */
+ public static DesignerSWTBotTestsSupportPlugin getDefault() {
+ return DesignerSWTBotTestsSupportPlugin.plugin;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/business/UISessionCreationWizard.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/business/UISessionCreationWizard.java
new file mode 100644
index 0000000000..1ad68c210d
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/internal/business/UISessionCreationWizard.java
@@ -0,0 +1,296 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.internal.business;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.sirius.business.api.helper.SiriusUtil;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UILocalSession;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIProject;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.AirdPickingChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.SemanticModelPage;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.SessionChoice;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.VpSelectionAfterWizard;
+import org.eclipse.sirius.tests.swtbot.support.api.business.UISessionCreationWizardFlow.WizardOk;
+import org.eclipse.sirius.tests.swtbot.support.api.condition.ItemEnabledCondition;
+import org.eclipse.sirius.tests.swtbot.support.api.dialog.ViewpointSelectionDialog;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.WrappedSWTBotRadio;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotButton;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRadio;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Local session creation wizard.
+ *
+ * @author dlecan
+ */
+public class UISessionCreationWizard implements SessionChoice {
+
+ private static final String DEFAULT_SESSION_NAME = "representations";
+
+ private final AirdPickingChoice airdPickingChoice = new AirdPickingChoice() {
+ @Override
+ public WizardOk select(final UIResource res) {
+ sessionResource = res;
+ return wizardOK;
+
+ }
+
+ @Override
+ public WizardOk withDefaultSessionName() {
+ UISessionCreationWizard.this.withDefaultSessionName();
+ return wizardOK;
+ }
+
+ @Override
+ public UILocalSession withDefaultSessionNameWithoutViewpointSelection() {
+ UISessionCreationWizard.this.withDefaultSessionName();
+ bot.tree().getAllItems()[0].select();
+ final SWTBotButton button = bot.button("Finish");
+ SWTBotShell dialogShell = bot.activeShell();
+ bot.waitUntil(new ItemEnabledCondition(button));
+ button.click();
+ bot.waitUntil(Conditions.shellCloses(dialogShell));
+ sessionResource = new UIResource(uiProject, UISessionCreationWizard.DEFAULT_SESSION_NAME + "." + SiriusUtil.SESSION_RESOURCE_EXTENSION);
+ return new UILocalSession(getSessionResource());
+ }
+ };
+
+ private final SWTWorkbenchBot bot;
+
+ private UIResource modelResource;
+
+ private ViewpointSelectionDialog selectionDialog;
+
+ private final SemanticModelPage semanticModelPage = new SemanticModelPage() {
+
+ @Override
+ public AirdPickingChoice select(final UIResource res) {
+ UISessionCreationWizard.this.sessionResource = res;
+ return airdPickingChoice;
+ }
+
+ };
+
+ private String sessionName;
+
+ private UIResource sessionResource;
+
+ private UIProject uiProject;
+
+ private final VpSelectionAfterWizard vpSelection = new VpSelectionAfterWizard() {
+
+ @Override
+ public UILocalSession selectNoViewpoint() {
+ UISessionCreationWizard.this.selectNoViewpoint();
+ final UILocalSession lSession = UISessionCreationWizard.this.finish();
+ return lSession;
+ }
+
+ @Override
+ public UILocalSession selectViewpoints(final String... vps) {
+ UISessionCreationWizard.this.selectViewpoints(Sets.newHashSet(vps));
+ final UILocalSession lSession = UISessionCreationWizard.this.finish();
+ return lSession;
+ }
+ };
+
+ private final WizardOk wizardOK = new WizardOk() {
+ @Override
+ public VpSelectionAfterWizard finish() {
+ return vpSelection;
+ }
+
+ };
+
+ private SWTBotShell wizardShell;
+
+ /**
+ * Constructor.
+ */
+ public UISessionCreationWizard() {
+ bot = new SWTWorkbenchBot();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param pUIResource
+ * UI resource model used to open the wizard.
+ */
+ public UISessionCreationWizard(final UIResource pUIResource) {
+ this();
+ modelResource = pUIResource;
+ selectionDialog = new ViewpointSelectionDialog(bot);
+ wizardShell = bot.shell("New Representations File");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AirdPickingChoice emptySession() {
+ SWTBotRadio emptySessionRadioButton = bot.radio(0);
+ emptySessionRadioButton = new WrappedSWTBotRadio(emptySessionRadioButton);
+ emptySessionRadioButton.click();
+
+ final SWTBotButton button = bot.button("Next >");
+ bot.waitUntil(new ItemEnabledCondition(button));
+ button.click();
+ return airdPickingChoice;
+ }
+
+ /**
+ * Finish the wizard.
+ *
+ * @return {@link UILocalSession} to handle local session.
+ */
+ public UILocalSession finish() {
+ bot.waitUntil(Conditions.shellCloses(wizardShell));
+
+ return new UILocalSession(getModelResource(), getSessionResource());
+ }
+
+ /**
+ * From already selected semantic resource.
+ *
+ * @return Current {@link UISessionCreationWizard}.
+ */
+ @Override
+ public AirdPickingChoice fromAlreadySelectedSemanticResource() {
+ new WrappedSWTBotRadio(bot.radio("Initialization from a semantic resource")).click();
+ final SWTBotButton button = bot.button("Finish");
+ bot.waitUntil(new ItemEnabledCondition(button));
+ button.click();
+
+ return airdPickingChoice;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public SemanticModelPage fromSemanticResource() {
+ return semanticModelPage;
+ }
+
+ /**
+ * Returns the model resource.
+ *
+ * @return The model resource.
+ */
+ public UIResource getModelResource() {
+ return modelResource;
+ }
+
+ /**
+ * Returns the session resource.
+ *
+ * @return The session resource.
+ */
+ public UIResource getSessionResource() {
+
+ if (sessionResource == null) {
+
+ UIProject project = uiProject;
+ if (project == null) {
+ project = modelResource.getProject();
+ }
+ sessionResource = new UIResource(project, modelResource.getPath(), sessionName + "." + SiriusUtil.SESSION_RESOURCE_EXTENSION);
+ }
+
+ return sessionResource;
+ }
+
+ /**
+ * In method.
+ *
+ * @param pUiProject
+ * Project where to create Local Session.
+ * @return Current {@link UISessionCreationWizard}.
+ */
+ @Override
+ public UISessionCreationWizard in(final UIProject pUiProject) {
+ this.uiProject = pUiProject;
+ return this;
+ }
+
+ /**
+ * "Select Viewpoints" operation, but without viewpoint selection.
+ *
+ * @return Current {@link UISessionCreationWizard}
+ * @see #selectViewpoints(Set)
+ */
+ public UISessionCreationWizard selectNoViewpoint() {
+ return selectViewpoints(Collections.<String> emptySet());
+ }
+
+ /**
+ * Select one viewpoint.
+ *
+ * @param viewpointToSelect
+ * Viewpoint to select to finish the wizard
+ * @return Current {@link UISessionCreationWizard}
+ * @see #selectViewpoints(Set)
+ */
+ public UISessionCreationWizard selectViewpoint(final String viewpointToSelect) {
+ return selectViewpoints(Collections.singleton(viewpointToSelect));
+ }
+
+ /**
+ * "Select Viewpoints" operation (when creating a new local session, either
+ * via wizard or drag and drop of model in local session view).
+ *
+ * @param viewpointsToSelect
+ * Viewpoint to select to finish the wizard
+ * @return Current {@link UISessionCreationWizard}
+ */
+ public UISessionCreationWizard selectViewpoints(final Set<String> viewpointsToSelect) {
+ selectionDialog.selectViewpoint(viewpointsToSelect, Collections.<String> emptySet());
+ return this;
+ }
+
+ /**
+ * Create new local session with default name.
+ *
+ * @return Current {@link UISessionCreationWizard}.
+ */
+ public UISessionCreationWizard withDefaultSessionName() {
+ if (modelResource == null) {
+ sessionName = UISessionCreationWizard.DEFAULT_SESSION_NAME;
+ } else {
+ final int dotPos = modelResource.getName().lastIndexOf('.');
+ if (dotPos > -1) {
+ sessionName = modelResource.getName().substring(0, dotPos);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * With session name method.
+ *
+ * @param name
+ * Session name to define.
+ * @return Current {@link UISessionCreationWizard}.
+ */
+ public UISessionCreationWizard withSessionName(final String name) {
+ this.sessionName = name;
+ return this;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotCommonHelper.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotCommonHelper.java
new file mode 100644
index 0000000000..c68affd112
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotCommonHelper.java
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.gef.ConnectionEditPart;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
+import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotDesignerEditor;
+import org.eclipse.sirius.tests.swtbot.support.api.view.DesignerViews;
+import org.eclipse.sirius.tests.swtbot.support.api.view.SiriusOutlineView;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefConnectionEditPart;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
+/**
+ * Common helpers to simplify SWTBot.
+ *
+ * @author smonnier
+ */
+public final class SWTBotCommonHelper {
+
+ /**
+ * Storage of edge data.
+ *
+ * @author dlecan
+ */
+ public static class EdgeData {
+
+ /** Source. */
+ protected Point source;
+
+ /** Target. */
+ protected Point target;
+
+ /** Points. */
+ protected PointList points;
+
+ /** SWTBot edit part. */
+ protected SWTBotGefConnectionEditPart swtBotEditPart;
+
+ /**
+ * Returns the source.
+ *
+ * @return The source.
+ */
+ public Point getSource() {
+ return source;
+ }
+
+ /**
+ * Returns the target.
+ *
+ * @return The target.
+ */
+ public Point getTarget() {
+ return target;
+ }
+
+ /**
+ * Returns the points.
+ *
+ * @return The points.
+ */
+ public PointList getPoints() {
+ return points;
+ }
+
+ /**
+ * Returns the swtBotEditPart.
+ *
+ * @return The swtBotEditPart.
+ */
+ public SWTBotGefConnectionEditPart getSwtBotEditPart() {
+ return swtBotEditPart;
+ }
+ }
+
+ private static final String FILE = "File";
+
+ /**
+ * SWTWorkbenchBot
+ */
+ private static SWTWorkbenchBot bot = new SWTWorkbenchBot();
+
+ /**
+ * Avoid instantiation.
+ */
+ private SWTBotCommonHelper() {
+
+ }
+
+ /**
+ * Close the current editor.
+ */
+ public static void closeCurrentEditor() {
+ SWTBotCommonHelper.bot.menu(SWTBotCommonHelper.FILE).menu("Close").click();
+ }
+
+ /**
+ * Open an editor on a file.
+ *
+ * @param project
+ * the current project
+ * @param editorPath
+ * the file path
+ */
+ public static void openEditor(final String project, final String editorPath) {
+ final SWTBot packageExplorerBot = SWTBotCommonHelper.bot.viewByTitle("Model Explorer").bot();
+
+ final SWTBotTree wizardTree = packageExplorerBot.tree();
+ wizardTree.expandNode(project);
+ SWTBotTreeItem treeItem = wizardTree.getTreeItem(project);
+ treeItem.expand();
+
+ final String[] path = editorPath.split(Pattern.quote(File.separator));
+ for (final String s : path) {
+ treeItem = treeItem.expandNode(s);
+ }
+
+ treeItem.setFocus();
+ treeItem.select().contextMenu("Open").click();
+ }
+
+ /**
+ * Save the current editor.
+ */
+ public static void saveCurrentEditor() {
+ SWTBotCommonHelper.bot.menu(SWTBotCommonHelper.FILE).menu("Save").click();
+ }
+
+ /**
+ * Get all edges between to edit parts.
+ *
+ * @param source
+ * Source edit part.
+ * @param target
+ * Target edit part.
+ * @param editor
+ * Current editor.
+ * @return All {@link EdgeData}.
+ */
+ public static List<EdgeData> getEdgeData(final SWTBotGefEditPart source, final SWTBotGefEditPart target, final SWTBotDesignerEditor editor) {
+ final List<SWTBotGefConnectionEditPart> connectionEditParts = editor.getConnectionEditPart(source, target);
+
+ return Lists.transform(connectionEditParts, new Function<SWTBotGefConnectionEditPart, EdgeData>() {
+
+ /**
+ * @{inheritDoc
+ */
+ @Override
+ public EdgeData apply(final SWTBotGefConnectionEditPart from) {
+ final ConnectionEditPart connectionEditPart = from.part();
+ final PolylineConnectionEx connection = (PolylineConnectionEx) connectionEditPart.getFigure();
+ final EdgeData result = new EdgeData();
+ result.swtBotEditPart = from;
+ result.source = connection.getSourceAnchor().getReferencePoint();
+ result.target = connection.getTargetAnchor().getReferencePoint();
+ result.points = connection.getPoints().getCopy();
+ return result;
+ }
+ });
+ }
+
+ /**
+ * <p>
+ * Gets the outline view of the current editor and selects the "Outline"
+ * button. Returns the outline Tree of the opened outline.
+ * </p>
+ *
+ * <p>
+ * <b>Use examples : </b><br/>
+ * <code> SWTBotView view = SWTBotCommonHelper.getOutlineView(designerViews);<br/>
+ view.bot().tree().expandNode("p", true);<br/>
+ SWTBotTreeItem nodeItem = view.bot().tree().getTreeItem("p").getNode("myNode").click();<br/>
+ nodeItem.contextMenu("myContextMenu").click();
+ </code>
+ * </p>
+ *
+ * @param designerViews
+ * if your test extends
+ * {@link org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase}
+ * , you should pass the <code>designerViews</code> attribute.
+ * @return a {@link SWTBotView} allowing to manipulate the current editor's
+ * outline (focused on the outline Tree)
+ *
+ * @throws NoSuchFieldException
+ * if a reflective exception occurred while trying to get the
+ * outline
+ */
+ public static SWTBotView getOutlineView(DesignerViews designerViews) throws NoSuchFieldException {
+ try {
+ // Step 1.1 : open the outline view and get its SWTBotView
+ SiriusOutlineView outlineView = designerViews.openOutlineView();
+ Field field;
+ field = SiriusOutlineView.class.getDeclaredField("view");
+ field.setAccessible(true);
+ SWTBotView view;
+
+ view = (SWTBotView) field.get(outlineView);
+
+ // Step 1.2 : selecting the outline tree
+ view.toolbarButton("Outline").click();
+ return view;
+
+ } catch (IllegalArgumentException e) {
+ throw new NoSuchFieldException(e.getMessage());
+ } catch (IllegalAccessException e) {
+ throw new NoSuchFieldException(e.getMessage());
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotSplitEditor.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotSplitEditor.java
new file mode 100644
index 0000000000..391ff1efa3
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotSplitEditor.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.eclipse.sirius.tests.swtbot.support.internal.DesignerSWTBotTestsSupportPlugin;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swtbot.eclipse.gef.finder.SWTBotGefTestCase;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.PartPane;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * Utilities to split an eclipse editor. Use reflexivity to compile with eclipse
+ * 4.
+ *
+ * @author <a href="mailto:julien.dupont@obeo.fr">Julien DUPONT</a>
+ *
+ */
+@SuppressWarnings("restriction")
+public final class SWTBotSplitEditor extends SWTBotGefTestCase {
+
+ /**
+ * To test that the editor can be splits. With eclipse 4.2 this code not
+ * work so the variable value equals false.
+ */
+ private static boolean editorSplit = true;
+
+ /**
+ * Avoid instantiation.
+ */
+ private SWTBotSplitEditor() {
+
+ }
+
+ /**
+ * Split the editor area if there is at least two editors in it.
+ */
+ public static void splitEditorArea() {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ doSplitEditorArea();
+ }
+ });
+ }
+
+ private static void doSplitEditorArea() {
+ IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IWorkbenchPart part = workbenchPage.getActivePart();
+ try {
+ PartSite partSite = (PartSite) part.getSite();
+ Method getPane = partSite.getClass().getMethod("getPane", new Class[0]);
+ PartPane partPane = (PartPane) getPane.invoke(partSite);
+ Class layoutPartClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.LayoutPart");
+ IEditorReference[] editorReferences = workbenchPage.getEditorReferences();
+ Method getPart = layoutPartClass.getMethod("getPart", new Class[0]);
+ Object layoutPart = getPart.invoke(partPane);
+ // Do it only if we have more that one editor
+ if (editorReferences.length > 1) {
+ // Get PartPane that correspond to the active editor
+ getPane = ((PartSite) workbenchPage.getActiveEditor().getSite()).getClass().getMethod("getPane", new Class[0]);
+ PartPane currentEditorPartPane = (PartPane) getPane.invoke(workbenchPage.getActiveEditor().getSite());
+ Object editorSashContainer = null;
+ Class editorSashContainerClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.EditorSashContainer");
+ Class iLayoutContainerClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.ILayoutContainer");
+ Method getContainer = layoutPart.getClass().getMethod("getContainer", new Class[0]);
+ Object rootLayoutContainer = getContainer.invoke(layoutPart);
+ if (layoutPartClass.isInstance(rootLayoutContainer)) {
+ Object editorSashLayoutContainer = getContainer.invoke(layoutPartClass.cast(rootLayoutContainer));
+ if (editorSashContainerClass.isInstance(editorSashLayoutContainer)) {
+ editorSashContainer = editorSashContainerClass.cast(editorSashLayoutContainer);
+ }
+ }
+ /*
+ * Create a new part stack (i.e. a workbook) to home the
+ * currentEditorPartPane which hold the active editor
+ */
+ Class partStackClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.PartStack");
+ Object newPart = SWTBotSplitEditor.createStack(editorSashContainer);
+ if (newPart != null) {
+ partStackClass.cast(newPart);
+ Class[] paramTypes = new Class[2];
+ paramTypes[0] = layoutPartClass;
+ paramTypes[1] = iLayoutContainerClass;
+ Method stack = editorSashContainerClass.getMethod("stack", paramTypes);
+ stack.invoke(editorSashContainer, currentEditorPartPane, newPart);
+ if (layoutPartClass.isInstance(rootLayoutContainer)) {
+ Object cont = getContainer.invoke(layoutPartClass.cast(rootLayoutContainer));
+ Class partSashContainerClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.PartSashContainer");
+ if (partSashContainerClass.isInstance(cont)) {
+ // "Split" the editor area by adding the new
+ // part
+ partSashContainerClass.cast(cont);
+ paramTypes = new Class[1];
+ paramTypes[0] = layoutPartClass;
+ Method add = partSashContainerClass.getMethod("add", paramTypes);
+ add.invoke(cont, newPart);
+ }
+ }
+ } else {
+ SWTBotSplitEditor.setEditor_split(false);
+ }
+ }
+ } catch (IllegalAccessException iae) {
+ SWTBotSplitEditor.setEditor_split(false);
+ } catch (NoSuchMethodException nsme) {
+ SWTBotSplitEditor.setEditor_split(false);
+ } catch (InvocationTargetException iae) {
+ SWTBotSplitEditor.setEditor_split(false);
+ } catch (ClassNotFoundException cnfe) {
+ SWTBotSplitEditor.setEditor_split(false);
+ }
+ }
+
+ // CHECKSTYLE:OFF
+ /**
+ * A method to create a part stack container (a new workbook).
+ *
+ * @param editorSashContainer
+ * the <code>EditorSashContainer</code> to set for the returned
+ * <code>PartStack</code>
+ * @return a new part stack container
+ */
+ public static Object createStack(Object editorSashContainer) {
+ WorkbenchPage workbenchPage = (WorkbenchPage) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ Object newWorkbook = null;
+ try {
+ Class editorStackClass = DesignerSWTBotTestsSupportPlugin.getDefault().getBundle().loadClass("org.eclipse.ui.internal.EditorStack");
+
+ Class[] paramTypes = new Class[2];
+ paramTypes[0] = editorSashContainer.getClass();
+ paramTypes[1] = workbenchPage.getClass();
+ Method newEditorWorkbook = editorStackClass.getMethod("newEditorWorkbook", paramTypes);
+ newWorkbook = newEditorWorkbook.invoke(null, editorSashContainer, workbenchPage);
+ } catch (IllegalAccessException iae) {
+ return newWorkbook;
+ } catch (NoSuchMethodException nsme) {
+ return newWorkbook;
+ } catch (InvocationTargetException iae) {
+ return newWorkbook;
+ } catch (ClassNotFoundException cnfe) {
+ return newWorkbook;
+ }
+ return newWorkbook;
+ }
+
+ /**
+ * @return the editor_split
+ */
+ public static boolean isEditor_split() {
+ return SWTBotSplitEditor.editorSplit;
+ }
+
+ /**
+ * @param editor_split
+ * the editor_split to set
+ */
+ public static void setEditor_split(boolean editor_split) {
+ SWTBotSplitEditor.editorSplit = editor_split;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotUtils.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotUtils.java
new file mode 100644
index 0000000000..b3f710beed
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SWTBotUtils.java
@@ -0,0 +1,429 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils;
+
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.sirius.tests.swtbot.support.utils.menu.SWTBotContextMenu;
+import org.eclipse.sirius.viewpoint.FontFormat;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.results.BoolResult;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.results.WidgetResult;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+
+/**
+ * Some utilities.
+ *
+ * @author smonnier
+ */
+public final class SWTBotUtils {
+
+ // seconds
+ private static final long CLOSE_PROGRESS_MONITOR_TIMEOUT = TimeUnit.SECONDS.toSeconds(60);
+
+ /**
+ * SWTWorkbenchBot
+ */
+ private static SWTWorkbenchBot bot = new SWTWorkbenchBot();
+
+ /**
+ * Avoid instantiation.
+ */
+ private SWTBotUtils() {
+
+ }
+
+ /**
+ * Type text as direct edition.
+ *
+ * @param widget
+ * the current widget
+ * @param text
+ * the text to type
+ */
+ public static void directEditWithKeyboard(final Widget widget, final String text) {
+ final char[] charArray = text.toCharArray();
+ if (charArray.length > 0) {
+ for (char element : charArray) {
+ SWTBotUtils.pressKeyboardKey(widget, element);
+ }
+ }
+ }
+
+ /**
+ * Press a key.
+ *
+ * @param widget
+ * the current widget
+ * @param key
+ * the key to press
+ */
+ public static void pressKeyboardKey(final Widget widget, final char key) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ widget.notifyListeners(SWT.KeyDown, SWTBotUtils.keyEvent(SWT.NONE, key, key, widget));
+ widget.notifyListeners(SWT.KeyUp, SWTBotUtils.keyEvent(SWT.NONE, key, key, widget));
+ }
+ });
+ }
+
+ /**
+ * Press the enter key.
+ *
+ * @param widget
+ * the current widget
+ */
+ public static void pressEnterKey(final Widget widget) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ widget.notifyListeners(SWT.Traverse, SWTBotUtils.keyEvent(SWT.NONE, SWT.CR, SWT.Selection, widget));
+ }
+ });
+ }
+
+ /**
+ * @param c
+ * the character.
+ * @param modificationKey
+ * the modification key.
+ * @param keyCode
+ * the keycode.
+ * @return a key event with the specified keys.
+ * @see Event#keyCode
+ * @see Event#character
+ * @see Event#stateMask
+ * @since 1.2
+ */
+ private static Event keyEvent(final int modificationKey, final char c, final int keyCode, final Widget widget) {
+ final Event keyEvent = SWTBotUtils.createEvent(widget);
+ keyEvent.stateMask = modificationKey;
+ keyEvent.character = c;
+ keyEvent.keyCode = keyCode;
+
+ return keyEvent;
+ }
+
+ private static Event createEvent(final Widget widget) {
+ final Event event = new Event();
+ event.time = (int) System.currentTimeMillis();
+ event.widget = widget;
+ event.display = SWTBotUtils.bot.getDisplay();
+ return event;
+ }
+
+ /**
+ * WARNING this class should move in SWTBot one day. WARNING if the text is
+ * not found it will not failed this method to get disposed elements with
+ * the current click on context menu SWTBot method
+ *
+ * @param treeItem
+ * the current item
+ * @param text
+ * the menu text
+ */
+ public static void clickContextMenu(final SWTBotTreeItem treeItem, final String text) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+
+ @Override
+ public void run() {
+ final SWTBotContextMenu menu = new SWTBotContextMenu(treeItem);
+ menu.click(text);
+ }
+ });
+ }
+
+ /**
+ * WARNING this class should move in SWTBot one day. WARNING if the text is
+ * not found it will not failed this method to get disposed elements with
+ * the current click on context menu SWTBot method
+ *
+ * @param treeItem
+ * the current item
+ * @param text
+ * the menu text
+ * @return if treeItem has a context menu action named as the text parameter
+ */
+ public static boolean hasContextMenu(final SWTBotTreeItem treeItem, final String text) {
+
+ return UIThreadRunnable.syncExec(treeItem.display, new BoolResult() {
+
+ @Override
+ public Boolean run() {
+ SWTBotContextMenu swtBotContextMenu = new SWTBotContextMenu(treeItem);
+ return swtBotContextMenu.exist(text);
+ }
+ });
+ }
+
+ /**
+ * WARNING this class should move in SWTBot one day. WARNING if the text is
+ * not found it will not failed this method to get disposed elements with
+ * the current click on context menu SWTBot method
+ *
+ * @param treeItem
+ * the current item
+ * @param text
+ * the menu text
+ * @return if the context menu named as text is enabled
+ */
+ public static boolean isContextMenuEnabled(final SWTBotTreeItem treeItem, final String text) {
+ Matcher<MenuItem> withMnemonic = WidgetMatcherFactory.withMnemonic(text);
+ final Matcher<MenuItem> matcher = Matchers.allOf(WidgetMatcherFactory.widgetOfType(MenuItem.class), withMnemonic);
+
+ return UIThreadRunnable.syncExec(new BoolResult() {
+
+ @Override
+ public Boolean run() {
+ return new SiriusContextMenuFinder(treeItem.widget.getParent()).findMenuEnablement(matcher);
+ }
+ });
+ }
+
+ /**
+ * WARNING this class should move in SWTBot one day. WARNING if the text is
+ * not found it will not failed this method to get disposed elements with
+ * the current click on context menu SWTBot method
+ *
+ * @param tree
+ * the tree
+ * @param text
+ * the menu text
+ */
+ public static void clickContextMenu(final SWTBotTree tree, final String text) {
+ UIThreadRunnable.asyncExec(new VoidResult() {
+ @Override
+ public void run() {
+ final SWTBotContextMenu menu = new SWTBotContextMenu(tree);
+ menu.click(text);
+ }
+ });
+ }
+
+ /**
+ * Workaround method to ensure that previous call was processed fully.
+ */
+ public static void waitAllUiEvents() {
+ // use another sync exec to ensure that previous call was processed
+ // fully
+ UIThreadRunnable.syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ // do nothing, just wait for all events to be processed
+ }
+ });
+ }
+
+ /**
+ * This method is designed to wait close of progress monitor dialog if it
+ * opens. The dialog may not be opening if underlying process is shorter
+ * than 800ms. This method is able to manage this case.
+ *
+ * @param dialogTaskLabel
+ * A convenient name for the dialog to display errors
+ * @throws TimeoutException
+ * If dialog didn't close before timeout
+ * @see #waitProgressMonitorClose(String, String, long, TimeUnit)
+ */
+ public static void waitProgressMonitorClose(final String dialogTaskLabel) throws TimeoutException {
+ SWTBotUtils.waitProgressMonitorClose("Progress Information", dialogTaskLabel, SWTBotUtils.CLOSE_PROGRESS_MONITOR_TIMEOUT, TimeUnit.SECONDS);
+ }
+
+ /**
+ * This method is designed to wait close of progress monitor dialog if it
+ * opens. The dialog may not be opening if underlying process is shorter
+ * than 800ms. This method is able to mange this case.
+ *
+ * @param dialogTitle
+ * The real name of progress monitor dialog to look for
+ * @param dialogTaskLabel
+ * A convenient name for the dialog to display errors
+ * @param timeout
+ * Time to wait for dialog close
+ * @param unit
+ * Unit of timeout.
+ * @throws TimeoutException
+ * If dialog didn't close before timeout
+ */
+ public static void waitProgressMonitorClose(final String dialogTitle, final String dialogTaskLabel, final long timeout, final TimeUnit unit) throws TimeoutException {
+ // Need to wait progress monitor opening, that is to say at least
+ // ProgressManager#getLongOperationTime()
+ // As of 2010-03-31, it's 800ms
+ SWTBotUtils.bot.sleep(800);
+
+ // Try to find progress dialog monitor. It may be already closed
+ // SWTBot API can't be used because shell can be closed during
+ // SWTBotShell object initialization, and so it fails because shell
+ // might be disposed.
+ final Shell[] shells = SWTBotUtils.bot.getFinder().getShells();
+
+ final Shell progressShell = UIThreadRunnable.syncExec(SWTBotUtils.bot.getDisplay(), new WidgetResult<Shell>() {
+ @Override
+ public Shell run() {
+ for (Shell shell : shells) {
+ if (!shell.isDisposed() && shell.getText().equalsIgnoreCase(dialogTitle)) {
+ // Shell has been found
+ return shell;
+ }
+ }
+ return null;
+ }
+ });
+
+ if (progressShell != null) {
+ // Wait for close operation
+ long begin = System.currentTimeMillis();
+
+ boolean noTimeOut = true;
+
+ while (noTimeOut && SWTBotUtils.isShellNotClosed(progressShell)) {
+
+ long now = System.currentTimeMillis();
+
+ if (now - begin > unit.toMillis(timeout)) {
+ noTimeOut = false;
+
+ } else {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ if (!noTimeOut) {
+ // Check again, sometimes it is necessary to wait a little bit
+ // more
+ SWTBotUtils.waitAllUiEvents();
+
+ // Still not closed
+ if (SWTBotUtils.isShellNotClosed(progressShell)) {
+ throw new TimeoutException("'" + dialogTaskLabel + "' progress monitor dialog did not close in " + unit.toSeconds(SWTBotUtils.CLOSE_PROGRESS_MONITOR_TIMEOUT) + "s");
+ }
+ }
+ }
+ }
+
+ private static boolean isShellNotClosed(final Shell progressShell) {
+ return UIThreadRunnable.syncExec(SWTBotUtils.bot.getDisplay(), new BoolResult() {
+ @Override
+ public Boolean run() {
+ return !progressShell.isDisposed();
+ }
+ });
+ }
+
+ /**
+ * Finds the {@link FontFormat} of a {@link TreeItem}.
+ *
+ * @param widget
+ * the {@link TreeItem} under investigation
+ * @return the {@link FontFormat} of the {@link TreeItem}
+ */
+ public static FontFormat getWidgetFormat(final TreeItem widget) {
+ return UIThreadRunnable.syncExec(new Result<FontFormat>() {
+ @Override
+ public FontFormat run() {
+ FontFormat result = FontFormat.NORMAL_LITERAL;
+ Font font = widget.getFont(0);
+ if (font.getFontData().length > 0) {
+ switch (font.getFontData()[0].getStyle()) {
+ case SWT.BOLD:
+ result = FontFormat.BOLD_LITERAL;
+ break;
+ case SWT.ITALIC:
+ result = FontFormat.ITALIC_LITERAL;
+ break;
+ case SWT.BOLD | SWT.ITALIC:
+ result = FontFormat.BOLD_ITALIC_LITERAL;
+ break;
+ default:
+ result = FontFormat.NORMAL_LITERAL;
+ break;
+ }
+ }
+ return result;
+ }
+ });
+ }
+
+ /**
+ * Clicks on the column at the given index inside the given
+ * {@link SWTBotTree}.
+ *
+ * @param tree
+ * the {@link SWTBotTree} to click on
+ * @param columnIndex
+ * the column index
+ */
+ public static void clickOnTreeColumn(final SWTBotTree tree, final int columnIndex) {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ TreeColumn column = tree.widget.getColumn(columnIndex);
+ new SWTBotTreeColumn(column).clickOnColumn();
+ }
+ });
+ }
+
+ /**
+ * A Mock-up allowing to click on TreeColumns.
+ *
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ *
+ */
+ public static final class SWTBotTreeColumn extends AbstractSWTBot<TreeColumn> {
+ /**
+ * Constructs a new instance with the given widget.
+ *
+ * @param w
+ * the widget.
+ * @throws WidgetNotFoundException
+ * if the widget is <code>null</code> or widget has been
+ * disposed.
+ */
+ public SWTBotTreeColumn(TreeColumn w) throws WidgetNotFoundException {
+ super(w);
+ }
+
+ /**
+ * Simulate a click on the column.
+ */
+ public void clickOnColumn() {
+ notify(SWT.Selection);
+ notify(SWT.MouseUp, createMouseEvent(0, 0, 1, SWT.BUTTON1, 1), this.widget.getParent());
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SiriusContextMenuFinder.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SiriusContextMenuFinder.java
new file mode 100644
index 0000000000..9adb363395
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/SiriusContextMenuFinder.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2012, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swtbot.swt.finder.finders.ContextMenuFinder;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.BoolResult;
+import org.hamcrest.Matcher;
+import org.junit.Assert;
+
+/**
+ * This Class overrides ContextMenuFinder to be able to check a context menu
+ * enablement as soon as it is found in order to avoid a "Widget is disposed"
+ * exception.
+ *
+ * @author <a href="mailto:steve.monnier@obeo.fr">Steve Monnier</a>
+ */
+public class SiriusContextMenuFinder extends ContextMenuFinder {
+
+ /**
+ * Constructs the context menu finder for the given control to be searched.
+ *
+ * @param control
+ * the control that has a context menu.
+ */
+ public SiriusContextMenuFinder(Control control) {
+ super(control);
+ }
+
+ /**
+ * Finds a menu matching the given item in all available shells and return
+ * its enablement status. If recursive is set, it will attempt to find the
+ * controls recursively in each of the menus it that is found.
+ *
+ * @param matcher
+ * the matcher that can match menus and menu items.
+ * @return the enablement status if one menu in all shells matches the
+ * matcher.
+ */
+ public boolean findMenuEnablement(Matcher<MenuItem> matcher) {
+ return findMenuEnablement(getShells(), matcher, true);
+ }
+
+ /**
+ * Finds all the menus using the given matcher in the set of shells provided
+ * and return its enablement status. If recursive is set, it will attempt to
+ * find the controls recursively in each of the menus it that is found.
+ *
+ * @param shells
+ * the shells to probe for menus.
+ * @param matcher
+ * the matcher that can match menus and menu items.
+ * @param recursive
+ * if set to true, will find sub-menus as well.
+ * @return the enablement status if one menu in the specified shells matches
+ * the matcher.
+ */
+ public boolean findMenuEnablement(Shell[] shells, Matcher<MenuItem> matcher, boolean recursive) {
+ boolean result = false;
+ for (Shell shell : shells) {
+ result = result || findMenuEnablement(menuBar(shell), matcher, recursive);
+ }
+ return result;
+ }
+
+ /**
+ * Finds all the menus in the given menu bar matching the given matcher. If
+ * recursive is set, it will attempt to find the controls recursively in
+ * each of the menus it that is found.
+ *
+ * @param bar
+ * the menu bar
+ * @param matcher
+ * the matcher that can match menus and menu items.
+ * @param recursive
+ * if set to true, will find sub-menus as well.
+ * @return all menus in the specified menubar that match the matcher.
+ */
+ public boolean findMenuEnablement(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) {
+ return UIThreadRunnable.syncExec(display, new BoolResult() {
+
+ @Override
+ public Boolean run() {
+ List<MenuItem> menus = findMenusInternal(bar, matcher, recursive);
+ Assert.assertEquals("Only one widget was expected to be found", 1, menus.size());
+ return menus.get(0).getEnabled();
+ }
+ });
+ }
+
+ /**
+ * This method if just a copy from org.eclipse.swtbot.swt.finder.finders.MenuFinder.
+ */
+ private List<MenuItem> findMenusInternal(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) {
+ LinkedHashSet<MenuItem> result = new LinkedHashSet<MenuItem>();
+ if (bar != null) {
+ bar.notifyListeners(SWT.Show, new Event());
+ MenuItem[] items = bar.getItems();
+ for (MenuItem menuItem : items) {
+ if (isSeparator(menuItem)) {
+ continue;
+ }
+ if (matcher.matches(menuItem)) {
+ result.add(menuItem);
+ }
+ if (recursive) {
+ result.addAll(findMenusInternal(menuItem.getMenu(), matcher, recursive));
+ }
+ }
+ bar.notifyListeners(SWT.Hide, new Event());
+ }
+ return new ArrayList<MenuItem>(result);
+ }
+
+ /**
+ * This method if just a copy from org.eclipse.swtbot.swt.finder.finders.MenuFinder
+ */
+ private boolean isSeparator(MenuItem menuItem) {
+ // FIXME see https://bugs.eclipse.org/bugs/show_bug.cgi?id=208188
+ // FIXED > 20071101
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=208188#c2
+ return (menuItem.getStyle() & SWT.SEPARATOR) != 0;
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/business/UIRepresentationUtils.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/business/UIRepresentationUtils.java
new file mode 100644
index 0000000000..2c59c93c8a
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/business/UIRepresentationUtils.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2009, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils.business;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.sirius.tests.swtbot.support.api.business.AbstractUIRepresentation;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * Utils for representations.
+ *
+ * @author dlecan
+ *
+ */
+public final class UIRepresentationUtils {
+
+ private UIRepresentationUtils() {
+ // Nothing.
+ }
+
+ /**
+ * Select an instance of representation, <i>ie</i> a diagram or a table.
+ *
+ * @param <R>
+ * Type of representation.
+ * @param treeItem
+ * Tree item. May be <code>null</code>.
+ * @param representationInstanceLabelName
+ * Representation instance label name.
+ * @param representationType
+ * Representation type.
+ * @return A representation.
+ */
+ public static <R extends AbstractUIRepresentation<?>> R buildRepresentation(final SWTBotTreeItem treeItem, final String representationInstanceLabelName, final Class<R> representationType) {
+ try {
+ final Constructor<R> constructor = representationType.getConstructor(new Class<?>[] { SWTBotTreeItem.class, String.class });
+
+ return constructor.newInstance(treeItem, representationInstanceLabelName);
+ } catch (final InstantiationException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (final IllegalAccessException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (final SecurityException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (final NoSuchMethodException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (final IllegalArgumentException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ } catch (final InvocationTargetException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/dnd/DndUtil.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/dnd/DndUtil.java
new file mode 100644
index 0000000000..73d2b98353
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/dnd/DndUtil.java
@@ -0,0 +1,346 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils.dnd;
+
+import java.awt.AWTException;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.jface.util.Geometry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefFigureCanvas;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+
+/**
+ * A dnd utility class to help performing drag and drop. This code will be in
+ * SWTbot in future but need to be polished before.
+ *
+ * @author mchauvin
+ */
+public class DndUtil {
+
+ /**
+ * Number of pixels traversed before a drag starts. Ms : 10 OSX : 10(1.3.1),
+ * 5(1.4.1) Linux/X11: delay+16
+ */
+ private static final int DRAG_THRESHOLD = "gtk".equals(SWT.getPlatform()) ? 16 : 10;
+
+ /**
+ * delay before moving after mouse is pressed. could be used for delay after
+ * moving before mouse is released
+ */
+ private static final int DRAG_DELAY = 400;
+
+ private final Display display;
+
+ /**
+ * Construct a new instance.
+ *
+ * @param display
+ * the display to use
+ */
+ public DndUtil(Display display) {
+ this.display = display;
+ }
+
+ /**
+ * Performs a drag and drop operation from this widget to the given target.
+ * The drag start location will be chosen depending on this widget's default
+ * implementation.
+ *
+ * @param source
+ * the source widget to drag
+ * @param target
+ * To perform the drop on
+ * @see #dragAndDrop(Point)
+ */
+ // TODO add modifier key mask
+ public void dragAndDrop(final AbstractSWTBot<? extends Widget> source, final AbstractSWTBot<? extends Widget> target) {
+ dragAndDrop(source, DndUtil.on(target));
+ }
+
+ /**
+ * Performs a drag and drop operation from this widget to the given target
+ * at the given location from target origin. The drag start location will be
+ * chosen depending on this widget's default implementation.
+ *
+ * @param source
+ * the source widget to drag
+ * @param target
+ * To perform the drop on
+ * @param locationOnTarget
+ * The target locations, from target origin, where the DND shall
+ * finish.
+ * @see #dragAndDrop(Point)
+ */
+ public void dragAndDrop(final AbstractSWTBot<? extends Widget> source, final AbstractSWTBot<? extends Widget> target, final Point locationOnTarget) {
+ Rectangle targetRectangle = DndUtil.absoluteLocation(target);
+ Point dropTarget = new Point(targetRectangle.x + locationOnTarget.x, targetRectangle.y + locationOnTarget.y);
+ dragAndDrop(source, dropTarget);
+ }
+
+ /**
+ * Performs a drag and drop operation from this widget to the given target
+ * at the given location from target origin. The drag start location will be
+ * chosen depending on this widget's default implementation.
+ *
+ * @param source
+ * the source widget to drag
+ * @param target
+ * To perform the drop on
+ * @param locationOnTarget
+ * The target locations, from target origin, where the DND shall
+ * finish.
+ * @see #dragAndDrop(Point)
+ */
+ public void dragAndDrop(final AbstractSWTBot<? extends Widget> source, final AbstractSWTBot<? extends Widget> target, final org.eclipse.draw2d.geometry.Point locationOnTarget) {
+ dragAndDrop(source, target, new Point(locationOnTarget.x, locationOnTarget.y));
+ }
+
+ /**
+ * Performs a DND operation to an arbitrary location. The drag start
+ * location will be chosen depending on this widget's default
+ * implementation.
+ *
+ * @param source
+ * the source widget to drag
+ * @param target
+ * The target locations where the DND shall finish.
+ * @see #before(AbstractSWTBot)
+ * @see #on(AbstractSWTBot)
+ * @see #after(AbstractSWTBot)
+ */
+ public void dragAndDrop(final AbstractSWTBot<? extends Widget> source, final Point target) {
+ final Rectangle sourceLocation = DndUtil.absoluteLocation(source);
+ final Point slightOffset = Geometry.add(Geometry.getLocation(sourceLocation), new Point(DndUtil.DRAG_THRESHOLD, DndUtil.DRAG_THRESHOLD));
+ doDragAndDrop(Geometry.min(Geometry.centerPoint(sourceLocation), slightOffset), target);
+ }
+
+ /**
+ * Performs a DND operation starting at an arbitrary location, targeting the
+ * given widget.
+ *
+ * @param source
+ * From where to start dragging
+ * @param target
+ * Where to drop onto
+ * @see #dragAndDrop(AbstractSWTBot)
+ * @see #dragAndDrop(Point)
+ */
+ protected void dragAndDrop(final Point source, final AbstractSWTBot<? extends Widget> target) {
+ doDragAndDrop(source, DndUtil.on(target));
+ }
+
+ /**
+ *
+ */
+ private void doDragAndDrop(final Point source, final Point dest) {
+ // log.debug(MessageFormat.format("Drag-and-dropping from ({0},{1}) to ({2},{3})",
+ // source.x, source.y, dest.x, dest.y));
+ try {
+ final Robot awtRobot = new Robot();
+ // the x+10 motion is needed to let native functions register a drag
+ // detect. It did not work under Windows
+ // otherwise and has been reported to be required for linux, too.
+ // But I could not test that.
+ syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ awtRobot.mouseMove(source.x, source.y);
+ awtRobot.mousePress(InputEvent.BUTTON1_MASK);
+ awtRobot.mouseMove(source.x + DndUtil.DRAG_THRESHOLD, source.y);
+ }
+ });
+
+ /* drag delay */
+ SWTUtils.sleep(DndUtil.DRAG_DELAY);
+
+ syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ awtRobot.mouseMove(dest.x + DndUtil.DRAG_THRESHOLD, dest.y);
+ awtRobot.mouseMove(dest.x, dest.y);
+ }
+ });
+
+ /* drop delay */
+ SWTUtils.sleep(DndUtil.DRAG_DELAY);
+
+ syncExec(new VoidResult() {
+ @Override
+ public void run() {
+ awtRobot.mouseRelease(InputEvent.BUTTON1_MASK);
+ }
+ });
+ } catch (final AWTException e) {
+ // log.error(e.getMessage(), e);
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /**
+ * Invokes {@link VoidResult#run()} on the UI thread.
+ *
+ * @param toExecute
+ * the object to be invoked in the UI thread.
+ */
+ private void syncExec(VoidResult toExecute) {
+ UIThreadRunnable.syncExec(display, toExecute);
+ }
+
+ /**
+ * Calculates a position which can be used to insert an item <em>before</em>
+ * the given one by a DND operation.
+ *
+ * @param targetItem
+ * Before which the new item shall appear
+ * @param <T>
+ * .
+ * @return A point suitable to drop an item before {@code targetItem}
+ * @see #dragAndDrop(Point)
+ * @see DND#FEEDBACK_INSERT_BEFORE
+ */
+ public static <T extends Widget> Point before(final AbstractSWTBot<T> targetItem) {
+ return DndUtil.pointOnUpperBorder(DndUtil.absoluteLocation(targetItem));
+ }
+
+ /**
+ * Calculates a position which can be used to drop something <em>onto</em>
+ * the given widget by a DND operation. For tree structures, this will most
+ * likely result in another child node being added. But how this is handled
+ * in detail ultimately depends on the "drop action"'s implementation.
+ *
+ * @param targetItem
+ * On which to drop
+ * @param <T>
+ * .
+ * @return The {@code targetItem}'s center
+ * @see #dragAndDrop(Point)
+ * @see DND#FEEDBACK_SELECT
+ */
+ public static <T extends Widget> Point on(final AbstractSWTBot<T> targetItem) {
+ return Geometry.centerPoint(DndUtil.absoluteLocation(targetItem));
+ }
+
+ /**
+ * Calculates a position which can be used to insert an item after the given
+ * one by a DND operation.
+ *
+ * @param targetItem
+ * After which the new item shall appear
+ * @param <T>
+ * .
+ * @return A point suitable to drop an item after {@code targetItem}
+ * @see #dragAndDrop(Point)
+ * @see DND#FEEDBACK_INSERT_AFTER
+ */
+ public static <T extends Widget> Point after(final AbstractSWTBot<T> targetItem) {
+ return DndUtil.pointOnLowerBorder(DndUtil.absoluteLocation(targetItem));
+ }
+
+ private static Point pointOnLowerBorder(Rectangle rect) {
+ return new Point(Geometry.centerPoint(rect).x, rect.y + rect.height - 1);
+ }
+
+ private static Point pointOnUpperBorder(Rectangle rect) {
+ return new Point(Geometry.centerPoint(rect).x, rect.y + 1);
+ }
+
+ private static <T extends Widget> Rectangle absoluteLocation(final AbstractSWTBot<T> item) {
+ AbstractSWTBot<?> bot = null;
+ if (item instanceof SWTBotTreeItem) {
+ bot = new SWTBotTreeItemForDnd(((SWTBotTreeItem) item).widget);
+ } else if (item instanceof SWTBotGefFigureCanvas) {
+ bot = new SWTBotGefFigureCanvasForDnd((FigureCanvas) ((SWTBotGefFigureCanvas) item).widget);
+ } else {
+ bot = item;
+ }
+ Object result = null;
+ try {
+ Method m = AbstractSWTBot.class.getDeclaredMethod("absoluteLocation");
+ m.setAccessible(true);
+ result = m.invoke(bot);
+ } catch (SecurityException e) {
+ // do nothing
+ } catch (NoSuchMethodException e) {
+ // do nothing
+ } catch (IllegalArgumentException e) {
+ // do nothing
+ } catch (IllegalAccessException e) {
+ // do nothing
+ } catch (InvocationTargetException e) {
+ // do nothing
+ }
+ return (Rectangle) result;
+ }
+
+ /**
+ * Subclass to return the correct absolute location.
+ *
+ * @author mchauvin
+ */
+ private static class SWTBotTreeItemForDnd extends SWTBotTreeItem {
+
+ public SWTBotTreeItemForDnd(TreeItem treeItem) throws WidgetNotFoundException {
+ super(treeItem);
+ }
+
+ @Override
+ protected Rectangle absoluteLocation() {
+ return UIThreadRunnable.syncExec(new Result<Rectangle>() {
+ @Override
+ public Rectangle run() {
+ return display.map(widget.getParent(), null, widget.getBounds());
+ }
+ });
+ }
+
+ }
+
+ /**
+ * Subclass to return the correct absolute location.
+ *
+ * @author mchauvin
+ */
+ private static class SWTBotGefFigureCanvasForDnd extends SWTBotGefFigureCanvas {
+
+ public SWTBotGefFigureCanvasForDnd(FigureCanvas canvas) throws WidgetNotFoundException {
+ super(canvas);
+ }
+
+ @Override
+ protected Rectangle absoluteLocation() {
+ return UIThreadRunnable.syncExec(new Result<Rectangle>() {
+ @Override
+ public Rectangle run() {
+ return display.map(widget.getParent(), null, widget.getBounds());
+ }
+ });
+ }
+
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/FirstContextMenuFinder.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/FirstContextMenuFinder.java
new file mode 100644
index 0000000000..cf6571c347
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/FirstContextMenuFinder.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils.menu;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swtbot.swt.finder.finders.ContextMenuFinder;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.ListResult;
+import org.hamcrest.Matcher;
+
+/**
+ * A context menu finder, which stops to search when he found one result.
+ *
+ * @author mchauvin
+ */
+public class FirstContextMenuFinder extends ContextMenuFinder {
+
+ /**
+ * Constructs the context menu finder for the given control to be searched.
+ *
+ * @param control
+ * the control that has a context menu.
+ */
+ public FirstContextMenuFinder(Control control) {
+ super(control);
+ }
+
+ /**
+ * Finds all the menus using the given matcher in the set of shells
+ * provided. If recursive is set, it will attempt to find the controls
+ * recursively in each of the menus it that is found.
+ *
+ * @param shells
+ * the shells to probe for menus.
+ * @param matcher
+ * the matcher that can match menus and menu items.
+ * @param recursive
+ * if set to true, will find sub-menus as well.
+ * @return all menus in the specified shells that match the matcher.
+ */
+ @Override
+ public List<MenuItem> findMenus(Shell[] shells, Matcher<MenuItem> matcher, boolean recursive) {
+ LinkedHashSet<MenuItem> result = new LinkedHashSet<MenuItem>();
+ for (Shell shell : shells) {
+ result.addAll(findMenus(shell, matcher, recursive));
+ if (!result.isEmpty()) {
+ break;
+ }
+ }
+ return new ArrayList<MenuItem>(result);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swtbot.swt.finder.finders.MenuFinder#findMenus(org.eclipse.swt.widgets.Menu,
+ * org.hamcrest.Matcher, boolean)
+ */
+ @Override
+ public List<MenuItem> findMenus(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) {
+ return UIThreadRunnable.syncExec(display, new ListResult<MenuItem>() {
+ @Override
+ public List<MenuItem> run() {
+ return findMenuInternal(bar, matcher, recursive);
+ }
+ });
+ }
+
+ private List<MenuItem> findMenuInternal(final Menu bar, final Matcher<MenuItem> matcher, final boolean recursive) {
+ LinkedHashSet<MenuItem> result = new LinkedHashSet<MenuItem>();
+ if (bar != null) {
+ bar.notifyListeners(SWT.Show, new Event());
+ MenuItem[] items = bar.getItems();
+ for (MenuItem menuItem : items) {
+ if (isSeparator(menuItem)) {
+ continue;
+ }
+ if (matcher.matches(menuItem)) {
+ result.add(menuItem);
+ /* we found one, do not continue */
+ break;
+ }
+ if (recursive) {
+ result.addAll(findMenuInternal(menuItem.getMenu(), matcher, recursive));
+ if (!result.isEmpty()) {
+ break;
+ }
+ }
+
+ }
+ bar.notifyListeners(SWT.Hide, new Event());
+ }
+ return new ArrayList<MenuItem>(result);
+ }
+
+ private boolean isSeparator(MenuItem menuItem) {
+ return (menuItem.getStyle() & SWT.SEPARATOR) != 0;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/SWTBotContextMenu.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/SWTBotContextMenu.java
new file mode 100644
index 0000000000..8aeb00d08b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/menu/SWTBotContextMenu.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils.menu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.finders.ContextMenuFinder;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory;
+import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
+import org.eclipse.swtbot.swt.finder.widgets.TimeoutException;
+import org.hamcrest.Matcher;
+
+/**
+ * A context menu wrapper to handle click correctly.
+ *
+ * @author mchauvin
+ */
+public class SWTBotContextMenu {
+
+ private final Control control;
+
+ /**
+ * .
+ *
+ * @param treeItem
+ * .
+ */
+ public SWTBotContextMenu(final SWTBotTreeItem treeItem) {
+ this.control = treeItem.widget.getParent();
+
+ }
+
+ /**
+ * .
+ *
+ * @param tree
+ * .
+ */
+ public SWTBotContextMenu(final SWTBotTree tree) {
+ this.control = tree.widget;
+ }
+
+ /**
+ * Click on the first menu item matching the text.
+ *
+ * @param text
+ * the text on the context menu.
+ * @return the context menu
+ */
+ @SuppressWarnings("unchecked")
+ // varargs and generics doesn't mix well!
+ public SWTBotContextMenu click(final String text) {
+ Matcher<MenuItem> withMnemonic = WidgetMatcherFactory.withMnemonic(text);
+ final Matcher<MenuItem> matcher = WidgetMatcherFactory.allOf(WidgetMatcherFactory.widgetOfType(MenuItem.class), withMnemonic);
+ final ContextMenuFinder menuFinder = new FirstContextMenuFinder(control);
+
+ final List<MenuItem> items = new ArrayList<MenuItem>();
+
+ new SWTBot().waitUntil(new DefaultCondition() {
+ @Override
+ public String getFailureMessage() {
+ return "Could not find context menu with text: " + text; //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ items.addAll(menuFinder.findMenus(matcher));
+ return !items.isEmpty();
+ }
+ });
+
+ MenuItem menuItem = items.get(0);
+ if (!menuItem.isDisposed()) {
+ new SWTBotMenu(menuItem, matcher).click();
+ } else {
+ // do nothing or print something in debug
+ }
+ return this;
+ }
+
+ /**
+ * Click on the first menu item matching the text.
+ *
+ * @param text
+ * the text on the context menu.
+ * @return the context menu
+ */
+ @SuppressWarnings("unchecked")
+ // varargs and generics doesn't mix well!
+ public boolean exist(final String text) {
+ Matcher<MenuItem> withMnemonic = WidgetMatcherFactory.withMnemonic(text);
+ final Matcher<MenuItem> matcher = WidgetMatcherFactory.allOf(WidgetMatcherFactory.widgetOfType(MenuItem.class), withMnemonic);
+ final ContextMenuFinder menuFinder = new FirstContextMenuFinder(control);
+
+ final List<MenuItem> items = new ArrayList<MenuItem>();
+
+ try {
+ new SWTBot().waitUntil(new DefaultCondition() {
+ @Override
+ public String getFailureMessage() {
+ return "Could not find context menu with text: " + text; //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean test() throws Exception {
+ items.addAll(menuFinder.findMenus(matcher));
+ return !items.isEmpty();
+ }
+ });
+ return true;
+ } catch (TimeoutException e) {
+ return false;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/tree/TreeUtils.java b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/tree/TreeUtils.java
new file mode 100644
index 0000000000..226602349e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.swtbot.support/src/org/eclipse/sirius/tests/swtbot/support/utils/tree/TreeUtils.java
@@ -0,0 +1,789 @@
+/**
+ * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms 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.sirius.tests.swtbot.support.utils.tree;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.sirius.ext.base.Option;
+import org.eclipse.sirius.table.business.api.query.DCellQuery;
+import org.eclipse.sirius.table.metamodel.table.DCell;
+import org.eclipse.sirius.table.metamodel.table.DColumn;
+import org.eclipse.sirius.table.metamodel.table.DLine;
+import org.eclipse.sirius.table.metamodel.table.DTable;
+import org.eclipse.sirius.table.metamodel.table.DTableElementStyle;
+import org.eclipse.sirius.table.metamodel.table.TablePackage;
+import org.eclipse.sirius.table.ui.tools.api.editor.DTableEditor;
+import org.eclipse.sirius.table.ui.tools.internal.editor.utils.TreeColumnWidthQuery;
+import org.eclipse.sirius.table.ui.tools.internal.editor.utils.TreeColumnWidthSetter;
+import org.eclipse.sirius.tests.support.api.TreeItemImageQuery;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemBackgroundColorQuery;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemExpandedQuery;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemExpander;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemLabelColorQuery;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemLabelFontFormatQuery;
+import org.eclipse.sirius.tests.swtbot.support.api.widget.TreeItemLabelSizeQuery;
+import org.eclipse.sirius.tree.DTreeItem;
+import org.eclipse.sirius.tree.TreePackage;
+import org.eclipse.sirius.tree.ui.tools.api.editor.DTreeEditor;
+import org.eclipse.sirius.ui.tools.internal.util.ItemSearcher;
+import org.eclipse.sirius.viewpoint.FontFormat;
+import org.eclipse.sirius.viewpoint.RGBValues;
+import org.eclipse.sirius.viewpoint.ViewpointPackage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEditor;
+import org.junit.Assert;
+
+/**
+ * A Utility for {@link TreeItem} according to {@link DTreeItem}.
+ *
+ * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
+ */
+public final class TreeUtils {
+
+ private static final String COLLAPSE = "collapse";
+
+ private static final String EXPANDED = "expanded";
+
+ private TreeUtils() {
+ // To not instanciate
+ }
+
+ /**
+ * Change the {@link TablePackage#DLINE__COLLAPSED} feature of a
+ * {@link DLine}.
+ *
+ * @param dLine
+ * the {@link DLine}
+ * @param collapse
+ * the boolean to set for the feature
+ */
+ public static void changeDLineCollapse(DLine dLine, boolean collapse) {
+ TransactionalEditingDomain transactionalEditingDomain = TransactionUtil.getEditingDomain(dLine);
+ CommandStack commandStack = transactionalEditingDomain.getCommandStack();
+ Command expandCarDTreeItemCmd = SetCommand.create(transactionalEditingDomain, dLine, TablePackage.Literals.DLINE__COLLAPSED, collapse);
+ commandStack.execute(expandCarDTreeItemCmd);
+ }
+
+ /**
+ * Change the {@link TreePackage#DTREE_ITEM__EXPANDED} feature of a
+ * {@link DLine}.
+ *
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ * @param expand
+ * the boolean to set for the feature
+ */
+ public static void changeDTreeItemExpansion(DTreeItem dTreeItem, boolean expand) {
+ TransactionalEditingDomain transactionalEditingDomain = TransactionUtil.getEditingDomain(dTreeItem);
+ CommandStack commandStack = transactionalEditingDomain.getCommandStack();
+ Command expandCarDTreeItemCmd = SetCommand.create(transactionalEditingDomain, dTreeItem, TreePackage.Literals.DTREE_ITEM__EXPANDED, expand);
+ commandStack.execute(expandCarDTreeItemCmd);
+ }
+
+ /**
+ * Collapse a swt {@link TreeItem} corresponding to the specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} to collapse
+ * referencing the specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void collapseTreeItem(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ TreeUtils.changeExpansionTreeItem(swtBotTreeEditor, dTreeItem, false);
+ }
+
+ /**
+ * Expand a swt {@link TreeItem} corresponding to the specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} to expand
+ * referencing the specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void expandTreeItem(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ TreeUtils.changeExpansionTreeItem(swtBotTreeEditor, dTreeItem, true);
+ }
+
+ /**
+ * Change expansion state of a swt {@link TreeItem} corresponding to the
+ * specified {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} to change expansion
+ * referencing the specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ * @param expansion
+ * true to expand, false to collapse
+ */
+ public static void changeExpansionTreeItem(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem, boolean expansion) {
+ DTreeEditor dTreeEditor = (DTreeEditor) swtBotTreeEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTreeEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dTreeItem);
+ Display.getDefault().syncExec(itemSearcher);
+ TreeItem treeItem = (TreeItem) itemSearcher.getResult();
+ TreeItemExpander treeItemExpander = new TreeItemExpander(treeItem, expansion);
+ Display.getDefault().syncExec(treeItemExpander);
+ }
+
+ /**
+ * Collapse a swt {@link TreeItem} corresponding to the specified
+ * {@link DLine}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} to collapse
+ * referencing the specified {@link DLine}
+ * @param dLine
+ * the {@link DLine}
+ */
+ public static void collapseTreeItem(SWTBotEditor swtBotTableEditor, DLine dLine) {
+ TreeUtils.changeExpansionTreeItem(swtBotTableEditor, dLine, false);
+ }
+
+ /**
+ * Expand a swt {@link TreeItem} corresponding to the specified
+ * {@link DLine}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} to expand
+ * referencing the specified {@link DLine}
+ * @param dLine
+ * the {@link DLine}
+ */
+ public static void expandTreeItem(SWTBotEditor swtBotTableEditor, DLine dLine) {
+ TreeUtils.changeExpansionTreeItem(swtBotTableEditor, dLine, true);
+ }
+
+ /**
+ * Change expansion state of a swt {@link TreeItem} corresponding to the
+ * specified {@link DLine}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} to change expansion
+ * referencing the specified {@link DLine}
+ * @param dLine
+ * the {@link DLine}
+ * @param expansion
+ * true to expand, false to collapse
+ */
+ public static void changeExpansionTreeItem(SWTBotEditor swtBotTableEditor, DLine dLine, boolean expansion) {
+ DTableEditor dTableEditor = (DTableEditor) swtBotTableEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTableEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dLine);
+ Display.getDefault().syncExec(itemSearcher);
+ TreeItem treeItem = (TreeItem) itemSearcher.getResult();
+ TreeItemExpander treeItemExpander = new TreeItemExpander(treeItem, expansion);
+ Display.getDefault().syncExec(treeItemExpander);
+ }
+
+ /**
+ * Checks that the swt {@link TreeItem} expansion corresponds to the
+ * specified {@link DLine} expansion.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DLine}
+ * @param dLine
+ * the {@link DLine}
+ */
+ public static void checkTreeItemExpansion(SWTBotEditor swtBotTableEditor, DLine dLine) {
+ boolean collapsed = dLine.isCollapsed();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTableEditor, dLine);
+ boolean widgetExpansion = TreeUtils.getWidgetExpansion(treeItem);
+ Assert.assertEquals("As the DLine is " + (collapsed ? TreeUtils.COLLAPSE : TreeUtils.EXPANDED) + ", its TreeItem should be also " + (collapsed ? TreeUtils.COLLAPSE : TreeUtils.EXPANDED),
+ !collapsed, widgetExpansion);
+ }
+
+ /**
+ * Checks that the swt {@link TreeItem} expansion corresponds to the
+ * specified {@link DTreeItem} expansion.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemCollapse(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ boolean expanded = dTreeItem.isExpanded();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ boolean widgetExpansion = TreeUtils.getWidgetExpansion(treeItem);
+ Assert.assertEquals("As the DTreeitem is " + (expanded ? TreeUtils.COLLAPSE : TreeUtils.EXPANDED) + ", its TreeItem should be also " + (expanded ? TreeUtils.COLLAPSE : TreeUtils.EXPANDED),
+ expanded, widgetExpansion);
+ }
+
+ /**
+ * Change the {@link TablePackage#DLINE__COLLAPSED} feature of a
+ * {@link DLine}.
+ *
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ * @param newBackgroundColor
+ * the new background color to use
+ */
+ public static void changeDTreeItemBackgroundColor(DTreeItem dTreeItem, RGBValues newBackgroundColor) {
+ TransactionalEditingDomain transactionalEditingDomain = TransactionUtil.getEditingDomain(dTreeItem);
+ CommandStack commandStack = transactionalEditingDomain.getCommandStack();
+ Command changeDTreeItemBackgroundColorCmd = SetCommand.create(transactionalEditingDomain, dTreeItem.getOwnedStyle(), ViewpointPackage.Literals.RGB_VALUES__BLUE, newBackgroundColor.getRed());
+ changeDTreeItemBackgroundColorCmd = changeDTreeItemBackgroundColorCmd.chain(SetCommand.create(transactionalEditingDomain, dTreeItem.getOwnedStyle(),
+ ViewpointPackage.Literals.RGB_VALUES__BLUE, newBackgroundColor.getGreen()));
+ changeDTreeItemBackgroundColorCmd = changeDTreeItemBackgroundColorCmd.chain(SetCommand.create(transactionalEditingDomain, dTreeItem.getOwnedStyle(),
+ ViewpointPackage.Literals.RGB_VALUES__BLUE, newBackgroundColor.getBlue()));
+ commandStack.execute(changeDTreeItemBackgroundColorCmd);
+ }
+
+ /**
+ * Checks that the swt {@link TreeItem} background color corresponds to the
+ * specified {@link DTreeItem} background color.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemBackgroundColor(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ RGBValues backgroundColor = dTreeItem.getOwnedStyle().getBackgroundColor();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ RGBValues widgetBackgroundColor = TreeUtils.getWidgetBackgroundColor(treeItem);
+ // CHECKSTYLE:OFF
+ String backgroundColorMessage = "\t DTreeItem.backgroundColor : (" + backgroundColor.getRed() + "," + backgroundColor.getGreen() + "," + backgroundColor.getBlue() + ")\n";
+ String widgetBackgroundColorMessage = "\t SWTTreeItem.backgroundColor : (" + widgetBackgroundColor.getRed() + "," + widgetBackgroundColor.getGreen() + "," + widgetBackgroundColor.getBlue()
+ + ")\n";
+ String failureMessage = "The background color from the DTreeItem and this from the swt widget differs : \n" + backgroundColorMessage + widgetBackgroundColorMessage;
+ // CHECKSTYLE:ON
+ Assert.assertEquals(failureMessage, backgroundColor.getRed(), widgetBackgroundColor.getRed());
+ Assert.assertEquals(failureMessage, backgroundColor.getGreen(), widgetBackgroundColor.getGreen());
+ Assert.assertEquals(failureMessage, backgroundColor.getBlue(), widgetBackgroundColor.getBlue());
+ }
+
+ /**
+ * Checks that the swt {@link TreeItem} background color corresponds to the
+ * specified {@link DCell} background color.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DCell}
+ * @param dCell
+ * the {@link DCell}
+ */
+ public static void checkTreeItemBackgroundColor(SWTBotEditor swtBotTableEditor, DCell dCell) {
+ Option<DTableElementStyle> optionalBackgroundStyleToApply = new DCellQuery(dCell).getBackgroundStyleToApply();
+ Assert.assertTrue("We should have a background style for the cell.", optionalBackgroundStyleToApply.some());
+ RGBValues backgroundColor = optionalBackgroundStyleToApply.get().getBackgroundColor();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTableEditor, dCell.getLine());
+ int dCellIndex = new DCellQuery(dCell).getColumnIndex();
+ RGBValues widgetBackgroundColor = TreeUtils.getWidgetBackgroundColor(treeItem, dCellIndex + 1);
+ // CHECKSTYLE:OFF
+ String backgroundColorMessage = "\t DCellStyle.backgroundColor : (" + backgroundColor.getRed() + "," + backgroundColor.getGreen() + "," + backgroundColor.getBlue() + ")\n";
+ // CHECKSTYLE:ON
+ String widgetBackgroundColorMessage = "\t SWTTreeItem.backgroundColor : (" + widgetBackgroundColor.getRed() + "," + widgetBackgroundColor.getGreen() + "," + widgetBackgroundColor.getBlue()
+ + ")\n";
+ String failureMessage = "The background color from the DCellStyle and this from the swt widget differs : \n" + backgroundColorMessage + widgetBackgroundColorMessage;
+
+ Assert.assertEquals(failureMessage, backgroundColor.getRed(), widgetBackgroundColor.getRed());
+ Assert.assertEquals(failureMessage, backgroundColor.getGreen(), widgetBackgroundColor.getGreen());
+ Assert.assertEquals(failureMessage, backgroundColor.getBlue(), widgetBackgroundColor.getBlue());
+ }
+
+ /**
+ * Checks the swt Column width for a specified {@link DColumn}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt column referencing the specified
+ * {@link DColumn}
+ * @param dColumn
+ * the {@link DColumn}
+ */
+ public static void checkColumnWidth(SWTBotEditor swtBotTableEditor, DColumn dColumn) {
+ int dColumnWidh = dColumn.getWidth();
+ int treeColumnWidth = TreeUtils.getColumnWidth(swtBotTableEditor, dColumn);
+ Assert.assertEquals("The TreeColumn width should corresponds to its DColumn.width", dColumnWidh, treeColumnWidth);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getFont()}'s label size for a specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemLabelSize(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ int labelSize = dTreeItem.getOwnedStyle().getLabelSize();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ int treeItemLabelSize = TreeUtils.getWidgetLabelSize(treeItem);
+ Assert.assertEquals("The TreeItem label size should corresponds to its DTreeItem.ownedStyle.labelSize", labelSize, treeItemLabelSize);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getFont()}'s label size for a specified
+ * {@link DCell}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DCell}
+ * @param dCell
+ * the {@link DCell}
+ */
+ public static void checkTreeItemLabelSize(SWTBotEditor swtBotTableEditor, DCell dCell) {
+ Option<DTableElementStyle> optionalForegroundStyleToApply = new DCellQuery(dCell).getForegroundStyleToApply();
+ Assert.assertTrue("We should have a foreground Style for the cell.", optionalForegroundStyleToApply.some());
+ int labelSize = optionalForegroundStyleToApply.get().getLabelSize();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTableEditor, dCell.getLine());
+ int dCellIndex = new DCellQuery(dCell).getColumnIndex();
+ int treeItemLabelSize = TreeUtils.getWidgetLabelSize(treeItem, dCellIndex + 1);
+ Assert.assertEquals("The TreeItem label size should corresponds to its DCell.currentStyle.labelSize", labelSize, treeItemLabelSize);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getFont()}'s label format for a specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemLabelFormat(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ FontFormat fontFormat = dTreeItem.getOwnedStyle().getLabelFormat();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ FontFormat widgetFontFormat = TreeUtils.getWidgetLabelFormat(treeItem);
+ Assert.assertEquals("The TreeItem label font format should corresponds to its DTreeItem.ownedStyle.fontFormat", fontFormat, widgetFontFormat);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getFont()}'s label format for a specified
+ * {@link DCell}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DCell}
+ * @param dCell
+ * the {@link DCell}
+ */
+ public static void checkTreeItemLabelFormat(SWTBotEditor swtBotTableEditor, DCell dCell) {
+ Option<DTableElementStyle> optionalForegroundStyleToApply = new DCellQuery(dCell).getForegroundStyleToApply();
+ Assert.assertTrue("We should have a currentStyle for the cell.", optionalForegroundStyleToApply.some());
+ FontFormat fontFormat = optionalForegroundStyleToApply.get().getLabelFormat();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTableEditor, dCell.getLine());
+ int dCellIndex = new DCellQuery(dCell).getColumnIndex();
+ FontFormat widgetFontFormat = TreeUtils.getWidgetLabelFormat(treeItem, dCellIndex + 1);
+ Assert.assertEquals("The TreeItem label font format should corresponds to its DCell.currentStyle.fontFormat", fontFormat, widgetFontFormat);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getImage()} is not null for a specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemShowIcon(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ boolean showIcon = dTreeItem.getOwnedStyle().isShowIcon();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ boolean widgetShowIcon = TreeUtils.hasWidgetWithIcon(treeItem);
+ Assert.assertEquals("The TreeItem.image nullity should corresponds to its DTreeItem.ownedStyle.showIcon", showIcon, widgetShowIcon);
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getFont()}'s label color for a specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ */
+ public static void checkTreeItemLabelColor(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ RGBValues labelColor = dTreeItem.getOwnedStyle().getLabelColor();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTreeEditor, dTreeItem);
+ RGBValues widgetLabelColor = TreeUtils.getWidgetLabelColor(treeItem);
+ // CHECKSTYLE:OFF
+ String backgroundColorMessage = "\t DTreeItem.ownedStyle.labelColor : (" + labelColor.getRed() + "," + labelColor.getGreen() + "," + labelColor.getBlue() + ")\n";
+ // CHECKSTYLE:ON
+ String widgetBackgroundColorMessage = "\t SWTTreeItem.backgroundColor : (" + widgetLabelColor.getRed() + "," + widgetLabelColor.getGreen() + "," + widgetLabelColor.getBlue() + ")\n";
+ String failureMessage = "The label color from the DTreeItem and this from the swt widget differs : \n" + backgroundColorMessage + widgetBackgroundColorMessage;
+
+ Assert.assertEquals(failureMessage, labelColor.getRed(), widgetLabelColor.getRed());
+ Assert.assertEquals(failureMessage, labelColor.getGreen(), widgetLabelColor.getGreen());
+ Assert.assertEquals(failureMessage, labelColor.getBlue(), widgetLabelColor.getBlue());
+ }
+
+ /**
+ * Checks the swt {@link TreeItem#getForeground()}'s label color for a
+ * specified {@link DCell}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DCell}
+ * @param dCell
+ * the {@link DCell}
+ */
+ public static void checkTreeItemLabelColor(SWTBotEditor swtBotTableEditor, DCell dCell) {
+ Option<DTableElementStyle> optionalForegroundStyleToApply = new DCellQuery(dCell).getForegroundStyleToApply();
+ Assert.assertTrue("We should have a currentStyle for the cell.", optionalForegroundStyleToApply.some());
+ RGBValues foregroundColor = optionalForegroundStyleToApply.get().getForegroundColor();
+ TreeItem treeItem = TreeUtils.getTreeItem(swtBotTableEditor, dCell.getLine());
+ int dCellIndex = new DCellQuery(dCell).getColumnIndex();
+ RGBValues widgetForegroundColor = TreeUtils.getWidgetLabelColor(treeItem, dCellIndex + 1);
+ // CHECKSTYLE:OFF
+ String backgroundColorMessage = "\t DCellStyle.foregroundColor : (" + foregroundColor.getRed() + "," + foregroundColor.getGreen() + "," + foregroundColor.getBlue() + ")\n";
+ // CHECKSTYLE:ON
+ String widgetBackgroundColorMessage = "\t SWTTreeItem.oregroundColor : (" + widgetForegroundColor.getRed() + "," + widgetForegroundColor.getGreen() + "," + widgetForegroundColor.getBlue()
+ + ")\n";
+ String failureMessage = "The label color from the DCellStyle and this from the swt widget differs : \n" + backgroundColorMessage + widgetBackgroundColorMessage;
+
+ Assert.assertEquals(failureMessage, foregroundColor.getRed(), widgetForegroundColor.getRed());
+ Assert.assertEquals(failureMessage, foregroundColor.getGreen(), widgetForegroundColor.getGreen());
+ Assert.assertEquals(failureMessage, foregroundColor.getBlue(), widgetForegroundColor.getBlue());
+ }
+
+ /**
+ * Resize the header column with the specified new width on the specified
+ * editor.
+ *
+ * @param swtBotTableEditor
+ * the specified bot of the table editor
+ * @param dTable
+ * the {@link DTable} for which to resize the header column
+ * @param newWidth
+ * the new width
+ */
+ public static void resizeTreeHeaderColumnWidth(SWTBotEditor swtBotTableEditor, DTable dTable, int newWidth) {
+ TreeUtils.resizeTreeColumnWidth(swtBotTableEditor, null, newWidth);
+ }
+
+ /**
+ * Resize the column with the specified new width on the specified editor.
+ *
+ * @param swtBotTableEditor
+ * the specified bot of the table editor
+ * @param dColumn
+ * the {@link DColumn} for which to resize the TreeColumn
+ * @param newWidth
+ * the new width
+ */
+ public static void resizeTreeColumnWidth(SWTBotEditor swtBotTableEditor, DColumn dColumn, int newWidth) {
+ DTableEditor dTableEditor = (DTableEditor) swtBotTableEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTableEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, null);
+ Display.getDefault().syncExec(itemSearcher);
+ Item item = itemSearcher.getResult();
+ Assert.assertTrue("item should be a TreeColumn", item instanceof TreeColumn);
+ TreeColumn treeColumn = (TreeColumn) item;
+ TreeColumnWidthSetter treeColumnWidthSetter = new TreeColumnWidthSetter(treeColumn, newWidth);
+ Display.getDefault().syncExec(treeColumnWidthSetter);
+ }
+
+ /**
+ * Checks the swt Tree.columns[0]'s width for a specified {@link DTable}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DTable}
+ * @param dTable
+ * the {@link DTable}
+ */
+ public static void checkTreeHeaderColumnWidth(SWTBotEditor swtBotTableEditor, DTable dTable) {
+ int widgetHeaderColumnWidth = TreeUtils.getColumnWidth(swtBotTableEditor, null);
+ int modelHeaderColumnWidth = dTable.getHeaderColumnWidth();
+ Assert.assertEquals("DTable.headerColumnWidth should corresponds to the Tree.treeColumn[0].width", modelHeaderColumnWidth, widgetHeaderColumnWidth);
+ }
+
+ /**
+ * Checks the swt TreeColumn's width for a specified {@link DColumn}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt {@link TreeItem} referencing the
+ * specified {@link DColumn}
+ * @param dColumn
+ * the {@link DColumn}
+ */
+ public static void checkTreeColumnWidth(SWTBotEditor swtBotTableEditor, DColumn dColumn) {
+ int widgetHeaderColumnWidth = TreeUtils.getColumnWidth(swtBotTableEditor, dColumn);
+ int modelColumnWidth = dColumn.getWidth();
+ Assert.assertEquals("DColumn.width should corresponds to the TreeColumn.width", modelColumnWidth, widgetHeaderColumnWidth);
+ }
+
+ private static TreeItem getTreeItem(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ TreeItem treeItem = null;
+ DTreeEditor dTreeEditor = (DTreeEditor) swtBotTreeEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTreeEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dTreeItem);
+ Display.getDefault().syncExec(itemSearcher);
+ treeItem = (TreeItem) itemSearcher.getResult();
+ return treeItem;
+ }
+
+ private static TreeItem getTreeItem(SWTBotEditor swtBotTableEditor, DLine dLine) {
+ TreeItem treeItem = null;
+ DTableEditor dTableEditor = (DTableEditor) swtBotTableEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTableEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dLine);
+ Display.getDefault().syncExec(itemSearcher);
+ treeItem = (TreeItem) itemSearcher.getResult();
+ return treeItem;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} expansion state for a specified
+ * {@link DLine}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DLine}
+ * @param dLine
+ * the {@link DLine}
+ *
+ * @return the swt {@link TreeItem} expansion state
+ */
+ public static boolean getWidgetExpansion(SWTBotEditor swtBotTableEditor, DLine dLine) {
+ boolean widgetExpansion = false;
+ DTableEditor dTableEditor = (DTableEditor) swtBotTableEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTableEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dLine);
+ Display.getDefault().syncExec(itemSearcher);
+ TreeItem treeItem = (TreeItem) itemSearcher.getResult();
+ widgetExpansion = TreeUtils.getWidgetExpansion(treeItem);
+ return widgetExpansion;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} expansion state for a specified
+ * {@link DTreeItem}.
+ *
+ * @param swtBotTreeEditor
+ * the editor bot owning the {@link TreeItem} referencing the
+ * specified {@link DTreeItem}
+ * @param dTreeItem
+ * the {@link DTreeItem}
+ * @return the swt {@link TreeItem} expansion state
+ */
+ public static boolean getWidgetExpansion(SWTBotEditor swtBotTreeEditor, DTreeItem dTreeItem) {
+ boolean widgetExpansion = false;
+ DTreeEditor dTreeEditor = (DTreeEditor) swtBotTreeEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTreeEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dTreeItem);
+ Display.getDefault().syncExec(itemSearcher);
+ TreeItem treeItem = (TreeItem) itemSearcher.getResult();
+ widgetExpansion = TreeUtils.getWidgetExpansion(treeItem);
+ return widgetExpansion;
+ }
+
+ /**
+ * Get the swt Column width for a specified {@link DColumn}.
+ *
+ * @param swtBotTableEditor
+ * the editor bot owning the swt column} referencing the
+ * specified {@link DColumn}
+ * @param dColumn
+ * the {@link DColumn}
+ * @return the swt Column widthfor a specified {@link DColumn}
+ */
+ public static int getColumnWidth(SWTBotEditor swtBotTableEditor, DColumn dColumn) {
+ int columnWidth = -1;
+ DTableEditor dTableEditor = (DTableEditor) swtBotTableEditor.getReference().getEditor(false);
+ Tree tree = (Tree) dTableEditor.getControl();
+ ItemSearcher itemSearcher = new ItemSearcher(tree, dColumn);
+ Display.getDefault().syncExec(itemSearcher);
+ Item item = itemSearcher.getResult();
+ Assert.assertTrue("item should be a TreeColumn", item instanceof TreeColumn);
+ TreeColumn treeColumn = (TreeColumn) item;
+ TreeColumnWidthQuery treeColumnWidthQuery = new TreeColumnWidthQuery(treeColumn);
+ Display.getDefault().syncExec(treeColumnWidthQuery);
+ columnWidth = treeColumnWidthQuery.getResult();
+ return columnWidth;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} expansion state for a specified
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return the swt {@link TreeItem} expansion state
+ */
+ public static boolean getWidgetExpansion(TreeItem treeItem) {
+ boolean widgetExpansion = false;
+ TreeItemExpandedQuery treeItemExpandedQuery = new TreeItemExpandedQuery(treeItem);
+ Display.getDefault().syncExec(treeItemExpandedQuery);
+ widgetExpansion = treeItemExpandedQuery.getResult();
+ return widgetExpansion;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} background color of a specified
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return the swt {@link TreeItem} background color of a specified
+ * {@link TreeItem}
+ */
+ private static RGBValues getWidgetBackgroundColor(TreeItem treeItem) {
+ RGBValues widgetBackgroundColor = TreeUtils.getWidgetBackgroundColor(treeItem, 0);
+ return widgetBackgroundColor;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} background color of a specified
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param index
+ * the index in the {@link TreeItem} for which to get the
+ * background color
+ * @return the swt {@link TreeItem} background color of a specified
+ * {@link TreeItem}
+ */
+ private static RGBValues getWidgetBackgroundColor(TreeItem treeItem, int index) {
+ RGBValues widgetBackgroundColor = null;
+ TreeItemBackgroundColorQuery treeItemBackgroundColorQuery = new TreeItemBackgroundColorQuery(treeItem, index);
+ Display.getDefault().syncExec(treeItemBackgroundColorQuery);
+ widgetBackgroundColor = treeItemBackgroundColorQuery.getResult();
+ return widgetBackgroundColor;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label size of a specified {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return the swt {@link TreeItem} label size a specified {@link TreeItem}
+ */
+ private static int getWidgetLabelSize(TreeItem treeItem) {
+ int widgetLabelSize = TreeUtils.getWidgetLabelSize(treeItem, 0);
+ return widgetLabelSize;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label size of a specified {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param index
+ * the index in the {@link TreeItem} for which to get the label
+ * size
+ * @return the swt {@link TreeItem} label size a specified {@link TreeItem}
+ */
+ private static int getWidgetLabelSize(TreeItem treeItem, int index) {
+ int widgetLabelSize;
+ TreeItemLabelSizeQuery treeItemBackgroundColorQuery = new TreeItemLabelSizeQuery(treeItem, index);
+ Display.getDefault().syncExec(treeItemBackgroundColorQuery);
+ widgetLabelSize = treeItemBackgroundColorQuery.getResult();
+ return widgetLabelSize;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label font format of a specified
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return the swt {@link TreeItem} label font format a specified
+ * {@link TreeItem}
+ */
+ private static FontFormat getWidgetLabelFormat(TreeItem treeItem) {
+ FontFormat widgetLabelFormat = TreeUtils.getWidgetLabelFormat(treeItem, 0);
+ return widgetLabelFormat;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label font format of a specified
+ * {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param index
+ * the index in the {@link TreeItem} for which to get the label
+ * format
+ * @return the swt {@link TreeItem} label font format a specified
+ * {@link TreeItem}
+ */
+ private static FontFormat getWidgetLabelFormat(TreeItem treeItem, int index) {
+ FontFormat widgetLabelFormat = null;
+ TreeItemLabelFontFormatQuery treeItemBackgroundColorQuery = new TreeItemLabelFontFormatQuery(treeItem, index);
+ Display.getDefault().syncExec(treeItemBackgroundColorQuery);
+ widgetLabelFormat = treeItemBackgroundColorQuery.getResult();
+ return widgetLabelFormat;
+ }
+
+ /**
+ * Tells if the swt {@link TreeItem} has a associated {@link Image}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return true if the swt {@link TreeItem} has a associated {@link Image},
+ * false else
+ */
+ private static boolean hasWidgetWithIcon(TreeItem treeItem) {
+ boolean hasWidgetWithIcon = false;
+ TreeItemImageQuery treeItemImageQuery = new TreeItemImageQuery(treeItem);
+ Display.getDefault().syncExec(treeItemImageQuery);
+ Image result = (Image) treeItemImageQuery.getResult();
+ hasWidgetWithIcon = result != null;
+ return hasWidgetWithIcon;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label color of a specified {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @return the swt {@link TreeItem} label color of a specified
+ * {@link TreeItem}
+ */
+ private static RGBValues getWidgetLabelColor(TreeItem treeItem) {
+ RGBValues widgetLabelColor = TreeUtils.getWidgetLabelColor(treeItem, 0);
+ return widgetLabelColor;
+ }
+
+ /**
+ * Get the swt {@link TreeItem} label color of a specified {@link TreeItem}.
+ *
+ * @param treeItem
+ * the {@link TreeItem}
+ * @param index
+ * the index in the {@link TreeItem} for which to get the
+ * background color
+ * @return the swt {@link TreeItem} label color of a specified
+ * {@link TreeItem}
+ */
+ private static RGBValues getWidgetLabelColor(TreeItem treeItem, int index) {
+ RGBValues widgetLabelColor = null;
+ TreeItemLabelColorQuery treeItemLabelColorQuery = new TreeItemLabelColorQuery(treeItem, index);
+ Display.getDefault().syncExec(treeItemLabelColorQuery);
+ widgetLabelColor = treeItemLabelColorQuery.getResult();
+ return widgetLabelColor;
+ }
+
+}
diff --git a/plugins/org.eclipse.sirius.tree.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tree.ui/META-INF/MANIFEST.MF
index fa2542efbe..4ac1e30172 100644
--- a/plugins/org.eclipse.sirius.tree.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.tree.ui/META-INF/MANIFEST.MF
@@ -32,7 +32,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.sirius;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.sirius.ui;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.emf.edit.ui;bundle-version="2.8.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)",
+ com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.sirius.ecore.extender;bundle-version="1.0.0",
org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.300",
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
index 83e65ab632..ce7795bb2a 100644
--- a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/DTreeViewerManager.java
@@ -61,6 +61,7 @@ import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeContentPro
import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeDecoratingLabelProvider;
import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeItemDropListener;
import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.DTreeItemEditingSupport;
+import org.eclipse.sirius.tree.ui.tools.internal.editor.provider.TreeUIUpdater;
import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTableViewerManager;
import org.eclipse.sirius.ui.tools.internal.editor.AbstractDTreeEditor;
import org.eclipse.sirius.ui.tools.internal.editor.DTableColumnViewerEditorActivationStrategy;
@@ -107,6 +108,8 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
private final ITreeCommandFactory treeCommandFactory;
+ private TreeUIUpdater treeUIUpdater;
+
private DTreeContentProvider dTreeContentProvider;
private DTreeMenuListener actualMenuListener;
@@ -172,7 +175,8 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
// tableViewer.setSorter(new
// ExampleTaskSorter(ExampleTaskSorter.DESCRIPTION));
- dTreeContentProvider = new DTreeContentProvider(getSession(), this);
+ treeUIUpdater = new TreeUIUpdater(this);
+ dTreeContentProvider = new DTreeContentProvider();
treeViewer.setContentProvider(dTreeContentProvider);
// Wrap the LabelProvider in a DecoratingLabelProvider
@@ -484,6 +488,8 @@ public class DTreeViewerManager extends AbstractDTableViewerManager {
public void dispose() {
treeViewer.removeTreeListener(treeViewerListener);
treeViewerListener = null;
+ treeUIUpdater.dispose();
+ treeUIUpdater = null;
dTreeContentProvider.dispose();
dTreeContentProvider = null;
super.dispose();
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java
index 85c14beafc..6ced88b104 100644
--- a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentProvider.java
@@ -14,12 +14,9 @@ import java.util.List;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
-
-import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.tree.DTree;
import org.eclipse.sirius.tree.DTreeItem;
import org.eclipse.sirius.tree.DTreeItemContainer;
-import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
/**
* The provider for the content of the tree.
@@ -28,25 +25,6 @@ import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
*/
public class DTreeContentProvider implements ITreeContentProvider {
- private Session session;
-
- /** The EMF adapter */
- private DTreeContentAdapter dTreeContentAdapter;
-
- /**
- * Creates a tree with the given session.
- *
- * @param session
- * the session.
- * @param dTreeViewerManager
- * the manager of the structured viewer to update
- */
- public DTreeContentProvider(final Session session, DTreeViewerManager dTreeViewerManager) {
- this.session = session;
- this.dTreeContentAdapter = new DTreeContentAdapter(dTreeViewerManager);
- this.session.getTransactionalEditingDomain().addResourceSetListener(dTreeContentAdapter);
- }
-
/**
* Returns the elements to display in the viewer (only the visible one).
*
@@ -132,8 +110,6 @@ public class DTreeContentProvider implements ITreeContentProvider {
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
- session.getTransactionalEditingDomain().removeResourceSetListener(dTreeContentAdapter);
- dTreeContentAdapter = null;
}
}
diff --git a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreeUIUpdater.java
index c53ed89ddc..f344b49b2f 100644
--- a/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/DTreeContentAdapter.java
+++ b/plugins/org.eclipse.sirius.tree.ui/src/org/eclipse/sirius/tree/ui/tools/internal/editor/provider/TreeUIUpdater.java
@@ -17,12 +17,8 @@ import org.eclipse.emf.transaction.ResourceSetChangeEvent;
import org.eclipse.emf.transaction.ResourceSetListenerImpl;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
-import org.eclipse.ui.PlatformUI;
-
-import com.google.common.collect.Iterables;
-
-import org.eclipse.sirius.common.tools.DslCommonPlugin;
import org.eclipse.sirius.business.api.helper.SiriusUtil;
+import org.eclipse.sirius.common.tools.DslCommonPlugin;
import org.eclipse.sirius.tools.api.profiler.SiriusTasksKey;
import org.eclipse.sirius.tree.DTree;
import org.eclipse.sirius.tree.DTreeItem;
@@ -32,15 +28,16 @@ import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewer;
import org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewerManager;
import org.eclipse.sirius.viewpoint.RGBValues;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
+import org.eclipse.ui.PlatformUI;
+
+import com.google.common.collect.Iterables;
/**
- * This class is an EMF Adapter which listen change in the model to update a
- * {@link org.eclipse.sirius.tree.ui.tools.internal.editor.DTreeViewer}.
+ * A class responsible to update the UI part of a {@link DTree}.
*
* @author nlepine
- *
*/
-public class DTreeContentAdapter extends ResourceSetListenerImpl {
+public class TreeUIUpdater extends ResourceSetListenerImpl {
private DTreeViewerManager dTreeViewerManager;
@@ -53,9 +50,10 @@ public class DTreeContentAdapter extends ResourceSetListenerImpl {
* @param dTreeViewerManager
* the structured viewer to update
*/
- public DTreeContentAdapter(DTreeViewerManager dTreeViewerManager) {
+ public TreeUIUpdater(DTreeViewerManager dTreeViewerManager) {
this.dTreeViewerManager = dTreeViewerManager;
this.dTreeViewer = (DTreeViewer) dTreeViewerManager.getTreeViewer();
+ dTreeViewerManager.getEditingDomain().addResourceSetListener(this);
}
/**
@@ -287,4 +285,13 @@ public class DTreeContentAdapter extends ResourceSetListenerImpl {
}
}
}
+
+ /**
+ * Dispose this {@link TreeUIUpdater}.
+ */
+ public void dispose() {
+ if (getTarget() != null) {
+ getTarget().removeResourceSetListener(this);
+ }
+ }
}
diff --git a/plugins/org.eclipse.sirius.tree/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.tree/META-INF/MANIFEST.MF
index aadda8b785..cd2e622ef7 100644
--- a/plugins/org.eclipse.sirius.tree/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.tree/META-INF/MANIFEST.MF
@@ -36,7 +36,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.sirius.synchronizer;bundle-version="1.0.0";visibility:=reexport,
org.eclipse.sirius.ecore.extender;bundle-version="1.0.0",
org.eclipse.emf.transaction;bundle-version="1.4.0",
- com.google.guava;bundle-version="[11.0.0,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Eclipse-LazyStart: true
Bundle-ActivationPolicy: lazy
Import-Package: org.eclipse.sirius.ext.base;version="1.0.0"
diff --git a/plugins/org.eclipse.sirius.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius.ui/META-INF/MANIFEST.MF
index c5802f7bd8..a16c64c21f 100644
--- a/plugins/org.eclipse.sirius.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius.ui/META-INF/MANIFEST.MF
@@ -92,7 +92,7 @@ Export-Package: org.eclipse.sirius.description.contribution.provider;version="1.
org.eclipse.sirius.viewpoint.description.tool.provider;version="1.0.0",
org.eclipse.sirius.viewpoint.description.validation.provider;version="1.0.0",
org.eclipse.sirius.viewpoint.provider;version="1.0.0"
-Require-Bundle: com.google.guava;bundle-version="[11.0.0,12.0.0)",
+Require-Bundle: com.google.guava;bundle-version="[11.0.2,16.0)",
org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.sirius;visibility:=reexport;bundle-version="1.0.0",
org.eclipse.emf.edit;visibility:=reexport;bundle-version="2.8.0",
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/business/api/session/SessionHelper.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/business/api/session/SessionHelper.java
index a4f6982529..90029f40fa 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/business/api/session/SessionHelper.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/business/api/session/SessionHelper.java
@@ -114,8 +114,8 @@ public final class SessionHelper {
if (!checkedDescriptions.containsKey(description)) {
boolean candidate = false;
if (description.isShowOnStartup()) {
- Viewpoint parentSirius = new RepresentationDescriptionQuery(description).getParentSirius();
- candidate = parentSirius == null ? false : selectedVps.contains(parentSirius);
+ Viewpoint parentViewpoint = new RepresentationDescriptionQuery(description).getParentViewpoint();
+ candidate = parentViewpoint == null ? false : selectedVps.contains(parentViewpoint);
}
checkedDescriptions.put(description, candidate);
}
diff --git a/plugins/org.eclipse.sirius/META-INF/MANIFEST.MF b/plugins/org.eclipse.sirius/META-INF/MANIFEST.MF
index 1c42086538..0d1394d6c3 100644
--- a/plugins/org.eclipse.sirius/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.sirius/META-INF/MANIFEST.MF
@@ -125,7 +125,7 @@ Require-Bundle: org.eclipse.sirius.common;bundle-version="1.0.0",
org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.emf.ecore;visibility:=reexport;bundle-version="2.8.3",
org.eclipse.emf.ecore.xmi;bundle-version="2.8.1",
- com.google.guava;bundle-version="[11.0.0,12.0.0)"
+ com.google.guava;bundle-version="[11.0.2,16.0)"
Import-Package: org.eclipse.sirius.ext.base;version="1.0.0",
org.eclipse.sirius.ext.base.cache;version="1.0.0",
org.eclipse.sirius.ext.base.collect;version="1.0.0",
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/componentization/ViewpointRegistryImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/componentization/ViewpointRegistryImpl.java
index 0847ae710d..90bcb03cad 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/componentization/ViewpointRegistryImpl.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/componentization/ViewpointRegistryImpl.java
@@ -20,7 +20,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
@@ -61,10 +61,12 @@ import org.eclipse.sirius.viewpoint.description.Viewpoint;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
public class ViewpointRegistryImpl extends ViewpointRegistry {
@@ -84,7 +86,7 @@ public class ViewpointRegistryImpl extends ViewpointRegistry {
private boolean shouldInvalidateCache;
- private Map<EObject, EObject> foundCache = prepareFoundCache();
+ private LoadingCache<EObject, EObject> foundCache = prepareFoundCache();
private Map<String, ViewpointFileCollector> collectors;
@@ -172,13 +174,12 @@ public class ViewpointRegistryImpl extends ViewpointRegistry {
prepareFoundCache();
}
- private ConcurrentMap<EObject, EObject> prepareFoundCache() {
- return new MapMaker().weakKeys().makeComputingMap(new Function<EObject, EObject>() {
-
+ private LoadingCache<EObject, EObject> prepareFoundCache() {
+ return CacheBuilder.newBuilder().weakKeys().build(CacheLoader.from(new Function<EObject, EObject>() {
public EObject apply(EObject from) {
return lookForEquivalentInRegistry(from);
}
- });
+ }));
}
/**
@@ -441,7 +442,7 @@ public class ViewpointRegistryImpl extends ViewpointRegistry {
* @since 0.9.0
*/
public Viewpoint getViewpoint(final RepresentationDescription description) {
- return new RepresentationDescriptionQuery(description).getParentSirius();
+ return new RepresentationDescriptionQuery(description).getParentViewpoint();
}
/**
@@ -860,7 +861,11 @@ public class ViewpointRegistryImpl extends ViewpointRegistry {
* @return the eObject instance if found, the given object otherwise
*/
public EObject find(final EObject eObject) {
- return foundCache.get(eObject);
+ try {
+ return foundCache.get(eObject);
+ } catch (ExecutionException e) {
+ return eObject;
+ }
}
private EObject lookForEquivalentInRegistry(final EObject eObject) {
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/RepresentationDescriptionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/RepresentationDescriptionQuery.java
index 9c9c1c561c..fb9fb955fe 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/RepresentationDescriptionQuery.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/query/RepresentationDescriptionQuery.java
@@ -36,11 +36,11 @@ public class RepresentationDescriptionQuery {
}
/**
- * return the Sirius defining the representation description.
+ * return the Viewpoint defining the representation description.
*
- * @return the Sirius defining the representation description.
+ * @return the Viewpoint defining the representation description.
*/
- public Viewpoint getParentSirius() {
+ public Viewpoint getParentViewpoint() {
EObject current = vp;
while (current != null) {
current = current.eContainer();
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/repair/SiriusRepairProcess.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/repair/SiriusRepairProcess.java
index 6542ab0d03..0338cd6d15 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/repair/SiriusRepairProcess.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/repair/SiriusRepairProcess.java
@@ -457,7 +457,7 @@ public class SiriusRepairProcess {
final DRepresentation representation = view.getAllRepresentations().get(0);
final RepresentationDescription description = DialectManager.INSTANCE.getDescription(representation);
if (description != null) {
- Viewpoint vp = new RepresentationDescriptionQuery(description).getParentSirius();
+ Viewpoint vp = new RepresentationDescriptionQuery(description).getParentViewpoint();
if (vp != null) {
view.setViewpoint(vp);
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/contribution/RepresentationExtensionsFinder.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/contribution/RepresentationExtensionsFinder.java
index 1d4ddb2012..fa75d0ba76 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/contribution/RepresentationExtensionsFinder.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/contribution/RepresentationExtensionsFinder.java
@@ -108,7 +108,7 @@ public class RepresentationExtensionsFinder {
public LinkedHashSet<Viewpoint> findAllRelevantViewpoints(Session session) {
RepresentationDescription mainRepresentationDescription = extensionTarget;
LinkedHashSet<Viewpoint> result = Sets.newLinkedHashSet();
- Viewpoint mainVP = new RepresentationDescriptionQuery(mainRepresentationDescription).getParentSirius();
+ Viewpoint mainVP = new RepresentationDescriptionQuery(mainRepresentationDescription).getParentViewpoint();
if (mainVP != null) {
BiMap<URI, Viewpoint> candidates = HashBiMap.create();
for (Viewpoint vp : session.getSelectedViewpoints(false)) {
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/MaskingPolicy.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/MaskingPolicy.java
index b5aee978d1..6f983414f2 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/MaskingPolicy.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/MaskingPolicy.java
@@ -12,8 +12,8 @@ package org.eclipse.sirius.business.internal.movida.registry;
import java.util.Comparator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
@@ -27,11 +27,13 @@ import com.google.common.base.Functions;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
-import com.google.common.collect.MapMaker;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
/**
@@ -129,7 +131,7 @@ public class MaskingPolicy {
* resource A. A resource (and all the Viewpoints it defines) is visible if
* and only if this sum is 0.
*/
- private final Map<Resource, Integer> score = new MapMaker().makeComputingMap(Functions.constant(0));
+ private final LoadingCache<Resource, Integer> score = CacheBuilder.newBuilder().<Resource, Integer>build(CacheLoader.from(Functions.constant(0)));
/**
* The handler used to find Sirius instances inside loaded resources.
@@ -228,7 +230,7 @@ public class MaskingPolicy {
updateScore(providers.get(i).provider, -1, change);
}
}
- score.remove(unloaded);
+ score.invalidate(unloaded);
change.masked.add(unloaded);
assert change.isConsistent();
return change;
@@ -283,7 +285,12 @@ public class MaskingPolicy {
}
private void updateScore(Resource res, int delta, MaskingChange change) {
- int oldValue = score.get(res);
+ int oldValue;
+ try {
+ oldValue = score.get(res);
+ } catch (ExecutionException e) {
+ oldValue = 0;
+ }
int newValue = oldValue + delta;
assert newValue >= 0;
score.put(res, newValue);
@@ -303,7 +310,7 @@ public class MaskingPolicy {
* another resource.
*/
public synchronized boolean isMasked(Resource res) {
- return score.containsKey(res) && score.get(res).intValue() > 0;
+ return score.asMap().containsKey(res) && score.getIfPresent(res).intValue() > 0;
}
/**
@@ -313,7 +320,7 @@ public class MaskingPolicy {
*/
public synchronized Set<Resource> getUnmaskedResources() {
Set<Resource> unmasked = Sets.newHashSet();
- for (Resource resource : score.keySet()) {
+ for (Resource resource : score.asMap().keySet()) {
if (!isMasked(resource)) {
unmasked.add(resource);
}
@@ -327,6 +334,6 @@ public class MaskingPolicy {
* @return all the loaded but masked resources.
*/
public synchronized Set<Resource> getMaskedResources() {
- return ImmutableSet.copyOf(Sets.difference(score.keySet(), getUnmaskedResources()));
+ return ImmutableSet.copyOf(Sets.difference(score.asMap().keySet(), getUnmaskedResources()));
}
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java
index a71dad6d06..0214b73933 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/movida/registry/ViewpointRegistry.java
@@ -653,7 +653,7 @@ public class ViewpointRegistry extends org.eclipse.sirius.business.api.component
* {@inheritDoc}
*/
public Viewpoint getViewpoint(RepresentationDescription description) {
- return new RepresentationDescriptionQuery(description).getParentSirius();
+ return new RepresentationDescriptionQuery(description).getParentViewpoint();
}
/**
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/SessionTransientAttachment.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/SessionTransientAttachment.java
index 857b739d64..8a735f5e22 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/SessionTransientAttachment.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/SessionTransientAttachment.java
@@ -19,6 +19,7 @@ import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
/**
* This adapter might be used as a marker to retrieve a {@link Session} from any
@@ -68,7 +69,7 @@ public class SessionTransientAttachment extends AdapterImpl {
* @return an optional SessionTransientAttachment.
*/
public static Option<SessionTransientAttachment> getSessionTransientAttachement(Notifier eObj) {
- Iterator<SessionTransientAttachment> it = Iterators.filter(eObj.eAdapters().iterator(), SessionTransientAttachment.class);
+ Iterator<SessionTransientAttachment> it = Iterators.filter(Sets.newLinkedHashSet(eObj.eAdapters()).iterator(), SessionTransientAttachment.class);
if (it.hasNext()) {
return Options.newSome(it.next());
}
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java
index 688c188807..9639575eed 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionImpl.java
@@ -1,6 +1,6 @@
//CHECKSTYLE:OFF
/*******************************************************************************
- * Copyright (c) 2013 THALES GLOBAL SERVICES.
+ * Copyright (c) 2013, 2014 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -206,8 +206,6 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
/** The listener suitable for refresh the opened viewpoint editors. */
protected RefreshEditorsPrecommitListener refreshEditorsListeners;
- private VisibilityPropagatorAdapter visibilityPropagator;
-
private final RepresentationsChangeAdapter representationsChangeAdapter;
private final ResourceSetListener representationNameListener;
@@ -225,7 +223,6 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
this.mainDAnalysis = mainDAnalysis;
this.sessionResource = mainDAnalysis.eResource();
this.interpreter = new ODesignGenericInterpreter();
- this.visibilityPropagator = new VisibilityPropagatorAdapter(this);
this.representationsChangeAdapter = new RepresentationsChangeAdapter(this);
this.representationNameListener = new RepresentationNameListener();
this.controlledResourcesDetector = new ControlledResourcesDetector(this);
@@ -1228,9 +1225,6 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
@Override
public void addAdaptersOnAnalysis(final DAnalysis analysis) {
- if (this.visibilityPropagator != null) {
- analysis.eAdapters().add(this.visibilityPropagator);
- }
if (this.representationsChangeAdapter != null) {
this.representationsChangeAdapter.registerAnalysis(analysis);
}
@@ -1241,9 +1235,6 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
@Override
public void removeAdaptersOnAnalysis(final DAnalysis analysis) {
- if (this.visibilityPropagator != null) {
- analysis.eAdapters().remove(this.visibilityPropagator);
- }
if (this.representationsChangeAdapter != null) {
this.representationsChangeAdapter.unregisterAnalysis(analysis);
}
@@ -1756,7 +1747,6 @@ public class DAnalysisSessionImpl extends DAnalysisSessionEObjectImpl implements
}
interpreter = null;
crossReferencer = null;
- visibilityPropagator = null;
transactionalEditingDomain.removeResourceSetListener(representationNameListener);
// TODO deinitialize model accessor, authority..
// dispose the SessionEventBroker
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java
index cc8ae6e37b..a09c016285 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/session/danalysis/DAnalysisSessionServicesImpl.java
@@ -331,7 +331,7 @@ public class DAnalysisSessionServicesImpl implements SessionService, DAnalysisSe
private void addRepresentationToContainer(final DRepresentation representation, final Resource res) {
final EObject semanticRoot = res.getContents().iterator().next();
- final Viewpoint viewpoint = new RepresentationDescriptionQuery(DialectManager.INSTANCE.getDescription(representation)).getParentSirius();
+ final Viewpoint viewpoint = new RepresentationDescriptionQuery(DialectManager.INSTANCE.getDescription(representation)).getParentViewpoint();
DRepresentationContainer existingContainer = DAnalysisSessionHelper.findContainerForAddedRepresentation(semanticRoot, viewpoint, getAnalysisAndReferenced(), analysisSelector, representation);
if (existingContainer == null) {

Back to the top