Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreperico2010-04-22 09:35:07 +0000
committereperico2010-04-22 09:35:07 +0000
commit64c2939079c9f262e1a34a66173819a7f8138dfe (patch)
treebe30cf5638b7f516af85826295cac67f36689e6d
parent1a07d538c09cd2065521e2db4e82b4023f64d2ae (diff)
downloadorg.eclipse.papyrus-64c2939079c9f262e1a34a66173819a7f8138dfe.tar.gz
org.eclipse.papyrus-64c2939079c9f262e1a34a66173819a7f8138dfe.tar.xz
org.eclipse.papyrus-64c2939079c9f262e1a34a66173819a7f8138dfe.zip
branch to develop the resource loading strategy
-rw-r--r--org.eclipse.papyrus.core/.classpath8
-rw-r--r--org.eclipse.papyrus.core/.options6
-rw-r--r--org.eclipse.papyrus.core/.project28
-rw-r--r--org.eclipse.papyrus.core/META-INF/MANIFEST.MF27
-rw-r--r--org.eclipse.papyrus.core/about.ini11
-rw-r--r--org.eclipse.papyrus.core/about.properties13
-rw-r--r--org.eclipse.papyrus.core/build.properties23
-rw-r--r--org.eclipse.papyrus.core/icons/papyrus/32x32/Papyrus_32x32_t.gifbin0 -> 1264 bytes
-rw-r--r--org.eclipse.papyrus.core/icons/papyrus/Papyrus.gifbin0 -> 963 bytes
-rw-r--r--org.eclipse.papyrus.core/plugin.properties12
-rw-r--r--org.eclipse.papyrus.core/plugin.xml11
-rw-r--r--org.eclipse.papyrus.core/schema/contentOutline.exsd144
-rw-r--r--org.eclipse.papyrus.core/schema/loadingStrategy.exsd128
-rw-r--r--org.eclipse.papyrus.core/schema/modelListener.exsd133
-rw-r--r--org.eclipse.papyrus.core/schema/papyrusDiagram.exsd239
-rw-r--r--org.eclipse.papyrus.core/schema/readme.txt5
-rw-r--r--org.eclipse.papyrus.core/schema/service.exsd149
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/Activator.java71
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/ContentOutlineRegistry.java251
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/IPapyrusContentOutlinePage.java34
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/BackboneException.java70
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/CoreMultiDiagramEditor.java744
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/IMultiDiagramEditor.java82
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorFactory.java40
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorIconFactory.java60
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IPageIconsRegistry.java34
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageIconsRegistry.java88
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageModelFactoryRegistry.java90
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadClassNameException.java86
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadNameExtensionException.java69
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/DescriptorExtensionFactory.java81
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/ExtensionException.java84
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/NotFoundException.java69
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandDescriptor.java99
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandExtensionFactory.java99
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandRegistry.java122
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommand.java36
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommandRegistry.java41
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCondition.java33
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/PerspectiveContextDependence.java49
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/AbstractEditorFactory.java110
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptor.java115
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptorExtensionFactory.java81
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorFactoryProxy.java107
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorIconFactory.java123
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorNotFoundException.java53
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/IPluggableEditorFactory.java37
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/MultiDiagramException.java53
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/PluggableEditorFactoryReader.java141
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/DoSaveEvent.java47
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ILifeCycleEventsProvider.java59
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ISaveEventListener.java28
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProvider.java277
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/IPapyrusListener.java29
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/ModelListenerManager.java125
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java68
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java69
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java161
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java110
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/IActionBarContributorFactory.java26
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/AbstractServiceEntry.java156
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ExtensionServicesRegistry.java145
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/IService.java25
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/PojoServiceEntry.java67
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceDescriptor.java159
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceEntry.java108
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceException.java58
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceNotFoundException.java52
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceStartKind.java19
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServicesRegistry.java224
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/BusinessModelResolver.java93
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/DiResourceSet.java398
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/EditorUtils.java308
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionView.java213
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionViewFromIterator.java248
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredListView.java369
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IDebugChannel.java30
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IFilter.java29
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ILoadingStrategy.java33
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/NotationUtils.java119
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/PapyrusTrace.java106
-rw-r--r--org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ProxyManager.java116
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEvent.java28
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEventListener.java57
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProviderTest.java232
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA.java18
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA10.java6
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceB.java6
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceC.java6
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicePojoA.java6
-rw-r--r--org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicesRegistryTest.java218
-rw-r--r--org.eclipse.papyrus.core/todo.txt8
92 files changed, 8848 insertions, 0 deletions
diff --git a/org.eclipse.papyrus.core/.classpath b/org.eclipse.papyrus.core/.classpath
new file mode 100644
index 00000000000..b04b8be8f5d
--- /dev/null
+++ b/org.eclipse.papyrus.core/.classpath
@@ -0,0 +1,8 @@
+<?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/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="test"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.papyrus.core/.options b/org.eclipse.papyrus.core/.options
new file mode 100644
index 00000000000..e98ce7bb88b
--- /dev/null
+++ b/org.eclipse.papyrus.core/.options
@@ -0,0 +1,6 @@
+# master switch
+org.eclipse.papyrus.core/debug=true
+# switch for tracing papyrus core
+org.eclipse.papyrus.core/debug/core=true
+# switch for tracing papyrus extension point loading
+org.eclipse.papyrus.core/debug/extensionpoint=true \ No newline at end of file
diff --git a/org.eclipse.papyrus.core/.project b/org.eclipse.papyrus.core/.project
new file mode 100644
index 00000000000..9c5fd1135cb
--- /dev/null
+++ b/org.eclipse.papyrus.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.core</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>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.papyrus.core/META-INF/MANIFEST.MF b/org.eclipse.papyrus.core/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..32be455e18a
--- /dev/null
+++ b/org.eclipse.papyrus.core/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Localization: plugin
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.papyrus.core;singleton:=true
+Bundle-Version: 0.7.0.qualifier
+Bundle-Activator: org.eclipse.papyrus.core.Activator
+Require-Bundle: org.eclipse.papyrus.sasheditor;bundle-version="0.7.0";visibility:=reexport,
+ org.eclipse.ui.ide;bundle-version="3.4.0";visibility:=reexport,
+ org.eclipse.gmf.runtime.diagram.ui;bundle-version="1.1.0";visibility:=reexport,
+ org.junit,
+ org.eclipse.papyrus.sasheditor.di;bundle-version="0.7.0"
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.papyrus.core,
+ org.eclipse.papyrus.core.contentoutline,
+ org.eclipse.papyrus.core.editor,
+ org.eclipse.papyrus.core.editorsfactory,
+ org.eclipse.papyrus.core.extension,
+ org.eclipse.papyrus.core.extension.commands,
+ org.eclipse.papyrus.core.extension.diagrameditor,
+ org.eclipse.papyrus.core.lifecycleevents,
+ org.eclipse.papyrus.core.listenerservice,
+ org.eclipse.papyrus.core.multidiagram.actionbarcontributor,
+ org.eclipse.papyrus.core.services,
+ org.eclipse.papyrus.core.utils
+Bundle-Vendor: %providerName
diff --git a/org.eclipse.papyrus.core/about.ini b/org.eclipse.papyrus.core/about.ini
new file mode 100644
index 00000000000..b765c003d2a
--- /dev/null
+++ b/org.eclipse.papyrus.core/about.ini
@@ -0,0 +1,11 @@
+# about.ini
+# contains information about a feature
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# "%key" are externalized strings defined in about.properties
+# This file does not need to be translated.
+
+# Property "aboutText" contains blurb for "About" dialog (translated)
+aboutText=%featureText
+
+# Papyrus UML feature icon
+featureImage=icons/papyrus/32x32/Papyrus_32x32_t.gif
diff --git a/org.eclipse.papyrus.core/about.properties b/org.eclipse.papyrus.core/about.properties
new file mode 100644
index 00000000000..e5716664eb2
--- /dev/null
+++ b/org.eclipse.papyrus.core/about.properties
@@ -0,0 +1,13 @@
+# about.properties
+# contains externalized strings for about.ini
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# fill-ins are supplied by about.mappings
+# This file should be translated.
+
+featureText=Papyrus Core \n\
+\n\
+Copyright (c) 2008 Atos Origin, CEA LIST, Obeo, Conselleria d'Infraestructures i Transports.\n\
+\n\
+Papyrus provide an integrated, user-consumable environment for editing models based on UML and other related languages such as SysML. \n\
+Specially, this project will provide the glue around valuable UML and SysML diagram editors (GMF-based or not) and other MDE tools. It will also offer support for UML and SysML profiling mechanisms. \n\
+Visit http://www.eclipse.org/modeling/mdt/?project=papyrus
diff --git a/org.eclipse.papyrus.core/build.properties b/org.eclipse.papyrus.core/build.properties
new file mode 100644
index 00000000000..09c7910f9b3
--- /dev/null
+++ b/org.eclipse.papyrus.core/build.properties
@@ -0,0 +1,23 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ schema/,\
+ plugin.properties,\
+ .options,\
+ icons/,\
+ about.ini,\
+ about.properties,\
+ about.html
+src.includes = about.html,\
+ .classpath,\
+ .options,\
+ .project,\
+ META-INF/,\
+ plugin.properties,\
+ build.properties,\
+ icons/,\
+ plugin.xml,\
+ schema/,\
+ src/
diff --git a/org.eclipse.papyrus.core/icons/papyrus/32x32/Papyrus_32x32_t.gif b/org.eclipse.papyrus.core/icons/papyrus/32x32/Papyrus_32x32_t.gif
new file mode 100644
index 00000000000..50cd9a142ee
--- /dev/null
+++ b/org.eclipse.papyrus.core/icons/papyrus/32x32/Papyrus_32x32_t.gif
Binary files differ
diff --git a/org.eclipse.papyrus.core/icons/papyrus/Papyrus.gif b/org.eclipse.papyrus.core/icons/papyrus/Papyrus.gif
new file mode 100644
index 00000000000..a32f4b1b572
--- /dev/null
+++ b/org.eclipse.papyrus.core/icons/papyrus/Papyrus.gif
Binary files differ
diff --git a/org.eclipse.papyrus.core/plugin.properties b/org.eclipse.papyrus.core/plugin.properties
new file mode 100644
index 00000000000..4ce5500d6a1
--- /dev/null
+++ b/org.eclipse.papyrus.core/plugin.properties
@@ -0,0 +1,12 @@
+#################################################################################
+# Copyright (c) 2008 CEA LIST.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+##################################################################################
+pluginName=Papyrus Backbone (Incubation)
+providerName=Eclipse.org
diff --git a/org.eclipse.papyrus.core/plugin.xml b/org.eclipse.papyrus.core/plugin.xml
new file mode 100644
index 00000000000..bf076b6cfb7
--- /dev/null
+++ b/org.eclipse.papyrus.core/plugin.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension-point id="papyrusDiagram" name="PapyrusDiagram" schema="schema/papyrusDiagram.exsd"/>
+ <extension-point id="modelListener" name="ModelListener" schema="schema/modelListener.exsd"/>
+ <extension-point id="papyrusContentOutline" name="PapyrusContentOutline" schema="schema/contentOutline.exsd"/>
+ <extension-point id="service" name="Service" schema="schema/service.exsd"/>
+ <extension-point id="org.eclipse.papyrus.core" name="loadingStrategy" schema="schema/org.eclipse.papyrus.core.exsd"/>
+
+
+</plugin>
diff --git a/org.eclipse.papyrus.core/schema/contentOutline.exsd b/org.eclipse.papyrus.core/schema/contentOutline.exsd
new file mode 100644
index 00000000000..18d72546961
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/contentOutline.exsd
@@ -0,0 +1,144 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.core" id="org.eclipse.papyrus.core.contentoutline" name="contentoutline"/>
+ </appinfo>
+ <documentation>
+ Specify the content outline to be used by the Papyrus backbone.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="contentoutline"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="contentoutline">
+ <complexType>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ A human readable description.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the contentOutline.
+Class must extends org.eclipse.papyrus.core.contentoutline.IPapyrusContentOutlinePage.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.contentoutline.IPapyrusContentOutlinePage"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="priority" type="string" use="required">
+ <annotation>
+ <documentation>
+ An integer value representing the priority of the contentOutline.
+Only one contentOutline is shown. The one with the highest priority is choosen.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="actionBarContributorId" type="string">
+ <annotation>
+ <documentation>
+ ID of the ActionBarContributor requested by the outline.
+The ID must match a declared ActionBarContributor.
+If no ID is set, use the main ActionBarContributor (the one associated to the MultiEditor).
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2008 CEA List.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA List - initial API and implementation
+ *******************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.papyrus.core/schema/loadingStrategy.exsd b/org.eclipse.papyrus.core/schema/loadingStrategy.exsd
new file mode 100644
index 00000000000..2077bd10bd1
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/loadingStrategy.exsd
@@ -0,0 +1,128 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.core" id="loadingStrategy" name="Model Loading Strategy"/>
+ </appInfo>
+ <documentation>
+ Extension point to load the model and resolve objects according to a specified strategy.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="loadingStrategy" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="loadingStrategy">
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ must be integer
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string" use="required">
+ <annotation>
+ <documentation>
+ A readable description.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="strategy" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.utils.ILoadingStrategy"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ MDT Papyrus 0.7.0 M7
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ You can use startegy to avoid loading all the needed resources for a model.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ The concrete strategy class must implement the interface ILoadingStrategy
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ none
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2010 Atos Origin.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/epl-v10.html
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.papyrus.core/schema/modelListener.exsd b/org.eclipse.papyrus.core/schema/modelListener.exsd
new file mode 100644
index 00000000000..5cc3436db8e
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/modelListener.exsd
@@ -0,0 +1,133 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.core" id="papyrus.backbone.modellistener" name="modelListener"/>
+ </appinfo>
+ <documentation>
+ This extension is used to plug a listener that will know all event in uml model di2 or notation.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="listener"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="listener">
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+ name of the listener
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ Description of the job of this listener
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="realization" type="string" use="required">
+ <annotation>
+ <documentation>
+ Class that is realizes this listener
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.listenerservice.IPapyrusListener"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2008 CEA List.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA List - initial API and implementation
+ *******************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.papyrus.core/schema/papyrusDiagram.exsd b/org.eclipse.papyrus.core/schema/papyrusDiagram.exsd
new file mode 100644
index 00000000000..ecb8fe05f99
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/papyrusDiagram.exsd
@@ -0,0 +1,239 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="papyrus.gmf.multipages" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="papyrus.gmf.multipages" id="nestedEditor" name="NestedEditor"/>
+ </appinfo>
+ <documentation>
+ Define a nested editor descriptor. This descriptor is used to add instance of the described editor to a multi diagram editor.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="editorDiagram" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="creationCommand" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="actionBarContributor" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="editorDiagram">
+ <annotation>
+ <documentation>
+ A diagram suitable for Papyrus backbone.
+Such diagram is a Eclipse Editor.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="factoryClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ The factory used to create an instance of the editor.
+The factory must implements org.eclipse.papyrus.sasheditor.extension.IEditorFactory
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.extension.diagrameditor.IPluggableEditorFactory"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="actionBarContributorId" type="string">
+ <annotation>
+ <documentation>
+ ID of the ActionBarContributor requested by the editor.
+The ID must match a declared ActionBarContributor.
+If no ID is set, the main ActionBarContributor is used (the one associated to the MultiEditor).
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The icon representing the diagram. (use in outline tree)
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="actionBarContributor">
+ <annotation>
+ <documentation>
+ An ActionBarContributor that can be associated to Editors or Views.
+An ActionBarContributor can be shared among several Editors or Views.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Id of the ActionBarContributor. Use to associate the ActionBarContributor to editors.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="implementingClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the ActionBarContributor.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.ui.part.EditorActionBarContributor:"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="creationCommand">
+ <annotation>
+ <documentation>
+ A creation command used to create a new diagram.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ Id of the creation command.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.ui.commands/command/@id"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="label" type="string" use="required">
+ <annotation>
+ <documentation>
+ Label of the creation command.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="creationCommandClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the context.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.extension.commands.ICreationCommand"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="icon" type="string">
+ <annotation>
+ <documentation>
+ The icon representing the command.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="resource"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="creationCondition" type="string">
+ <annotation>
+ <documentation>
+ this condition is evaluated at diagram creation menu and if the method returning boolean in the interface returns false then the diagram will not be available
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.extension.commands.ICreationCondition"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="modelFileExtension" type="string" use="required">
+ <annotation>
+ <documentation>
+ The extension of the model files supported by the diagram.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiInfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ /*******************************************************************************
+ * Copyright (c) 2008 CEA List.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA List - initial API and implementation
+ *******************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.papyrus.core/schema/readme.txt b/org.eclipse.papyrus.core/schema/readme.txt
new file mode 100644
index 00000000000..381d7f1d4f0
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/readme.txt
@@ -0,0 +1,5 @@
+nestedEditor.exsd is an example of schema that should be provided by plugin using
+the multidiagrams extension mechanism.
+Each multi-editor wanting to have auto plugable diagram should declare in its own plugin.xml the
+extension point referencing a copy of nestedEditor.exsd. This copy should be in the same plugin
+has the new multi-editor. \ No newline at end of file
diff --git a/org.eclipse.papyrus.core/schema/service.exsd b/org.eclipse.papyrus.core/schema/service.exsd
new file mode 100644
index 00000000000..e0d3dc2e779
--- /dev/null
+++ b/org.eclipse.papyrus.core/schema/service.exsd
@@ -0,0 +1,149 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.core" id="service" name="Service"/>
+ </appInfo>
+ <documentation>
+ Define a Service used by Papyrus Editors.
+A service can be shared across editors. It can be used as a shared object between editors.
+Some services are used to load models, provide factories, ...
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="service" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="service">
+ <annotation>
+ <documentation>
+ Description of the service.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ The key used to retrieve the service from the ServiceRegistry.
+If not set (default), the classname is used as key.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="classname" type="string" use="required">
+ <annotation>
+ <documentation>
+ Name of the class implementing the service.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.core.services.IService"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="priority" type="string" use="default" value="1">
+ <annotation>
+ <documentation>
+ Priority used when two services are registered under the same key. The service with the higher prority is used.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="startKind" use="default" value="lazy">
+ <annotation>
+ <documentation>
+ Specify how the service is started:
+lazy: when the service is requested.
+startup: started when the Registry is about to finish its initialization.
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="lazy">
+ </enumeration>
+ <enumeration value="startup">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ <attribute name="useClassTypeAsKey" type="boolean" use="default" value="false">
+ <annotation>
+ <documentation>
+ If set to true, indicate that the classtype should be used as key.
+If set to false, attribute &apos;key&apos; is used as key.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/Activator.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/Activator.java
new file mode 100644
index 00000000000..448f3b23105
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/Activator.java
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core;
+
+import org.eclipse.papyrus.log.LogHelper;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.core";
+
+ // The shared instance
+ private static Activator plugin;
+
+ /** Logging helper */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ // register the login helper
+ log = new LogHelper(plugin);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/ContentOutlineRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/ContentOutlineRegistry.java
new file mode 100644
index 00000000000..dcf126dfd36
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/ContentOutlineRegistry.java
@@ -0,0 +1,251 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.contentoutline;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.papyrus.core.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.core.extension.BadClassNameException;
+import org.eclipse.papyrus.core.extension.NotFoundException;
+import org.eclipse.papyrus.core.extension.diagrameditor.EditorDescriptorExtensionFactory;
+import org.osgi.framework.Bundle;
+
+public class ContentOutlineRegistry {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusContentOutline";
+
+ private static String classAttributeName = "class";
+
+ private static String actionBarContributorIdPropertyName = "actionBarContributorId";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /**
+ * The selected content outline.
+ */
+ protected IPapyrusContentOutlinePage contentOutline;
+
+ /**
+ * Associated editor.
+ */
+ private IMultiDiagramEditor multiEditor;
+
+ /**
+ * Constructor. defaultContext, input and site are explicitly required in order be sure that they are initialized. The multiEditor should be
+ * initialized. In particular, getEditorSite(),
+ * getEditorInput() and getDefaultContext() should return initialized values.
+ *
+ * @param multiEditor
+ * @param defaultContext
+ * @param input
+ * @param site
+ * @param extensionPointNamespace
+ */
+ public ContentOutlineRegistry(IMultiDiagramEditor multiEditor, String extensionPointNamespace) {
+ this.multiEditor = multiEditor;
+ this.extensionPointNamespace = extensionPointNamespace;
+ }
+
+ /**
+ * Returns the single instance of the content outline. Creates one if necessary.
+ *
+ * @return the contentOutline the single instance of the content outline
+ * @throws BackboneException
+ * exception thrown when the outline can not be created.
+ */
+ public IPapyrusContentOutlinePage getContentOutline() throws BackboneException {
+ if(contentOutline == null) {
+ createContentOutline();
+ }
+ return contentOutline;
+ }
+
+ /**
+ * Return the {@link ContentOutlineDescriptor} with the highest priority.
+ *
+ * @return
+ * @throws BackboneException
+ * @throws NotFoundException
+ * If no ContentOutline can be found in extensions
+ */
+ private ContentOutlineDescriptor getContentOutlineDescriptor() throws BackboneException {
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+ ContentOutlineDescriptor found = null;
+
+ // look for the one with the highest priority
+ for(IConfigurationElement ele : configElements) {
+ ContentOutlineDescriptor desc = new ContentOutlineDescriptor(ele);
+ if(desc.isHigher(found))
+ found = desc;
+ }
+
+ // Instanciate the object
+ if(found == null)
+ throw new NotFoundException("No ContentOutline registered.");
+
+ return found;
+
+ }
+
+ /**
+ * Creates the content outline from the selected extension.
+ *
+ * @throws BackboneException
+ * exception thrown when the outline can not be created.
+ */
+ private void createContentOutline() throws BackboneException {
+
+ ContentOutlineDescriptor found = getContentOutlineDescriptor();
+ // Instanciate the object
+ if(found != null) {
+ contentOutline = found.createContentOutlinePage();
+ }
+ }
+
+ /**
+ * Inner Descriptor for content outline.
+ * This class load data from Eclipse extension mechanism
+ * TODO Change the parent class. It is here just to have quick code.
+ */
+ protected class ContentOutlineDescriptor extends EditorDescriptorExtensionFactory {
+
+ private int priority;
+
+ private String className;
+
+ private String actionBarContributorID;
+
+ private IConfigurationElement element;
+
+
+ /**
+ * Instance is created when requested.
+ */
+ protected IPapyrusContentOutlinePage instance = null;
+
+ /**
+ * Create a descriptor backuped by the config element.
+ */
+ protected ContentOutlineDescriptor(IConfigurationElement element) throws BackboneException {
+ String tagName = "contentoutline";
+ checkTagName(element, tagName);
+ this.className = element.getAttribute(classAttributeName);
+ this.actionBarContributorID = element.getAttribute(actionBarContributorIdPropertyName);
+ try {
+ this.priority = Integer.parseInt(element.getAttribute("priority"));
+ } catch (NumberFormatException e) {
+ this.priority = 0;
+ }
+
+ this.element = element;
+ // check parameters
+ if(className == null)
+ throw new BadClassNameException("Class name must be set", "contentoutline", classAttributeName);
+
+ }
+
+ /**
+ * Compare priority. The highest priority win.
+ */
+ public boolean isHigher(ContentOutlineDescriptor found) {
+ if(found == null) {
+ return true;
+ }
+ return this.getPriority() > found.getPriority();
+ }
+
+ /**
+ * Return the higher value of the descriptor. This value is used to order the contentOutline. The highest priority win.
+ */
+ private int getPriority() {
+ return priority;
+ }
+
+
+ /**
+ * @return the actionBarContributorID
+ */
+ public String getActionBarContributorID() {
+ return actionBarContributorID;
+ }
+
+ /**
+ * Returns the content outline page instance (lazy initialization)
+ *
+ * @return the context outline page
+ * @throws BackboneException
+ * exception thrown when a problem occurs.
+ */
+ protected IPapyrusContentOutlinePage getContentOutline() throws BackboneException {
+ if(instance == null) {
+ instance = createContentOutlinePage();
+ }
+ return instance;
+ }
+
+ /**
+ * Create the class corresponding to the class attribute.
+ */
+ private Class<IPapyrusContentOutlinePage> loadClass() throws BadClassNameException {
+ if(className == null || className.length() == 0) {
+ throw new BadClassNameException("Classname should be set.", "contentoutline", classAttributeName);
+ }
+ Class<IPapyrusContentOutlinePage> factoryClass;
+ try {
+ factoryClass = (Class<IPapyrusContentOutlinePage>)Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ // try another way
+ try {
+ String declaringID = element.getContributor().getName();
+ Bundle bundle = Platform.getBundle(declaringID);
+ factoryClass = bundle.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ throw new BadClassNameException("", "contentoutline", classAttributeName, e1);
+ }
+ }
+ return factoryClass;
+ }
+
+ /**
+ * create the outlinepage by calling constructor without parameter and then call init method
+ *
+ * @return the outline.
+ * @throws BackboneException
+ */
+ protected IPapyrusContentOutlinePage createContentOutlinePage() throws BackboneException {
+ try {
+ IPapyrusContentOutlinePage outline = loadClass().newInstance();
+ outline.init(multiEditor);
+ return outline;
+
+ } catch (SecurityException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ // throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ throw new RuntimeException(e);
+ }
+ return null;
+ }
+
+ } // end class
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/IPapyrusContentOutlinePage.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/IPapyrusContentOutlinePage.java
new file mode 100644
index 00000000000..44a74b7bb33
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/contentoutline/IPapyrusContentOutlinePage.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.contentoutline;
+
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.papyrus.core.editor.IMultiDiagramEditor;
+
+/**
+ * Extends the original interface to add the init method.
+ */
+public interface IPapyrusContentOutlinePage extends org.eclipse.ui.views.contentoutline.IContentOutlinePage {
+
+ /**
+ * Init the content outline.
+ *
+ * @param multiEditor
+ * the multiEditor is used to access to the context
+ * @throws BackboneException
+ * during research of the associated context.
+ */
+ void init(IMultiDiagramEditor multiEditor) throws BackboneException;
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/BackboneException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/BackboneException.java
new file mode 100644
index 00000000000..45a8a257cd2
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/BackboneException.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.editor;
+
+/**
+ * Root of Backbone Exception
+ *
+ * @author dumoulin
+ *
+ */
+public class BackboneException extends Exception {
+
+ /**
+ * serial version UID
+ *
+ * @generated
+ */
+ private static final long serialVersionUID = 4859634627616979417L;
+
+ /**
+ * Creates a new BackboneException.
+ */
+ public BackboneException() {
+ super();
+ }
+
+ /**
+ * Creates a new BackboneException with the specified message.
+ *
+ * @param message
+ * the message of the exception
+ */
+ public BackboneException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new BackboneException with the specified cause.
+ *
+ * @param cause
+ * the cause of the exception
+ */
+ public BackboneException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a new BackboneException with a specified message and the specified cause.
+ *
+ * @param message
+ * the message of the exception
+ * @param cause
+ * the cause of the exception
+ */
+ public BackboneException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/CoreMultiDiagramEditor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/CoreMultiDiagramEditor.java
new file mode 100644
index 00000000000..1b5cd20c498
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/CoreMultiDiagramEditor.java
@@ -0,0 +1,744 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.core.editor;
+
+import static org.eclipse.papyrus.core.Activator.log;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.EventObject;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListener;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.ui.actions.ActionRegistry;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.papyrus.core.Activator;
+import org.eclipse.papyrus.core.contentoutline.ContentOutlineRegistry;
+import org.eclipse.papyrus.core.editorsfactory.IPageIconsRegistry;
+import org.eclipse.papyrus.core.editorsfactory.PageIconsRegistry;
+import org.eclipse.papyrus.core.editorsfactory.PageModelFactoryRegistry;
+import org.eclipse.papyrus.core.extension.diagrameditor.PluggableEditorFactoryReader;
+import org.eclipse.papyrus.core.lifecycleevents.ILifeCycleEventsProvider;
+import org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider;
+import org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent;
+import org.eclipse.papyrus.core.multidiagram.actionbarcontributor.ActionBarContributorRegistry;
+import org.eclipse.papyrus.core.multidiagram.actionbarcontributor.CoreComposedActionBarContributor;
+import org.eclipse.papyrus.core.services.ExtensionServicesRegistry;
+import org.eclipse.papyrus.core.services.ServiceException;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+import org.eclipse.papyrus.core.utils.BusinessModelResolver;
+import org.eclipse.papyrus.core.utils.DiResourceSet;
+import org.eclipse.papyrus.sasheditor.contentprovider.IContentChangedListener;
+import org.eclipse.papyrus.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.DiSashModelMngr;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.IPageMngr;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.IPageModelFactory;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.TransactionalDiSashModelMngr;
+import org.eclipse.papyrus.sasheditor.editor.AbstractMultiPageSashEditor;
+import org.eclipse.papyrus.sasheditor.editor.gef.MultiDiagramEditorGefDelegate;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * Multi diagram editor allowing to plug various kind of editors. Editors are registered with the help of the Eclipse extension mechanism. This
+ * implementation allows to register editors and context
+ * separately. An editor should specify which context it need to run. This multi diagram editor allows to show editor side by side in one or more sash
+ * windows.
+ *
+ * The real implementation for the generic type T of SashMultiPageEditorPart is actually di2.Diagram
+ *
+ * @author cedric dumoulin
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a> Refactoring.
+ *
+ * TODO : remove GMF dependency !
+ */
+public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implements IMultiDiagramEditor, ITabbedPropertySheetPageContributor, IDiagramWorkbenchPart {
+
+ /** Gef adapter */
+ private MultiDiagramEditorGefDelegate gefAdaptorDelegate;
+
+ /** ContentOutline registry */
+ private ContentOutlineRegistry contentOutlineRegistry;
+
+ /** Services registry. Used to get registered services */
+ private ServicesRegistry servicesRegistry;
+
+ /**
+ * ActionBarContributor Registry. Allows to get an ActionBar by its Id. The registry is initialized from the Eclipse extension mechanism.
+ */
+ private ActionBarContributorRegistry actionBarContributorRegistry;
+
+ /** SashModelMngr to add pages */
+ protected DiSashModelMngr sashModelMngr;
+
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ /**
+ * Object managing models lifeCycle.
+ */
+ protected DiResourceSet resourceSet = new DiResourceSet();
+
+ /**
+ * Class used to propagate life cycle events.
+ * This class can be retrieved as a service using {@link ILifeCycleEventsProvider}.class.
+ */
+ protected LifeCycleEventsProvider lifeCycleEventsProvider;
+
+ /**
+ * Cached event that can be reused.
+ */
+ protected DoSaveEvent lifeCycleEvent;
+
+ /**
+ *
+ */
+ private TabbedPropertySheetPage tabbedPropertySheetPage = null;
+
+ /**
+ * My editing domain provider.
+ */
+ private IEditingDomainProvider domainProvider = new IEditingDomainProvider() {
+
+ public EditingDomain getEditingDomain() {
+ return transactionalEditingDomain;
+ }
+ };
+
+ /**
+ * A listener on model change events.
+ */
+ private IContentChangedListener contentChangedListener = new IContentChangedListener() {
+
+ /**
+ * Called when the content is changed. RefreshTabs.
+ */
+ public void contentChanged(ContentEvent event) {
+ refreshTabs();
+ }
+ };
+
+ private final org.eclipse.emf.common.command.CommandStackListener commandStackListener = new org.eclipse.emf.common.command.CommandStackListener() {
+
+ public void commandStackChanged(EventObject event) {
+ getSite().getShell().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+ }
+ });
+ }
+ };
+
+ private final ResourceSetListener resourceSetListener = new ResourceSetListener() {
+
+ public NotificationFilter getFilter() {
+ return null;
+ }
+
+ public boolean isAggregatePrecommitListener() {
+ return false;
+ }
+
+ public boolean isPostcommitOnly() {
+ return true;
+ }
+
+ public boolean isPrecommitOnly() {
+ return false;
+ }
+
+ public void resourceSetChanged(ResourceSetChangeEvent event) {
+ if(event.getTransaction() != null && event.getTransaction().getStatus().isOK()) {
+ getSite().getShell().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+ }
+ });
+ }
+ }
+
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
+ return null;
+ }
+
+ };
+
+ /**
+ * Get the contentOutlineRegistry. Create it if needed.
+ *
+ * @return the contentOutlineRegistry
+ */
+ protected ContentOutlineRegistry getContentOutlineRegistry() {
+ if(contentOutlineRegistry == null) {
+ createContentOutlineRegistry();
+ }
+
+ return contentOutlineRegistry;
+ }
+
+ /**
+ * Create the contentOutlineRegistry.
+ */
+ private void createContentOutlineRegistry() {
+ contentOutlineRegistry = new ContentOutlineRegistry(this, Activator.PLUGIN_ID);
+ }
+
+ /**
+ * Returns the service registry associated to the editor.
+ *
+ * @return the servicesRegistry The registry.
+ */
+ public ServicesRegistry getServicesRegistry() {
+ if(servicesRegistry == null) {
+ servicesRegistry = createServicesRegistry();
+ }
+ return servicesRegistry;
+ }
+
+ /**
+ * Create the ServicesRegistry.
+ *
+ * @return
+ */
+ private ServicesRegistry createServicesRegistry() {
+ // Create Services Registry
+ try {
+ ServicesRegistry servicesRegistry = new ExtensionServicesRegistry(Activator.PLUGIN_ID);
+// servicesRegistry.startRegistry();
+ return servicesRegistry;
+ } catch (ServiceException e) {
+ // Show log and error
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * Do nothing as we create the provider before any calls to this method.
+ * Should not be called by subclasses.
+ *
+ * @see org.eclipse.papyrus.sasheditor.editor.AbstractMultiPageSashEditor#createPageProvider()
+ */
+ @Override
+ protected ISashWindowsContentProvider createPageProvider() {
+ throw new UnsupportedOperationException("Not implemented. Should not be called as the ContentProvider is already initialized.");
+ }
+
+ /**
+ * Create the pageContentProvider.
+ *
+ * @param pageFactory
+ * @param diResource
+ * Resource used to load/save the SashModel.
+ */
+ protected ISashWindowsContentProvider createPageProvider(IPageModelFactory pageFactory, Resource diResource, TransactionalEditingDomain editingDomain) {
+
+ sashModelMngr = new TransactionalDiSashModelMngr(pageFactory, diResource, editingDomain);
+
+ ISashWindowsContentProvider pageProvider = sashModelMngr.getISashWindowsContentProvider();
+
+ return pageProvider;
+ }
+
+ /**
+ * Get The {@link IPageMngr} used to add, open, remove or close a diagram in the
+ * SashWindow.
+ * This method is available as soon as the {@link CoreMultiDiagramEditor#init(IEditorSite, IEditorInput)} method is called.
+ *
+ * @return
+ */
+ protected IPageMngr getIPageMngr() throws IllegalStateException {
+ try {
+ return sashModelMngr.getIPageMngr();
+ } catch (Exception e) {
+ throw new IllegalStateException("Method should be called after CoreMultiDiagramEditor#init(IEditorSite, IEditorInput) is called");
+ }
+ }
+
+ /**
+ * Get the ActionBarContributorRegistry. Creates it if necessary.
+ *
+ * @return
+ */
+ protected ActionBarContributorRegistry getActionBarContributorRegistry() {
+ if(actionBarContributorRegistry != null) {
+ return actionBarContributorRegistry;
+ }
+
+ // Try to got it from CoreComposedActionBarContributor
+ // The ActionBarContributorRegistry is initialized by the Contributor.
+ // Get it from the contributor.
+ IEditorActionBarContributor contributor = getEditorSite().getActionBarContributor();
+ if(contributor instanceof CoreComposedActionBarContributor) {
+ log.info(getClass().getSimpleName() + " - ActionBarContributorRegistry loaded from CoreComposedActionBarContributor.");
+ return ((CoreComposedActionBarContributor)contributor).getActionBarContributorRegistry();
+ } else {
+ // Create a registry.
+ log.info(getClass().getSimpleName() + " - create an ActionBarContributorRegistry.");
+ return createActionBarContributorRegistry();
+ }
+
+ }
+
+ /**
+ * Create the ActionBarContributorRegistry.
+ *
+ * @return
+ */
+ private ActionBarContributorRegistry createActionBarContributorRegistry() {
+ return new ActionBarContributorRegistry(Activator.PLUGIN_ID);
+ }
+
+ /**
+ *
+ *
+ * @param adapter
+ *
+ * @return
+ */
+ @Override
+ public Object getAdapter(@SuppressWarnings("unchecked") Class adapter) {
+
+ if(ServicesRegistry.class == adapter) {
+ return getServicesRegistry();
+ }
+
+ if(IPageMngr.class == adapter) {
+ return getIPageMngr();
+ }
+
+ if(IPropertySheetPage.class == adapter) {
+ // Do not test if tabbedPropertySheetPage is null before calling new
+ // this is managed by Eclipse which only call current method when necessary
+ return getPropertySheetPage();
+ }
+
+ // Add a viewer
+ if(IContentOutlinePage.class == adapter) {
+ try {
+ IContentOutlinePage contentOutline = getContentOutlineRegistry().getContentOutline();
+ if(contentOutline != null) {
+ return contentOutline;
+ }
+ } catch (BackboneException e) {
+ // TODO change next exception to more appropriate one
+ throw new RuntimeException(e);
+ }
+ }
+
+ if(EditingDomain.class == adapter) {
+ return transactionalEditingDomain;
+ }
+
+ // EMF requirements
+ if(IEditingDomainProvider.class == adapter) {
+
+ // return (IEditingDomainProvider) defaultContext.getTransactionalEditingDomain().getResourceSet();
+ return domainProvider;
+ }
+
+ // GEF diagram requirements
+ if(adapter == ActionRegistry.class) {
+ return gefAdaptorDelegate.getActionRegistry();
+ }
+
+ // // GEF diagram requirements
+ // if (adapter == SelectionSynchronizer.class) {
+ // return gefAdaptorDelegate.getSelectionSynchronizer();
+ // }
+
+ // TODO : following code is GMF dependent. It should be moved to adapter
+ // Do we really need it? Who use it ?
+ if(adapter == IDiagramGraphicalViewer.class) {
+ IEditorPart activeEditor = getActiveEditor();
+ if(activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor)activeEditor).getDiagramGraphicalViewer();
+ }
+ return null;
+ }
+
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Init the editor.
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+
+ // Init super
+ super.init(site, input);
+
+ // Used to get the appropriate domain object from a graphical object (EditPart, ...)
+ BusinessModelResolver.getInstance();
+
+ // Load resources
+ IFile file = ((IFileEditorInput)input).getFile();
+ resourceSet.loadResources(file);
+
+ // Create the 2 edit domains
+ transactionalEditingDomain = resourceSet.getTransactionalEditingDomain();
+
+ // Create Gef adaptor
+ gefAdaptorDelegate = new MultiDiagramEditorGefDelegate();
+
+
+ // Create ServicesRegistry and register services
+ servicesRegistry = createServicesRegistry();
+
+ // Create lifeCycle event provider.
+ lifeCycleEventsProvider = new LifeCycleEventsProvider();
+ lifeCycleEvent = new DoSaveEvent(servicesRegistry, this);
+ servicesRegistry.add(ILifeCycleEventsProvider.class, 1, lifeCycleEventsProvider);
+
+ // register services
+ servicesRegistry.add(ActionBarContributorRegistry.class, 1, getActionBarContributorRegistry());
+ servicesRegistry.add(TransactionalEditingDomain.class, 1, transactionalEditingDomain);
+ servicesRegistry.add(DiResourceSet.class, 1, resourceSet);
+
+ // Create and initalize editor icons service
+ PageIconsRegistry pageIconsRegistry = new PageIconsRegistry();
+ PluggableEditorFactoryReader editorReader = new PluggableEditorFactoryReader(Activator.PLUGIN_ID);
+ editorReader.populate(pageIconsRegistry);
+ servicesRegistry.add(IPageIconsRegistry.class, 1, pageIconsRegistry);
+
+
+ // Create PageModelRegistry requested by content provider.
+ // Also populate it from extensions.
+ PageModelFactoryRegistry pageModelRegistry = new PageModelFactoryRegistry();
+ editorReader.populate(pageModelRegistry, servicesRegistry);
+
+ // TODO : create appropriate Resource for the contentProvider, and pass it here.
+ // This will allow to remove the old sash stuff.
+ setContentProvider(createPageProvider(pageModelRegistry, resourceSet.getDiResource(), transactionalEditingDomain));
+ servicesRegistry.add(ISashWindowsContentProvider.class, 1, getContentProvider());
+ servicesRegistry.add(IPageMngr.class, 1, getIPageMngr());
+
+
+ // Start servicesRegistry
+ servicesRegistry.startRegistry();
+
+ // Listen to the modifications of the EMF model
+ transactionalEditingDomain.getCommandStack().addCommandStackListener(commandStackListener);
+
+ // Let's listen to the resource set change
+ transactionalEditingDomain.addResourceSetListener(resourceSetListener);
+
+ // Set editor name
+ setPartName(file.getName());
+
+ // Listen on contentProvider changes
+ sashModelMngr.getSashModelContentChangedProvider().addContentChangedListener(contentChangedListener);
+ }
+
+ /**
+ * Overrides getPropertySheetPage.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.core.editor.IMultiDiagramEditor#getPropertySheetPage()
+ */
+ public IPropertySheetPage getPropertySheetPage() {
+ if(this.tabbedPropertySheetPage == null) {
+ this.tabbedPropertySheetPage = new TabbedPropertySheetPage(this);
+ }
+ return tabbedPropertySheetPage;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.sasheditor.editor.AbstractMultiPageSashEditor#dispose()
+ *
+ */
+ @Override
+ public void dispose() {
+ if(sashModelMngr != null) {
+ sashModelMngr.getSashModelContentChangedProvider().removeContentChangedListener(contentChangedListener);
+ }
+
+ if(transactionalEditingDomain != null) {
+ transactionalEditingDomain.getCommandStack().removeCommandStackListener(commandStackListener);
+ transactionalEditingDomain.removeResourceSetListener(resourceSetListener);
+ }
+
+ // Avoid memory leak
+ if(resourceSet != null) {
+ resourceSet.unload();
+ }
+
+ // dispose available service
+ if(servicesRegistry != null)
+ {
+ servicesRegistry.disposeService();
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * Overrides doSave.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+
+ // Sent pre doSave event
+ lifeCycleEventsProvider.fireAboutToDoSaveEvent(lifeCycleEvent);
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.fireDoSaveEvent(lifeCycleEvent);
+ // Perform local doSave
+ // TODO : put it in a listener ?
+ try {
+ // Save each associated resource
+ resourceSet.save(monitor);
+ markSaveLocation();
+ } catch (IOException e) {
+ log.error("Error during save", e);
+ }
+
+ // Sent post Events
+ lifeCycleEventsProvider.firePostDoSaveEvent(lifeCycleEvent);
+
+ }
+
+ /**
+ * Mark the command stack of all sub-editors. Default implementation do nothing.
+ */
+ @Override
+ protected void markSaveLocation() {
+ ((BasicCommandStack)transactionalEditingDomain.getCommandStack()).saveIsDone();
+ super.markSaveLocation();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDirty() {
+ // First, look if the model part (EMF) is dirty, else look at the Graphical part (GEF/GMF)
+ return ((BasicCommandStack)transactionalEditingDomain.getCommandStack()).isSaveNeeded() || super.isDirty();
+ }
+
+ /**
+ * Overrides doSaveAs.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#doSaveAs()
+ */
+ @Override
+ public void doSaveAs() {
+
+ // Sent pre doSave event
+ lifeCycleEventsProvider.fireAboutToDoSaveAsEvent(lifeCycleEvent);
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.fireDoSaveAsEvent(lifeCycleEvent);
+ // Perform local doSaveAs
+
+
+ // Show a SaveAs dialog
+ Shell shell = getEditorSite().getWorkbenchWindow().getShell();
+ SaveAsDialog dialog = new SaveAsDialog(shell);
+ dialog.setOriginalFile(((IFileEditorInput)getEditorInput()).getFile());
+ dialog.open();
+ final IPath path = dialog.getResult();
+ if(path != null) {
+ // try to save the editor's contents under a different file name
+ final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ try {
+ new ProgressMonitorDialog(shell).run(false, // don't fork
+ false, // not cancelable
+ new WorkspaceModifyOperation() { // run this operation
+
+ @Override
+ public void execute(final IProgressMonitor monitor) {
+ try {
+ resourceSet.saveAs(path);
+ } catch (IOException e) {
+ log.error("Unable to saveAs the resource set", e);
+ }
+ }
+ });
+ // set input to the new file
+ setInput(new FileEditorInput(file));
+ markSaveLocation();
+ } catch (InterruptedException e) {
+ // should not happen, since the monitor dialog is not cancelable
+ log.error(e);
+ } catch (InvocationTargetException e) {
+ log.error(e);
+ }
+ }
+
+ // sent doSaveEvent
+ lifeCycleEventsProvider.firePostDoSaveAsEvent(lifeCycleEvent);
+
+ }
+
+ /**
+ * Overrides isSaveAsAllowed.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed()
+ */
+ @Override
+ public boolean isSaveAsAllowed() {
+ return true;
+ }
+
+ /**
+ * Overrides getContributorId.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor#getContributorId()
+ */
+ public String getContributorId() {
+ // return Activator.PLUGIN_ID;
+ return "TreeOutlinePage";
+
+ }
+
+ // implements IDiagramWorkbenchPart to restore GMF standard behavior
+ // and delegate to the activeEditor
+
+ /**
+ * Overrides getDiagram.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart#getDiagram()
+ */
+ public org.eclipse.gmf.runtime.notation.Diagram getDiagram() {
+ IEditorPart activeEditor = getActiveEditor();
+ if(activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor)activeEditor).getDiagram();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * This method is called from a GMF diagram. It should only be called from GMF diagram code. Normally, the Diagram under the Mouse is a GMF
+ * Diagram. The active Diagram can be another Diagram, not
+ * under the mouse. This is a GMF issue.
+ */
+ public DiagramEditPart getDiagramEditPart() {
+
+ // Get the editor under the mouse
+ // IEditorPart activeEditor = rootContainer.getEditorUnderMouse();
+ IEditorPart activeEditor = getActiveEditor();
+ if(activeEditor == null) {
+ return null;
+ }
+ // IEditorPart activeEditor = getActiveEditor();
+ if(activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor)activeEditor).getDiagramEditPart();
+ } else {
+ // This case should never happen.
+ // Return null, as the GMF runtime now support it (since 093009)
+ return null;
+ }
+ }
+
+ /**
+ * Overrides getDiagramGraphicalViewer.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart#getDiagramGraphicalViewer()
+ */
+ public IDiagramGraphicalViewer getDiagramGraphicalViewer() {
+ IEditorPart activeEditor = getActiveEditor();
+ if(activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor)activeEditor).getDiagramGraphicalViewer();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Overrides getEditingDomain.
+ *
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.edit.domain.IEditingDomainProvider#getEditingDomain()
+ */
+ public EditingDomain getEditingDomain() {
+ return transactionalEditingDomain;
+ }
+
+ /**
+ * Throws an UnsupportedOperationException.
+ *
+ * @see org.eclipse.papyrus.core.editor.IMultiDiagramEditor#getDiagramEditDomain()
+ */
+ public DiagramEditDomain getDiagramEditDomain() {
+ throw new UnsupportedOperationException("Not implemented. Should not be called.");
+ }
+
+
+ /**
+ * Change the editor input.<BR>
+ * <U>Note</U>: that method should be called within the UI-Thread.
+ *
+ * @see org.eclipse.papyrus.core.editor.IMultiDiagramEditor#setEditorInput(org.eclipse.ui.IEditorInput)
+ *
+ * @param newInput
+ * The new input
+ */
+
+ public void setEditorInput(IEditorInput newInput) {
+ setInputWithNotify(newInput);
+ setPartName(newInput.getName());
+ markSaveLocation();
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/IMultiDiagramEditor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/IMultiDiagramEditor.java
new file mode 100644
index 00000000000..761da8d3e56
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editor/IMultiDiagramEditor.java
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.editor;
+
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+
+/**
+ * Interface implemented by the main multipage editor. This interface list the methods available to diagram editors. Diagram editors can relies on
+ * this interface to retrieve services from the main
+ * multi diagram editor.
+ *
+ * @author dumoulin
+ *
+ */
+public interface IMultiDiagramEditor extends IEditorPart, IEditingDomainProvider {
+
+ /**
+ * Returns the service registry associated to the editor.
+ *
+ * @return the servicesRegistry The registry.
+ */
+ public ServicesRegistry getServicesRegistry();
+
+
+ /**
+ * Return the editor site.
+ *
+ * @return
+ */
+ public IEditorSite getEditorSite();
+
+ /**
+ * Get the editor input.
+ *
+ * @return
+ */
+ public IEditorInput getEditorInput();
+
+ /**
+ * Change the editor input.
+ *
+ * @param newInput The new input.
+ */
+ public void setEditorInput(IEditorInput newInput);
+
+ /**
+ * Returns the edit domain shared among editors
+ *
+ * @return the edit domain shared among editors
+ */
+ // FIXME Remove it (GMF dependency)
+ public DiagramEditDomain getDiagramEditDomain();
+
+ /**
+ * Get the currently active Editor.
+ */
+ public IEditorPart getActiveEditor();
+
+ /**
+ * Get the property sheet page associated to the Editor.
+ *
+ * @return the property sheet page associated to the Editor.
+ */
+ public IPropertySheetPage getPropertySheetPage();
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorFactory.java
new file mode 100644
index 00000000000..33ca891f634
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorFactory.java
@@ -0,0 +1,40 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.editorsfactory;
+
+import org.eclipse.papyrus.sasheditor.contentprovider.IPageModel;
+
+
+
+/**
+ * Factory used to get the Icon associated to the editor used to render the specified pageIdentifier.
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface IEditorFactory {
+
+ /**
+ * Create the {@link IPageModel} for the specified identifier.
+ * TODO throw an exception encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * Object identifying an Editor.
+ * @return PageModel allowing to create the editor.
+ */
+ public IPageModel createIPageModel(Object pageIdentifier);
+
+ /**
+ * Return true if the factory can create an IPageModel for the specified pageIdentifier.
+ * Return false otherwise
+ * TODO throw an exception encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * The object representing the page to test
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier);
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorIconFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorIconFactory.java
new file mode 100644
index 00000000000..ba74f7104bd
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IEditorIconFactory.java
@@ -0,0 +1,60 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.editorsfactory;
+
+import org.eclipse.papyrus.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.DiSashModelMngr;
+import org.eclipse.papyrus.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.swt.graphics.Image;
+
+
+
+/**
+ * Factory used to create an {@link IPageModel} used by the {@link ISashWindowsContainer} to create
+ * an instance of the editor represented by the provided Object.
+ * Such factory is required by the {@link DiSashModelMngr}. It is called whenever the ISashWindowsContainer
+ * need to create an editor from an EObject representing this editor in the Di implementation of the
+ * {@link ISashWindowsContentProvider}
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface IEditorIconFactory {
+
+ /**
+ * Get the icon associated to the editor used to render the model. Model represent the top level
+ * object of a model editor.
+ * Can return a cached Image.
+ *
+ * @param pageIdentifier
+ * the pageIdentifier representing the Editor. This is usually the EObject used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image getEditorIcon(Object pageIdentifier);
+
+ /**
+ * Create the icon associated to the editor used to render the model. Model represent the top level
+ * object of a model editor.
+ * Always return a newly created Image.
+ *
+ * @param pageIdentifier
+ * the pageIdentifier representing the Editor. This is usually the EObject used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image createEditorIcon(Object pageIdentifier);
+
+ /**
+ * Return true if the factory can create an IPageModel for the specified pageIdentifier.
+ * Return false otherwise
+ * TODO throw an exception encapsulating problems encountered while creating the model.
+ *
+ * @param pageIdentifier
+ * The object representing the page to test
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier);
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IPageIconsRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IPageIconsRegistry.java
new file mode 100644
index 00000000000..f7cc243f319
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/IPageIconsRegistry.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.editorsfactory;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Registry used to get Icons associated to an editor.
+ *
+ * @author cedric dumoulin
+ */
+public interface IPageIconsRegistry {
+
+ /**
+ * Get the icon associated to the editor used to render the model. Model represent the top level
+ * object of a model editor.
+ *
+ * @param model
+ * the model representing the Editor. This is usually the EObject used to reconstruct the editor.
+ * @return the icon representing the editor
+ */
+ public Image getEditorIcon(Object model);
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageIconsRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageIconsRegistry.java
new file mode 100644
index 00000000000..a50b164033b
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageIconsRegistry.java
@@ -0,0 +1,88 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.editorsfactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Concrete implementation of the {@link IPageIconsRegistry}.
+ * This implementation allows to add and remove {@link IPageIconsRegistry}.
+ *
+ *
+ * @author cedric dumoulin
+ */
+public class PageIconsRegistry implements IPageIconsRegistry {
+
+ /** list of registered icon factories */
+ protected List<IEditorIconFactory> pageIcons = new ArrayList<IEditorIconFactory>();
+
+
+ /**
+ * Constructor.
+ *
+ * @param editorFactoryRegistry
+ * @param servicesRegistry
+ */
+ public PageIconsRegistry() {
+
+ }
+
+ /**
+ * Walk each registered {@link IEditorFactory} to find the one handling the specified pageIdentifier.
+ * Call the corresponding method in the found pageIdentifier.
+ *
+ * TODO Throw an exception to report errors.
+ *
+ * @see org.eclipse.papyrus.sasheditor.contentprovider.di.IPageModelFactory#createIPageModel(java.lang.Object)
+ */
+ public Image getEditorIcon(Object pageIdentifier) {
+
+ for(IEditorIconFactory factory : getPageIcons()) {
+ if(factory.isPageModelFactoryFor(pageIdentifier)) {
+ {
+ // return factory.getEditorIcon(pageIdentifier);
+ return factory.createEditorIcon(pageIdentifier);
+ }
+ }
+ }
+ // no editor found !
+ // TODO Throw an exception.
+ // throw new EditorNotFoundException("No editor registered for '" + pageIdentifier + "'.");
+ return null;
+ }
+
+
+ /**
+ * @return the editorFactories
+ */
+ protected List<IEditorIconFactory> getPageIcons() {
+ return pageIcons;
+ }
+
+ /**
+ * Add the specified {@link IEditorFactory}
+ *
+ * @param editorIconFactory
+ */
+ public void add(IEditorIconFactory editorIconFactory) {
+ // This should never happen
+ if(editorIconFactory == null)
+ throw new RuntimeException("Parameter should not be null.");
+
+ pageIcons.add(editorIconFactory);
+ }
+
+ /**
+ * Remove the specified {@link IEditorFactory}
+ *
+ * @param editorIconFactory
+ */
+ public void remove(IEditorIconFactory editorIconFactory) {
+ pageIcons.remove(editorIconFactory);
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageModelFactoryRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageModelFactoryRegistry.java
new file mode 100644
index 00000000000..cae06ff8d3b
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/editorsfactory/PageModelFactoryRegistry.java
@@ -0,0 +1,90 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.editorsfactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.sasheditor.contentprovider.IPageModel;
+import org.eclipse.papyrus.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.IPageModelFactory;
+
+
+/**
+ * Concrete implementation of the {@link IPageModelFactory} required by the di implementation of
+ * {@link ISashWindowsContentProvider}.
+ * This implementation allows to add and remove {@link IEditorFactory}.
+ *
+ *
+ * @author cedric dumoulin
+ */
+public class PageModelFactoryRegistry implements IPageModelFactory {
+
+ /** list of editor factories */
+ protected List<IEditorFactory> editorFactories = new ArrayList<IEditorFactory>();
+
+
+ /**
+ * Constructor.
+ *
+ * @param editorFactoryRegistry
+ * @param servicesRegistry
+ */
+ public PageModelFactoryRegistry() {
+
+ }
+
+ /**
+ * Walk each registered {@link IEditorFactory} to find the one handling the specified pageIdentifier.
+ * Call the corresponding method in the found pageIdentifier.
+ *
+ * TODO Throw an exception to report errors.
+ *
+ * @see org.eclipse.papyrus.sasheditor.contentprovider.di.IPageModelFactory#createIPageModel(java.lang.Object)
+ */
+ public IPageModel createIPageModel(Object pageIdentifier) {
+
+ for(IEditorFactory factory : getEditorFactories()) {
+ if(factory.isPageModelFactoryFor(pageIdentifier)) {
+ {
+ return factory.createIPageModel(pageIdentifier);
+ }
+ }
+ }
+ // no editor found !
+ // TODO Throw an exception.
+ // throw new EditorNotFoundException("No editor registered for '" + pageIdentifier + "'.");
+ return null;
+ }
+
+
+ /**
+ * @return the editorFactories
+ */
+ protected List<IEditorFactory> getEditorFactories() {
+ return editorFactories;
+ }
+
+ /**
+ * Add the specified {@link IEditorFactory}
+ * @param editorFactory
+ */
+ public void add(IEditorFactory editorFactory)
+ {
+ // This should never happen
+ if( editorFactory==null)
+ throw new RuntimeException("Parameter should not be null.");
+
+ editorFactories.add(editorFactory);
+ }
+
+ /**
+ * Remove the specified {@link IEditorFactory}
+ * @param editorFactory
+ */
+ public void remove(IEditorFactory editorFactory)
+ {
+ editorFactories.remove(editorFactory);
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadClassNameException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadClassNameException.java
new file mode 100644
index 00000000000..b8022b1c040
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadClassNameException.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * Exception thrown as an extension point is parsed at runtime. More accurately, it is thrown when one attribute of an extension point that should
+ * describe a class name does not correspond to a class
+ * in the classpath.
+ *
+ * @author Cedric Dumoulin
+ * @author Patrick Tessier
+ * @author schnekenburger
+ */
+public class BadClassNameException extends ExtensionException {
+
+ /**
+ * the name of{@link IConfigurationElement} that is bad build
+ */
+ private String iconfigurationElementName;
+
+ /**
+ * the name of the attribute of the {@link IConfigurationElement}
+ */
+ private String attributeName;
+
+ private Exception e = null;
+
+ /**
+ * serial version UID
+ *
+ * @generated
+ */
+ private static final long serialVersionUID = 1161426240944647521L;
+
+ /**
+ * constructor with an exception
+ *
+ * @param element
+ * the IConfigurationElement that raised the error
+ * @param attributeName
+ * the bad construct attibute
+ * @param e
+ * the associated exception
+ */
+ public BadClassNameException(String msg, String iConfigurationElementName, String attributeName, final Exception e) {
+ super(msg);
+ this.iconfigurationElementName = iConfigurationElementName;
+ this.attributeName = attributeName;
+ this.e = e;
+ }
+
+ /**
+ * constructor without an exception
+ *
+ * @param element
+ * the IConfigurationElement that raised the error
+ * @param attributeName
+ * the bad construct attibute
+ */
+ public BadClassNameException(String msg, String iConfigurationElementName, String attributeName) {
+ super(msg);
+ this.iconfigurationElementName = iConfigurationElementName;
+ this.attributeName = attributeName;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return super.toString() + " for the extension point " + iconfigurationElementName + "." + attributeName + " " + e;
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadNameExtensionException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadNameExtensionException.java
new file mode 100644
index 00000000000..d7d5ad6629b
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/BadNameExtensionException.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension;
+
+/**
+ * Exception thrown when a bad name is encountered in extension processing.
+ *
+ * @author dumoulin
+ * @author schnekenburger
+ */
+public class BadNameExtensionException extends ExtensionException {
+
+ /**
+ * serial version UID
+ *
+ * @generated
+ */
+ private static final long serialVersionUID = -2063118856033217385L;
+
+ /**
+ * Creates a simple BadNameExtensionException
+ */
+ public BadNameExtensionException() {
+ }
+
+ /**
+ * Creates a BadNameExtensionException with a specific message.
+ *
+ * @param message
+ * the message of the exception
+ */
+ public BadNameExtensionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a BadNameExtensionException with a specific cause.
+ *
+ * @param cause
+ * the cause of the exception
+ */
+ public BadNameExtensionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a BadNameExtensionException with a specific cause and a specific message.
+ *
+ * @param message
+ * the message of the exception
+ * @param cause
+ * the cause of the exception
+ */
+ public BadNameExtensionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/DescriptorExtensionFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/DescriptorExtensionFactory.java
new file mode 100644
index 00000000000..88b3793b5aa
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/DescriptorExtensionFactory.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) patrick.tessier@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+
+/**
+ * This is a factory in charge to create descriptor
+ *
+ * @author Patrick Tessier
+ */
+public abstract class DescriptorExtensionFactory {
+
+ /**
+ * used to verify if the name of the {@link IConfigurationElement} is the same as the given name
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @param tagName
+ * the name of the {@link IConfigurationElement} that has to be verified
+ * @throws InvalidRegistryObjectException
+ * @throws BadNameExtensionException
+ */
+ protected void checkTagName(IConfigurationElement element, String tagName) throws BadNameExtensionException {
+ String name = element.getName();
+ if(!tagName.equals(name))
+ throw new BadNameExtensionException("Expected '" + tagName + "', found '" + name + "'.");
+ }
+
+ /**
+ * Retrieves the value of a specific attribute in a configuration element
+ *
+ * @param element
+ * the configuration element to parse
+ * @param attributeName
+ * the name of the attribute to read
+ * @param extensionPointName
+ * Name of the extension point. Used in exception msg. TODO: remove ?
+ *
+ * @return the class, result of the parsing
+ * @throws InvalidRegistryObjectException
+ * @throws BadClassNameException
+ */
+ protected Class<?> parseClass(IConfigurationElement element, String attributeName, String extensionPointName) throws BadClassNameException {
+ String className = element.getAttribute(attributeName);
+
+ element.getContributor().getName();
+ if(className == null || className.length() == 0) {
+ throw new BadClassNameException(attributeName + "=null ", extensionPointName, attributeName);
+ }
+ Class<?> factoryClass;
+ try {
+ factoryClass = Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ // try another way
+ try {
+ String declaringID = element.getContributor().getName();
+ Bundle bundle = Platform.getBundle(declaringID);
+ factoryClass = bundle.loadClass(className);
+ } catch (ClassNotFoundException e1) {
+ throw new BadClassNameException(className + " can not be loaded ", extensionPointName, attributeName, e1);
+ }
+ }
+ return factoryClass;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/ExtensionException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/ExtensionException.java
new file mode 100644
index 00000000000..1e1b77ec107
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/ExtensionException.java
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.core.editor.BackboneException;
+
+/**
+ * Base class for extension exceptions
+ *
+ * @author dumoulin
+ * @author schnekenburger
+ */
+public class ExtensionException extends BackboneException {
+
+ /**
+ * serial version UID
+ *
+ * @generated
+ */
+ private static final long serialVersionUID = -9144153309491137046L;
+
+ /**
+ * Creates a simple ExtensionException.
+ */
+ public ExtensionException() {
+ }
+
+ /**
+ * Creates a ExtensionException with a specific message.
+ *
+ * @param message
+ * the message of the exception
+ */
+ public ExtensionException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a ExtensionException with a specific cause.
+ *
+ * @param cause
+ * the cause of the exception
+ */
+ public ExtensionException(Throwable cause) {
+ super(cause);
+
+ }
+
+ /**
+ * Creates a ExtensionException with a specific cause and a specific message.
+ *
+ * @param message
+ * the message of the exception
+ * @param cause
+ * the cause of the exception
+ */
+ public ExtensionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Return the name of the plugin and extension declaring the extension.
+ *
+ * @param element
+ * the configuration element corresponding to the extension
+ * @return a string containing the name of the plugin and the name of the extension
+ */
+ protected static String declaringExtensionToString(IConfigurationElement element) {
+ return "plugin:" + element.getContributor().getName() + " extension:" + element.getName();
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/NotFoundException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/NotFoundException.java
new file mode 100644
index 00000000000..9df2e493000
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/NotFoundException.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension;
+
+/**
+ * Exception thrown when something is not found when parsing a configuration element.
+ *
+ * @author dumoulin
+ * @author schnekenburger
+ */
+public class NotFoundException extends ExtensionException {
+
+ /**
+ * serial version UID
+ *
+ * @generated
+ */
+ private static final long serialVersionUID = -130754574538610199L;
+
+ /**
+ * Creates a simple NotFoundException.
+ */
+ public NotFoundException() {
+ }
+
+ /**
+ * Creates a NotFoundException with a specific message.
+ *
+ * @param message
+ * the message of the exception
+ */
+ public NotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a NotFoundException with a specific cause.
+ *
+ * @param cause
+ * the cause of the exception
+ */
+ public NotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Creates a NotFoundException with a specific cause and a specific message.
+ *
+ * @param message
+ * the message of the exception
+ * @param cause
+ * the cause of the exception
+ */
+ public NotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandDescriptor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandDescriptor.java
new file mode 100644
index 00000000000..dd8ed70d77e
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandDescriptor.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jerome Benois (Obeo) jerome.benois@obeo.fr - initial API and implementation
+ * Tristan Faure (Atos Origin) tristan.faure@atosorigin.com - add condition to the create command (task #296902)
+ *******************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.core.editor.BackboneException;
+
+/**
+ * Creation Command Descriptor used to create a new diagram
+ *
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public class CreationCommandDescriptor {
+
+ protected Class<? extends ICreationCommand> creationCommandClass;
+
+ protected String commandId;
+
+ protected String label;
+
+ protected String modelFileExtension;
+
+ protected ImageDescriptor icon;
+
+ private ICreationCondition condition;
+
+ public String getCommandId() {
+ return commandId;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getModelFileExtension() {
+ return modelFileExtension;
+ }
+
+ public ImageDescriptor getIcon() {
+ return icon;
+ }
+
+ public ICreationCondition getCondition() {
+ return condition;
+ }
+
+ public void setCondition(ICreationCondition condition) {
+ this.condition = condition;
+ condition.setCommand(getCommandId());
+
+ }
+
+ /**
+ * Instance is created when requested.
+ */
+ protected ICreationCommand instance = null;
+
+ /**
+ * constructor.
+ *
+ * @return the creation command
+ * @throws BackboneException
+ */
+ protected ICreationCommand getCommand() throws BackboneException {
+ if(instance == null)
+ instance = createCommand();
+
+ return instance;
+ }
+
+ private ICreationCommand createCommand() throws BackboneException {
+ try {
+ ICreationCommand command = creationCommandClass.newInstance();
+ return command;
+ } catch (SecurityException e) {
+ // Lets propagate. This is an implementation problem that should be solved by
+ // programmer.
+ throw new RuntimeException(e);
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be solved by
+ // programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be solved by
+ // programmer.
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandExtensionFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandExtensionFactory.java
new file mode 100644
index 00000000000..2200eba8c7f
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandExtensionFactory.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jerome Benois (Obeo) jerome.benois@obeo.fr - initial API and implementation
+ * Tristan Faure (Atos Origin) tristan.faure@atosorigin.com - add condition to the create command (task #296902)
+ *******************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.core.extension.BadNameExtensionException;
+import org.eclipse.papyrus.core.extension.DescriptorExtensionFactory;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.papyrus.core.utils.IDebugChannel;
+import org.eclipse.papyrus.core.utils.PapyrusTrace;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * A factory used to create CreationCommand object from Eclipse extensions points elements.
+ *
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public class CreationCommandExtensionFactory extends DescriptorExtensionFactory {
+
+ /** singleton eINSTANCE of this class */
+ public final static CreationCommandExtensionFactory eINSTANCE = new CreationCommandExtensionFactory();
+
+ /** constant for the creation command **/
+ public final static String CREATION_COMMAND_EXTENSIONPOINT = "creationCommand";
+
+ /** constant for the attribute creationCommandClass **/
+ public final static String CREATION_COMMAND_CLASS_ATTR = "creationCommandClass";
+
+ /** constant for the attribute creationCommandClass **/
+ public final static String CONDITION_COMMAND_CLASS_ATTR = "creationCondition";
+
+ /** constant for the attribute label **/
+ public final static String LABEL_ATTR = "label";
+
+ /** constant for the attribute contextId **/
+ public final static String ID_ATTRIBUTE = "id";
+
+ /** constant for the attribute icon **/
+ public final static String ICON_ATTR = "icon";
+
+ /** constant for the attribute modelFileExtension **/
+ public final static String MODEL_FILE_EXTENSION_ATTR = "modelFileExtension";
+
+ /**
+ * @return the eINSTANCE
+ */
+ public static CreationCommandExtensionFactory getInstance() {
+ return eINSTANCE;
+ }
+
+ /**
+ * Create a CreationCommand instance corresponding to the ConfigurationElement.
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @return a CreationCommandDescriptor structure that contains information to the creation
+ * diagram command
+ * @throws BadNameExtensionException
+ **/
+ public CreationCommandDescriptor createCreationCommand(IConfigurationElement element) throws ExtensionException {
+ CreationCommandDescriptor res;
+ checkTagName(element, CREATION_COMMAND_EXTENSIONPOINT);
+ res = new CreationCommandDescriptor();
+ res.creationCommandClass = (Class<ICreationCommand>)parseClass(element, CREATION_COMMAND_CLASS_ATTR, CREATION_COMMAND_EXTENSIONPOINT);
+ res.commandId = element.getAttribute(ID_ATTRIBUTE);
+ res.label = element.getAttribute(LABEL_ATTR);
+ res.modelFileExtension = element.getAttribute(MODEL_FILE_EXTENSION_ATTR);
+ String iconPath = element.getAttribute(ICON_ATTR);
+ if(iconPath != null) {
+ res.icon = AbstractUIPlugin.imageDescriptorFromPlugin(element.getNamespaceIdentifier(), iconPath);
+ }
+ String attributeForCreationCondition = element.getAttribute(CONDITION_COMMAND_CLASS_ATTR);
+ if(attributeForCreationCondition != null && attributeForCreationCondition.length() > 0) {
+ Class<ICreationCondition> classCondition = (Class<ICreationCondition>)parseClass(element, CONDITION_COMMAND_CLASS_ATTR, CREATION_COMMAND_EXTENSIONPOINT);
+ if(classCondition != null) {
+ try {
+ res.setCondition(classCondition.newInstance());
+ } catch (InstantiationException e) {
+ throw new ExtensionException("can nott instantiate class : " + e.getMessage());
+ } catch (IllegalAccessException e) {
+ throw new ExtensionException("can nott acces to class : " + e.getMessage());
+ }
+ }
+ }
+ PapyrusTrace.trace(IDebugChannel.PAPYRUS_EXTENSIONPOINT_LOADING, this, "a creation command ready " + res);
+
+ return res;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandRegistry.java
new file mode 100644
index 00000000000..918330ae3a2
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/CreationCommandRegistry.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jerome Benois (Obeo) jerome.benois@obeo.fr - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.core.Activator;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.papyrus.core.extension.NotFoundException;
+import org.eclipse.papyrus.core.utils.IDebugChannel;
+import org.eclipse.papyrus.core.utils.PapyrusTrace;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public class CreationCommandRegistry implements ICreationCommandRegistry {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusDiagram";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /**
+ * The icon representing the command
+ */
+ private String icon;
+
+ /**
+ * Registered creation command descriptors.
+ */
+ private Map<Object, CreationCommandDescriptor> creationCommandDescriptors;
+
+ public CreationCommandRegistry(String extensionPointNamespace) {
+ this.extensionPointNamespace = extensionPointNamespace;
+ initializeCreationCommandDescriptors();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<CreationCommandDescriptor> getCommandDescriptors() {
+ return creationCommandDescriptors.values();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws NotFoundException
+ */
+ public ICreationCommand getCommand(String commandId) throws NotFoundException {
+ try {
+ CreationCommandDescriptor desc = creationCommandDescriptors.get(commandId);
+ return desc.getCommand();
+ } catch (Exception e) {
+ throw new NotFoundException("No creation command registered under id '" + commandId + "'.");
+ }
+ }
+
+ /**
+ * get the command icon path
+ *
+ * @return the editor icon path
+ */
+ public String getIcon() {
+ return icon;
+ }
+
+ /**
+ * set the command icon
+ *
+ * @param icon
+ * the icon path
+ */
+ public void setIcon(String icon) {
+ this.icon = icon;
+ }
+
+ /**
+ * Read command descriptors from extension points.
+ */
+ private void initializeCreationCommandDescriptors() {
+
+ creationCommandDescriptors = new HashMap<Object, CreationCommandDescriptor>();
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+
+ CreationCommandExtensionFactory extensionReader = new CreationCommandExtensionFactory();
+
+ for(IConfigurationElement ele : configElements) {
+ CreationCommandDescriptor desc;
+ try {
+ if(CreationCommandExtensionFactory.CREATION_COMMAND_EXTENSIONPOINT.equals(ele.getName())) {
+ desc = extensionReader.createCreationCommand(ele);
+ creationCommandDescriptors.put(desc.commandId, desc);
+ }
+ } catch (ExtensionException e) {
+ Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage(), e));
+ PapyrusTrace.error(IDebugChannel.PAPYRUS_EXTENSIONPOINT_LOADING, this, "Initialization creation command problem " + e);
+ }
+ }
+ PapyrusTrace.trace(IDebugChannel.PAPYRUS_EXTENSIONPOINT_LOADING, this, "" + creationCommandDescriptors.size() + " creationCommands loaded");
+
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommand.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommand.java
new file mode 100644
index 00000000000..477db19f06c
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommand.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jerome Benois (Obeo) jerome.benois@obeo.fr - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.core.utils.DiResourceSet;
+
+/**
+ * Define a command use to create new diagram. It use to provide Eclipse extension @see {@link PapyrusDiagram#creationCommand} It used by the creation
+ * model wizard.
+ *
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public interface ICreationCommand {
+
+ /**
+ * Create a new diagram in diResourceSet with the given name.
+ *
+ * @param diResourceSet
+ * the resourceSet containing all diagrams
+ * @param container
+ * of the diagram, if container is null, the diagram is contained by the top level container
+ * @param name
+ * the name of the new diagram
+ */
+ public void createDiagram(DiResourceSet diResourceSet, EObject container, String name);
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommandRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommandRegistry.java
new file mode 100644
index 00000000000..2fe0420d7f6
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCommandRegistry.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jerome Benois (Obeo) jerome.benois@obeo.fr - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import java.util.Collection;
+
+import org.eclipse.papyrus.core.extension.NotFoundException;
+
+/**
+ * Registry containing CreationCommand registered by Eclipse extension.
+ *
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ */
+public interface ICreationCommandRegistry {
+
+ /**
+ * Get all registered creation command descriptors
+ *
+ * @return collection of command descriptors
+ */
+ public Collection<CreationCommandDescriptor> getCommandDescriptors();
+
+ /**
+ * Get registered creation with given identifier
+ *
+ * @param commandId
+ * the command id
+ * @return the registered command
+ * @throws NotFoundException
+ * if command not registered
+ */
+ ICreationCommand getCommand(String commandId) throws NotFoundException;
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCondition.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCondition.java
new file mode 100644
index 00000000000..7d3cca6b894
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/ICreationCondition.java
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * Copyright (c) 2009 ATOS ORIGIN.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Tristan Faure (ATOS ORIGIN) tristan.faure@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import org.eclipse.emf.ecore.EObject;
+
+public interface ICreationCondition {
+
+ /**
+ * This method returns true if the diagram creation is allowed
+ *
+ * @param selectedElement
+ * the element where the diagram is provided
+ * @return true if the diagram can be created
+ */
+ boolean create(EObject selectedElement);
+ /**
+ * set the command ID in order to take account the environment in order to create a diagram
+ * @param commandID
+ */
+ public void setCommand(String commandID);
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/PerspectiveContextDependence.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/PerspectiveContextDependence.java
new file mode 100644
index 00000000000..385613ddd1d
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/commands/PerspectiveContextDependence.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.commands;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.core.extension.commands.ICreationCondition;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.Perspective;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+public class PerspectiveContextDependence implements ICreationCondition {
+
+ protected String commandID=null;
+ public PerspectiveContextDependence() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean create(EObject selectedElement) {
+ // Get the perspective
+ Perspective perspective = ((WorkbenchPage)PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()).getActivePerspective();
+ //look for the perspective
+ //verify if the commannd has to be displayed
+ if(perspective.getHiddenMenuItems().contains(commandID)&& perspective.getHiddenToolbarItems().contains(commandID)){
+ return false;
+ }
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public void setCommand(String commandID) {
+ this.commandID=commandID;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/AbstractEditorFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/AbstractEditorFactory.java
new file mode 100644
index 00000000000..bf6c8349ae6
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/AbstractEditorFactory.java
@@ -0,0 +1,110 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.papyrus.core.editorsfactory.IEditorFactory;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+
+/**
+ * Abstract base class for Factory of editors.
+ * See {@link IEditorFactory}.
+ *
+ *
+ * @author Remi Schnekenburger
+ * @author Patrick Tessier
+ * @author cedric dumoulin
+ */
+public abstract class AbstractEditorFactory implements IPluggableEditorFactory {
+
+ /**
+ * Expected Class of the diagram to create.
+ */
+ private Class<?> diagramClass;
+
+ /** Expected diagram type (@see {@link Diagram#getType()}) */
+ private String expectedType;
+
+ /**
+ * EditorDescriptor associated to the factory.
+ * TODO : Maybe use individual setters to set the requested data (ContributorId and Icon).
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * ServiceRegistry that can be provided to created editors.
+ */
+ private ServicesRegistry serviceRegistry;
+
+ /**
+ * Creates a new AbstractEditorFactory.
+ *
+ * @param diagramClass
+ * expected Class of the diagram to create.
+ * @param expectedType
+ * expected diagram type (@see {@link Diagram#getType()})
+ */
+ public AbstractEditorFactory(Class<?> diagramClass, String expectedType) {
+ assert (expectedType != null);
+ this.diagramClass = diagramClass;
+ this.expectedType = expectedType;
+ }
+
+ /**
+ * Initialize the factory with useful Classes.
+ *
+ * @param serviceRegistry Service registry that will be provided to created editor.
+ * @param editorDescriptor Descriptor containing data from the Eclipse Extension.
+ */
+ public void init(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor) {
+ this.editorDescriptor = editorDescriptor;
+ this.serviceRegistry = serviceRegistry;
+
+ }
+
+
+ /**
+ * @return the serviceRegistry
+ */
+ public ServicesRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ /**
+ * Returns the expected class for the diagram implementation
+ *
+ * @return the expected class for the diagram implementation
+ */
+ public Class<?> getDiagramClass() {
+ return diagramClass;
+ }
+
+ /**
+ * Returns the expected type of the diagram
+ *
+ * @return the expected diagram type (@see {@link Diagram#getType()})
+ */
+ public String getExpectedType() {
+ return expectedType;
+ }
+
+ /**
+ * @return the editorDescriptor
+ */
+ public EditorDescriptor getEditorDescriptor() {
+ return editorDescriptor;
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptor.java
new file mode 100644
index 00000000000..0e8a0c12918
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptor.java
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * This descriptor describes a nested diagram. It is used by MultiDiagramEditor to know about the nested diagram. It is fill by an extension.
+ *
+ * @author Cedric Dumoulin
+ *
+ */
+public class EditorDescriptor {
+
+ /**
+ * Editor factory implementation class.
+ */
+ private Class<IPluggableEditorFactory> editorFactoryClass;
+
+ /**
+ * EditorActionBarContributor Id used to search the EditorActionBarContributor requested by the editor.
+ */
+ private String actionBarContributorId;
+
+ /**
+ * The icon representing the diagram
+ */
+ private ImageDescriptor icon;
+
+ /**
+ * Constructor.
+ */
+ public EditorDescriptor() {
+
+ }
+
+ /**
+ *
+ * @param attribute
+ */
+ public void setActionBarContributorId(String actionBarContributorId) {
+ this.actionBarContributorId = actionBarContributorId;
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.extension.diagrameditor.IEditorDescriptor#getActionBarContributorId()
+ * @return
+ *
+ */
+ public String getActionBarContributorId() {
+ return actionBarContributorId;
+ }
+
+ /**
+ * get the editor icon path
+ *
+ * @return the editor icon path
+ */
+ public ImageDescriptor getIcon() {
+ return icon;
+ }
+
+ /**
+ * set the editor icon
+ *
+ * @param icon
+ * the icon path
+ */
+ public void setIcon(ImageDescriptor icon) {
+ this.icon = icon;
+ }
+
+ /**
+ * get the class of the editor factory
+ *
+ * @return the class of the editor
+ */
+ public Class<IPluggableEditorFactory> getEditorFactoryClass() {
+ return editorFactoryClass;
+ }
+
+ /**
+ * set the editor facoty to this descriptor
+ *
+ * @param editorFactoryClass
+ * the class that represents the editor factory
+ */
+ public void setEditorFactoryClass(Class<IPluggableEditorFactory> editorFactoryClass) {
+ this.editorFactoryClass = editorFactoryClass;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public String toString() {
+ if(editorFactoryClass == null || editorFactoryClass.getName() == null) {
+ return "[nestedEditor editorFactory:" + editorFactoryClass + "(null)]";
+ }
+ return "[nestedEditor editorFactory:" + editorFactoryClass.getName() + "]";
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptorExtensionFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptorExtensionFactory.java
new file mode 100644
index 00000000000..86219179727
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorDescriptorExtensionFactory.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import static org.eclipse.papyrus.core.Activator.log;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.core.extension.BadNameExtensionException;
+import org.eclipse.papyrus.core.extension.DescriptorExtensionFactory;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * A factory used to create editor descriptor object from Eclipse extensions points elements.
+ *
+ *@author Cedric Dumoulin
+ *@author Patrick Tessier
+ */
+public class EditorDescriptorExtensionFactory extends DescriptorExtensionFactory {
+
+ /** singleton eINSTANCE of this class */
+ public final static EditorDescriptorExtensionFactory eINSTANCE = new EditorDescriptorExtensionFactory();
+
+ /** constant for the editor diagram **/
+ public final static String EDITOR_DIAGRAM_EXTENSIONPOINT = "editorDiagram";
+
+ /** constant for the attribute factoryClass **/
+ public final static String FACTORYCLASS_ATTRIBUTE = "factoryClass";
+
+ /** constant for the attribute contextId **/
+ public final static String ACTIONBARCONTRIBUTORID_ATTRIBUTE = "actionBarContributorId";
+
+ /** constant for the attribute icon **/
+ public final static String ICON_ATTRIBUTE = "icon";
+
+ /**
+ * @return the eINSTANCE
+ */
+ public static EditorDescriptorExtensionFactory getInstance() {
+ return eINSTANCE;
+ }
+
+ /**
+ * Create a descriptor instance corresponding to the ConfigurationElement.
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @return a nestedEditorDescriptor strucure that contains information to create diagrams
+ * @throws BadNameExtensionException
+ */
+ @SuppressWarnings("unchecked")
+ public EditorDescriptor createNestedEditorDescriptor(IConfigurationElement element) throws ExtensionException {
+ EditorDescriptor res;
+
+ checkTagName(element, EDITOR_DIAGRAM_EXTENSIONPOINT);
+
+ res = new EditorDescriptor();
+ res.setEditorFactoryClass((Class<IPluggableEditorFactory>)parseClass(element, FACTORYCLASS_ATTRIBUTE, EDITOR_DIAGRAM_EXTENSIONPOINT));
+ res.setActionBarContributorId(element.getAttribute(ACTIONBARCONTRIBUTORID_ATTRIBUTE));
+ String iconPath = element.getAttribute(ICON_ATTRIBUTE);
+ if(iconPath != null) {
+ res.setIcon(AbstractUIPlugin.imageDescriptorFromPlugin(element.getNamespaceIdentifier(), iconPath));
+ }
+
+ if(log.isDebugEnabled()) {
+ log.debug("Read editor descriptor " + res);
+ }
+ return res;
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorFactoryProxy.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorFactoryProxy.java
new file mode 100644
index 00000000000..d0085f47610
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorFactoryProxy.java
@@ -0,0 +1,107 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import org.eclipse.papyrus.core.editorsfactory.IEditorFactory;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+import org.eclipse.papyrus.sasheditor.contentprovider.IPageModel;
+
+
+/**
+ * A proxy implementation of {@link IEditorFactory} used to do lazy instantiation
+ * of concrete {@link IPluggableEditorFactory}.
+ * This class is used by the {@link PluggableEditorFactoryReader}
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class EditorFactoryProxy implements IEditorFactory {
+
+ /**
+ * The concrete implementation.
+ */
+ private IPluggableEditorFactory editorFactory;
+
+ /**
+ * EditorDescriptor associated to the factory.
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * ServiceRegistry that can be provided to created editors.
+ */
+ private ServicesRegistry serviceRegistry;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param editorDescriptor
+ */
+ public EditorFactoryProxy(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor) {
+ this.serviceRegistry = serviceRegistry;
+ this.editorDescriptor = editorDescriptor;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.editorsfactory.IEditorFactory#createIPageModel(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ public IPageModel createIPageModel(Object pageIdentifier) {
+ return getEditorFactory().createIPageModel(pageIdentifier);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.editorsfactory.IEditorFactory#isPageModelFactoryFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ return getEditorFactory().isPageModelFactoryFor(pageIdentifier);
+ }
+
+
+ /**
+ * @return the editorFactory
+ */
+ protected IPluggableEditorFactory getEditorFactory() {
+
+ if(editorFactory == null)
+ {
+ editorFactory = createEditorFactory();
+ }
+
+ return editorFactory;
+
+ }
+
+ /**
+ * Create an instance of IPluggableEditorFactory as described in the editorDescriptor.
+ * TODO let propagate the exceptions.
+ * @return
+ */
+ private IPluggableEditorFactory createEditorFactory() {
+ // Create the requested class.
+ try {
+ editorFactory = editorDescriptor.getEditorFactoryClass().newInstance();
+ // Set the descriptor. USed by the factory to get the ActionBarId and Icon
+ editorFactory.init(serviceRegistry, editorDescriptor);
+ return editorFactory;
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorIconFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorIconFactory.java
new file mode 100644
index 00000000000..94469848176
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorIconFactory.java
@@ -0,0 +1,123 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.core.editorsfactory.IEditorIconFactory;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * A factory used to create the Icon associated to an editor
+ * TODO Lets have a common ancestor for {@link EditorIconFactory} and {@link EditorFactoryProxy}
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class EditorIconFactory implements IEditorIconFactory {
+
+ /**
+ * The concrete implementation.
+ */
+ private IPluggableEditorFactory editorFactory;
+
+ /**
+ * EditorDescriptor associated to the factory.
+ */
+ protected EditorDescriptor editorDescriptor;
+
+ /**
+ * Cached image for reuse.
+ */
+ protected Image cachedImage;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param editorDescriptor
+ */
+ public EditorIconFactory(EditorDescriptor editorDescriptor) {
+ this.editorDescriptor = editorDescriptor;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.editorsfactory.IEditorIconFactory#getEditorIcon(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ public Image getEditorIcon(Object pageIdentifier) {
+
+
+ if(cachedImage == null) {
+ cachedImage = createEditorIcon(pageIdentifier);
+ }
+
+ return cachedImage;
+ }
+
+ /**
+ * Create an Image associated to the editor used to render the specified pageIdentifier
+ *
+ * @return
+ */
+ public Image createEditorIcon(Object pageIdentifier) {
+ ImageDescriptor imageDescriptor = editorDescriptor.getIcon();
+ if(imageDescriptor == null)
+ return null;
+ Image image = imageDescriptor.createImage();
+ return image;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.editorsfactory.IEditorFactory#isPageModelFactoryFor(java.lang.Object)
+ *
+ * @param pageIdentifier
+ * @return
+ */
+ public boolean isPageModelFactoryFor(Object pageIdentifier) {
+ return getEditorFactory().isPageModelFactoryFor(pageIdentifier);
+ }
+
+
+ /**
+ * @return the editorFactory
+ */
+ protected IPluggableEditorFactory getEditorFactory() {
+
+ if(editorFactory == null) {
+ editorFactory = createEditorFactory();
+ }
+
+ return editorFactory;
+
+ }
+
+ /**
+ * Create an instance of IPluggableEditorFactory as described in the editorDescriptor.
+ * TODO let propagate the exceptions.
+ *
+ * @return
+ */
+ private IPluggableEditorFactory createEditorFactory() {
+ // Create the requested class.
+ try {
+ editorFactory = editorDescriptor.getEditorFactoryClass().newInstance();
+ // Set the descriptor. USed by the factory to get the ActionBarId and Icon
+ // editorFactory.init(serviceRegistry, editorDescriptor);
+ return editorFactory;
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be
+ // solved by programmer.
+ throw new RuntimeException(e);
+ }
+
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorNotFoundException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorNotFoundException.java
new file mode 100644
index 00000000000..a717ebdf00e
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/EditorNotFoundException.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+/**
+ * Editor was not found.
+ *
+ * @author dumoulin
+ *
+ */
+@SuppressWarnings("serial")
+public class EditorNotFoundException extends MultiDiagramException {
+
+ /**
+ *
+ */
+ public EditorNotFoundException() {
+ }
+
+ /**
+ * @param arg0
+ */
+ public EditorNotFoundException(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ */
+ public EditorNotFoundException(Throwable arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public EditorNotFoundException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/IPluggableEditorFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/IPluggableEditorFactory.java
new file mode 100644
index 00000000000..c3e286a30fa
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/IPluggableEditorFactory.java
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import org.eclipse.papyrus.core.editorsfactory.IEditorFactory;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+
+
+/**
+ * This interface should be implemented by Editor Factories that can be declared as Eclipse extension.
+ * It extends the {@link IEditorFactory} by adding methods to initialize the factory with multieditor
+ * ServiceRegistry and associated editor data.
+ *
+ * @author Cédric Dumoulin
+ *
+ */
+public interface IPluggableEditorFactory extends IEditorFactory {
+
+ /**
+ * Initialize the factory with useful Classes.
+ *
+ * @param serviceRegistry Service registry that will be provided to created editor.
+ * @param editorDescriptor Descriptor containing data from the Eclipse Extension.
+ */
+ public void init(ServicesRegistry serviceRegistry, EditorDescriptor editorDescriptor);
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/MultiDiagramException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/MultiDiagramException.java
new file mode 100644
index 00000000000..a5ad7af98d4
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/MultiDiagramException.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+/**
+ * Root Exception of MultiDiagram exception
+ *
+ * @author dumoulin
+ *
+ */
+@SuppressWarnings("serial")
+public class MultiDiagramException extends Exception {
+
+ /**
+ *
+ */
+ public MultiDiagramException() {
+ }
+
+ /**
+ * @param arg0
+ */
+ public MultiDiagramException(String arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ */
+ public MultiDiagramException(Throwable arg0) {
+ super(arg0);
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public MultiDiagramException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/PluggableEditorFactoryReader.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/PluggableEditorFactoryReader.java
new file mode 100644
index 00000000000..21a2647ddf7
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/extension/diagrameditor/PluggableEditorFactoryReader.java
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.extension.diagrameditor;
+
+import static org.eclipse.papyrus.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.core.editorsfactory.PageIconsRegistry;
+import org.eclipse.papyrus.core.editorsfactory.PageModelFactoryRegistry;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+
+/**
+ * This reader is used to read PluggableEditorFactory from the Eclipse extension declarations.
+ * It can be used to populate an {@link PageModelFactoryRegistry}.
+ */
+public class PluggableEditorFactoryReader {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusDiagram";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /** list of editor descriptors */
+ protected List<EditorDescriptor> editorDescriptors;
+
+ /** indicates if extension is loaded or not */
+ private boolean isExtensionLoaded = false;
+
+
+ /**
+ * Create a new Registry reading extension from the specified namespace. The namespace is
+ * usually the name of the plugin owning the registry.
+ *
+ * @param extensionPointNamespace
+ */
+ public PluggableEditorFactoryReader(String extensionPointNamespace) {
+ super();
+ this.extensionPointNamespace = extensionPointNamespace;
+ editorDescriptors = new ArrayList<EditorDescriptor>();
+ }
+
+ /**
+ * Populate the provided {@link PageModelFactoryRegistry} with {@link IPluggableEditorFactory} read
+ * from Eclipse extension declarations.
+ * For each declared editor, create a proxy encapsulating the real EditorFactory. Then the proxy is
+ * added to the PageModelFactoryRegistry.
+ *
+ * @param pageModelFactoryRegistry The object to populate
+ * @param serviceRegistry ServiceRegistry provided to newly instantiated {@link IPluggableEditorFactory}.
+ */
+ public void populate(PageModelFactoryRegistry pageModelFactoryRegistry, ServicesRegistry serviceRegistry) {
+
+ for(EditorDescriptor desc : getEditorDescriptors()) {
+
+ // Create and add a proxy encapsulating the EditorFactory.
+ pageModelFactoryRegistry.add(new EditorFactoryProxy(serviceRegistry, desc));
+ }
+ }
+
+ /**
+ * Populate the provided {@link PageIconsRegistry} with icons read
+ * from Eclipse extension declarations.
+ * For each declared editor, create a {@link EditorIconFactory}.
+ *
+ * @param pageModelFactoryRegistry The object to populate
+ * @param serviceRegistry ServiceRegistry provided to newly instantiated {@link IPluggableEditorFactory}.
+ */
+ public void populate(PageIconsRegistry registry) {
+
+ for(EditorDescriptor desc : getEditorDescriptors()) {
+
+ // Create and add a proxy encapsulating the EditorFactory.
+ registry.add(new EditorIconFactory(desc));
+ }
+ }
+
+
+
+ /**
+ * Get the list of editor descriptor.
+ *
+ * @return the list of editor descriptor.
+ */
+ public List<EditorDescriptor> getEditorDescriptors() {
+ if(!isExtensionLoaded) {
+ isExtensionLoaded = true;
+ initializeEditorDescriptors();
+ }
+ return editorDescriptors;
+ }
+
+ /**
+ * Read editor descriptors from extension points.
+ */
+ private void initializeEditorDescriptors() {
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+
+ for(IConfigurationElement ele : configElements) {
+ EditorDescriptor desc;
+ try {
+ if(EditorDescriptorExtensionFactory.EDITOR_DIAGRAM_EXTENSIONPOINT.equals(ele.getName())) {
+ desc = EditorDescriptorExtensionFactory.eINSTANCE.createNestedEditorDescriptor(ele);
+ editorDescriptors.add(desc);
+ }
+ } catch (ExtensionException e) {
+ log.error("Initialization editor problem ", e);
+ }
+ }
+
+ if(log.isDebugEnabled()) {
+ log.debug("Read " + editorDescriptors.size() + " editor descriptors from Eclipse extensions");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return "EditorFactoryRegistry: " + editorDescriptors.toString();
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/DoSaveEvent.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/DoSaveEvent.java
new file mode 100644
index 00000000000..af919f81446
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/DoSaveEvent.java
@@ -0,0 +1,47 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+
+import org.eclipse.papyrus.core.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+
+
+/**
+ * Event sent whith a Save or SaveAs.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class DoSaveEvent {
+
+ final protected ServicesRegistry serviceRegistry;
+ final protected IMultiDiagramEditor multiDiagramEditor;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param multiDiagramEditor
+ */
+ public DoSaveEvent(ServicesRegistry serviceRegistry, IMultiDiagramEditor multiDiagramEditor) {
+ this.serviceRegistry = serviceRegistry;
+ this.multiDiagramEditor = multiDiagramEditor;
+ }
+
+ /**
+ * @return the serviceRegistry
+ */
+ public ServicesRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ /**
+ * @return the multiDiagramEditor
+ */
+ public IMultiDiagramEditor getMultiDiagramEditor() {
+ return multiDiagramEditor;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ILifeCycleEventsProvider.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ILifeCycleEventsProvider.java
new file mode 100644
index 00000000000..433fd3cc0e9
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ILifeCycleEventsProvider.java
@@ -0,0 +1,59 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+
+
+/**
+ * Concrete implementation of this interface allows to listen on various lifecycle events.
+ * This interface is the "public" part of the {@link LifeCycleEventsProvider}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public interface ILifeCycleEventsProvider {
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addAboutToDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeAboutToDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addPostDoSaveListener(ISaveEventListener listener);
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removePostDoSaveListener(ISaveEventListener listener);
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ISaveEventListener.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ISaveEventListener.java
new file mode 100644
index 00000000000..cb3c04d119e
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/ISaveEventListener.java
@@ -0,0 +1,28 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+
+
+/**
+ * Interface used to listen on open, save and saveAs events.
+ *
+ * @author cedric dumoulin
+ *
+ * @param <T> Type of event passed to methods.
+ */
+public interface ISaveEventListener {
+
+ /**
+ *
+ * @param editor
+ */
+ public void doSave(DoSaveEvent event);
+
+ /**
+ *
+ * @param editor
+ */
+ public void doSaveAs(DoSaveEvent event);
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProvider.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProvider.java
new file mode 100644
index 00000000000..3017a9d1396
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProvider.java
@@ -0,0 +1,277 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides events about the life cycle of a MultiEditor.
+ * Not all life cycle events are available.
+ * Available events:
+ * <ul>
+ * <li>aboutToDoSave, aboutToDoSaveAs - SaveEventListener</li>
+ * <li>doSave, doSaveAs - SaveEventListener</li>
+ * <li>afterDoSave, afterDoSaveAs - SaveEventListener</li>
+ * <li></li>
+ * <li></li>
+ * </ul>
+ *
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class LifeCycleEventsProvider implements ILifeCycleEventsProvider {
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList preSaveListeners = new SaveEventListenerLazyList();
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList saveListeners = new SaveEventListenerLazyList();
+
+ /**
+ *
+ */
+ protected SaveEventListenerLazyList postSaveListeners = new SaveEventListenerLazyList();
+
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addDoSaveListener(ISaveEventListener listener) {
+
+ saveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeDoSaveListener(ISaveEventListener listener) {
+ saveListeners.removeListener(listener);
+ }
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addAboutToDoSaveListener(ISaveEventListener listener) {
+
+ preSaveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeAboutToDoSaveListener(ISaveEventListener listener) {
+ preSaveListeners.removeListener(listener);
+ }
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addPostDoSaveListener(ISaveEventListener listener) {
+
+ postSaveListeners.addListener(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removePostDoSaveListener(ISaveEventListener listener) {
+ postSaveListeners.removeListener(listener);
+ }
+
+
+ // ****************************************************** //
+ // Fire events methods //
+ // ****************************************************** //
+
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireAboutToDoSaveEvent(DoSaveEvent event) {
+ preSaveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireAboutToDoSaveAsEvent(DoSaveEvent event) {
+ preSaveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireDoSaveEvent(DoSaveEvent event) {
+ saveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireDoSaveAsEvent(DoSaveEvent event) {
+ saveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void firePostDoSaveEvent(DoSaveEvent event) {
+ postSaveListeners.fireSaveEvent(event);
+ }
+
+ /**
+ * Fire AboutToSaveAs to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void firePostDoSaveAsEvent(DoSaveEvent event) {
+ postSaveListeners.fireSaveAsEvent(event);
+ }
+
+ /**
+ * Fire all Save events (about, events, post) to registered Listeners.
+ * Exceptions from listeners are propagated and stop the event chain.
+ *
+ * @param editorPart
+ */
+ public void fireAllDoSaveEvent(DoSaveEvent event) {
+ fireAboutToDoSaveEvent(event);
+ fireDoSaveEvent(event);
+ firePostDoSaveEvent(event);
+ }
+
+ /**
+ * Fire all SaveAs events (about, events, post) to registered Listeners.
+ * If one of the saveAs event fail, post events are not sent.
+ *
+ * @param editorPart
+ */
+ public void fireAllDoSaveAsEvent(DoSaveEvent event) {
+ fireAboutToDoSaveAsEvent(event);
+ fireDoSaveAsEvent(event);
+ firePostDoSaveAsEvent(event);
+ }
+
+ /**
+ * Base class encapsulating a lazy creation list.
+ *
+ * @author cedric dumoulin
+ *
+ * @param <T>
+ */
+ abstract protected class AbstractEventListenersLazyList<T> {
+
+ List<T> listeners;
+
+ /**
+ * Add specified listener.
+ *
+ * @param listener
+ */
+ public void addListener(T listener) {
+ // Lazy creation
+ if(listeners == null)
+ listeners = new ArrayList<T>();
+
+ // do not add if already present.
+ if(listeners.contains(listener))
+ return;
+
+ listeners.add(listener);
+ }
+
+ /**
+ * Remove specified listener.
+ *
+ * @param listener
+ */
+ public void removeListener(T listener) {
+ // Lazy creation
+ if(listeners == null)
+ return;
+
+ listeners.remove(listener);
+ }
+
+
+ /**
+ * @return the listeners
+ */
+ protected List<T> getListeners() {
+ return listeners;
+ }
+
+ }
+
+ /**
+ * List of {@link ISaveEventListener}.
+ *
+ * @author cedric dumoulin
+ *
+ */
+ protected class SaveEventListenerLazyList extends AbstractEventListenersLazyList<ISaveEventListener> {
+
+ /**
+ * Fire OpenEvent to registered Listeners.
+ * If a listener throw an exception, remaining listeners are called, and then the exception
+ * is resent.
+ *
+ * @param editorPart
+ */
+ public void fireSaveEvent(DoSaveEvent event) {
+ // Lazy creation
+ if(listeners == null)
+ return;
+
+ for(ISaveEventListener listener : listeners) {
+ listener.doSave(event);
+ }
+ }
+
+ /**
+ * Fire OpenEvent to registered Listeners.
+ *
+ * @param editorPart
+ */
+ public void fireSaveAsEvent(DoSaveEvent event) {
+ // Lazy creation
+ if(listeners == null)
+ return;
+
+ for(ISaveEventListener listener : listeners) {
+ listener.doSaveAs(event);
+ }
+
+ }
+
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/IPapyrusListener.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/IPapyrusListener.java
new file mode 100644
index 00000000000..fb5dfb86c51
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/IPapyrusListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.listenerservice;
+
+import org.eclipse.emf.common.notify.Notification;
+
+/**
+ * This interface is a listener that will listen directly all events in papyrus: uml. It will be very useful for external plug-in.
+ *
+ *An implementation may be an adapter.
+ */
+public interface IPapyrusListener {
+
+ /**
+ * Notifies that a change to some feature has occurred.
+ *
+ * @param notification
+ * - a description of the change.
+ **/
+ public void notifyChanged(Notification notification);
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/ModelListenerManager.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/ModelListenerManager.java
new file mode 100644
index 00000000000..55f33e5ef74
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/listenerservice/ModelListenerManager.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.listenerservice;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.osgi.framework.Bundle;
+
+/**
+ * This class is a manager that loads all listeners of the uml model
+ *
+ */
+
+public class ModelListenerManager extends EContentAdapter {
+
+ // list of of listener
+ private Hashtable<String, IPapyrusListener> listenerRegistry;
+
+ // extension point ID
+ private String MODELLISTENERID_EXTENSION_ID = "org.eclipse.papyrus.core.modelListener";
+
+ private String NAME_ID = "name";
+
+ private String REALIZATION_ID = "realization";
+
+ /**
+ * Constructor
+ */
+ public ModelListenerManager() {
+ super();
+ // init stack
+ listenerRegistry = new Hashtable<String, IPapyrusListener>();
+ initializeListenerList();
+ }
+
+ /**
+ * Load all listeners of the model
+ */
+ private void initializeListenerList() {
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(MODELLISTENERID_EXTENSION_ID);
+ for(int i = 0; i < configElements.length; i++) {
+ inializeOneRule(configElements[i]);
+ }
+
+ }
+
+ /**
+ * Load one listener
+ *
+ * @param element
+ * the extension point
+ */
+ private void inializeOneRule(IConfigurationElement element) {
+ String listenerName = element.getAttribute(NAME_ID);
+ try {
+ IPapyrusListener listener = (IPapyrusListener)createExtension(element, element.getAttribute(REALIZATION_ID));
+ listenerRegistry.put(listenerName, listener);
+ } catch (Exception e) {
+ System.err.println("- " + listenerName + " can not be loaded: " + e);
+ }
+
+ }
+
+ /**
+ * Load an instance of a class
+ *
+ * @param element
+ * the extension point
+ * @param classAttribute
+ * the name of the class to load
+ * @return the loaded Class
+ * @throws Exception
+ * if the class is not loaded
+ */
+ private static Object createExtension(final IConfigurationElement element, final String classAttribute) throws Exception {
+ try {
+ Bundle extensionBundle = Platform.getBundle(element.getDeclaringExtension().getNamespaceIdentifier());
+ Class clazz = extensionBundle.loadClass(classAttribute);
+ Object obj = clazz.newInstance();
+ return obj;
+ // return element.createExecutableExtension(classAttribute);
+ } catch (Exception e) {
+ throw new Exception("unable to create Extension" + e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ String out = "ModelListener: \n";
+ Enumeration<String> keyenum = listenerRegistry.keys();
+ // we will call to string in each class
+ while(keyenum.hasMoreElements()) {
+ String aKey = keyenum.nextElement();
+ out = out + "- " + aKey + " (" + listenerRegistry.get(aKey).toString() + ")\n";
+ }
+ return out;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
+ Enumeration<IPapyrusListener> papyrusListenersEnum = listenerRegistry.elements();
+ while(papyrusListenersEnum.hasMoreElements()) {
+ papyrusListenersEnum.nextElement().notifyChanged(notification);
+ }
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java
new file mode 100644
index 00000000000..a52d71b28a6
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorDescriptor.java
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.multidiagram.actionbarcontributor;
+
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * Descriptor of an ActionBarContributor.
+ * This descriptor is usually loaded from the Eclipse extension mechanism.
+ *
+ * @author Cedric Dumoulin
+ * @author Patrick Tessier
+ *
+ */
+public class ActionBarContributorDescriptor {
+
+ protected Class<? extends EditorActionBarContributor> contextClass;
+
+ protected String contextId;
+
+ /**
+ * Instance is created when requested.
+ */
+ protected EditorActionBarContributor instance = null;
+
+ /**
+ * constructor.
+ *
+ * @return the context descriptor
+ * @throws BackboneException
+ */
+ protected EditorActionBarContributor getActionBarContributor() throws BackboneException {
+ if(instance == null)
+ instance = createActionBarContributor();
+
+ return instance;
+ }
+
+ private EditorActionBarContributor createActionBarContributor() throws BackboneException {
+ try {
+ EditorActionBarContributor context = contextClass.newInstance();
+ return context;
+
+ } catch (SecurityException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ throw new RuntimeException(e);
+ } catch (InstantiationException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // Lets propagate. This is an implementation problem that should be solved by programmer.
+ throw new RuntimeException(e);
+ }
+ }
+
+} // end class
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java
new file mode 100644
index 00000000000..c74ff17a253
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorExtensionFactory.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.multidiagram.actionbarcontributor;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.core.extension.BadNameExtensionException;
+import org.eclipse.papyrus.core.extension.DescriptorExtensionFactory;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * A factory used to create ActionBarContributor object from Eclipse extensions points elements.
+ *
+ * @author Cedric Dumoulin
+ *@auhtor Patrick Tessier
+ */
+public class ActionBarContributorExtensionFactory extends DescriptorExtensionFactory {
+
+ /** singleton eINSTANCE of this class */
+ public final static ActionBarContributorExtensionFactory eINSTANCE = new ActionBarContributorExtensionFactory();
+
+ /** constant for the editor diagram **/
+ public final static String EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT = "" + "actionBarContributor";
+
+ /** constant for the attribute factoryClass **/
+ public final static String CONTEXTCLASS_ATTRIBUTE = "implementingClass";
+
+ /** constant for the attribute contextId **/
+ public final static String ID_ATTRIBUTE = "id";
+
+ /**
+ * @return the eINSTANCE
+ */
+ public static ActionBarContributorExtensionFactory getInstance() {
+ return eINSTANCE;
+ }
+
+ /**
+ * Create a ContextDescriptor instance corresponding to the ConfigurationElement.
+ *
+ * @param element
+ * an {@link IConfigurationElement} see eclipse extension point
+ * @return a ContextDescriptor structure that contains information to the diagram context
+ * @throws BadNameExtensionException
+ **/
+ public ActionBarContributorDescriptor createActionBarContributorDescriptor(IConfigurationElement element) throws ExtensionException {
+ ActionBarContributorDescriptor res;
+
+ checkTagName(element, EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT);
+
+ res = new ActionBarContributorDescriptor();
+ res.contextClass = (Class<EditorActionBarContributor>)parseClass(element, CONTEXTCLASS_ATTRIBUTE, EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT);
+ res.contextId = element.getAttribute(ID_ATTRIBUTE);
+
+ return res;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java
new file mode 100644
index 00000000000..08c16edca72
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/ActionBarContributorRegistry.java
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.multidiagram.actionbarcontributor;
+
+import static org.eclipse.papyrus.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.papyrus.core.extension.ExtensionException;
+import org.eclipse.papyrus.core.extension.NotFoundException;
+import org.eclipse.papyrus.core.services.IService;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+/**
+ * A factory managing ActionBarContributor creation.
+ * The factory is loaded from ActionBarContributor declared in Eclipse extension mechanism.
+ *
+ * @author dumoulin
+ *
+ */
+public class ActionBarContributorRegistry implements IActionBarContributorFactory, IService {
+
+ /** ID of the editor extension (schema filename) */
+ public static final String EDITOR_EXTENSION_ID = "papyrusDiagram";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /**
+ * Registered context descriptors.
+ */
+ private Map<Object, ActionBarContributorDescriptor> editorContextDescriptors;
+
+ /**
+ * Constructor. defaultContext, input and site are explicitly required in order be sure that they are initialized. The multiEditor should be
+ * initialized. In particular, getEditorSite(),
+ * getEditorInput() and getDefaultContext() should return initialized values.
+ *
+ *@param multiEditor
+ * the multieditor
+ *@param extensionPointNamespace
+ */
+ public ActionBarContributorRegistry(String extensionPointNamespace) {
+
+
+ this.extensionPointNamespace = extensionPointNamespace;
+ initializeEditorContextDescriptors();
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public EditorActionBarContributor getActionBarContributor(Object key) throws BackboneException {
+ try {
+ ActionBarContributorDescriptor desc = editorContextDescriptors.get(key);
+ return desc.getActionBarContributor();
+ } catch (NullPointerException e) {
+ // no context found.
+ throw new NotFoundException("No ActionBarContributor registered under id '" + key + "'.");
+ }
+ }
+
+ /**
+ * Get the list of descriptors.
+ *
+ * @return
+ * @throws BackboneException
+ * If a contributor fail to be loaded.
+ */
+ public List<EditorActionBarContributor> getActionBarContributors() throws BackboneException {
+ List<EditorActionBarContributor> res = new ArrayList<EditorActionBarContributor>();
+ for(ActionBarContributorDescriptor desc : editorContextDescriptors.values()) {
+ res.add(desc.getActionBarContributor());
+ }
+ return res;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ public void registerActionBarContributor(String contextKey, EditorActionBarContributor contributor) {
+ ActionBarContributorDescriptor desc = new ActionBarContributorDescriptor();
+ desc.contextId = contextKey;
+ desc.instance = contributor;
+ desc.contextClass = contributor.getClass();
+
+ editorContextDescriptors.put(contextKey, desc);
+ }
+
+ /**
+ * Read context descriptors from extension points.
+ */
+ private void initializeEditorContextDescriptors() {
+
+ editorContextDescriptors = new HashMap<Object, ActionBarContributorDescriptor>();
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, EDITOR_EXTENSION_ID);
+
+ ActionBarContributorExtensionFactory extensionReader = new ActionBarContributorExtensionFactory();
+
+ for(IConfigurationElement ele : configElements) {
+ ActionBarContributorDescriptor desc;
+ try {
+ if(ActionBarContributorExtensionFactory.EDITOR_ACTIONBARCONTRIBUTOR_EXTENSIONPOINT.equals(ele.getName())) {
+ desc = extensionReader.createActionBarContributorDescriptor(ele);
+ // Check double
+ if(editorContextDescriptors.get(desc.contextId) != null) {
+ // Already exists. Check if it is the same
+ ActionBarContributorDescriptor existingDesc = editorContextDescriptors.get(desc.contextId);
+ if(desc.equals(existingDesc)) {
+ log.warn("More than one ActionBarContributor is registered under the name '" + desc.contextId + "', with different parameters. Extra declaration are discarded.");
+ }
+ } else {
+ editorContextDescriptors.put(desc.contextId, desc);
+ }
+ }
+ } catch (ExtensionException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+ if(log.isDebugEnabled()) {
+ log.debug(this.getClass().getSimpleName() + " : contributors desc loaded [" + editorContextDescriptors.size() + "]");
+ }
+ }
+
+ /**
+ * Do nothing in this implementation. {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.core.services.IService#startService()
+ */
+ public void startService() {
+ }
+
+ /*
+ * Do nothing in this implementation.
+ */
+ public void disposeService() {
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java
new file mode 100644
index 00000000000..ef9771cb16b
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/CoreComposedActionBarContributor.java
@@ -0,0 +1,110 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.multidiagram.actionbarcontributor;
+
+import java.util.List;
+
+import org.eclipse.gef.ui.actions.RedoRetargetAction;
+import org.eclipse.gef.ui.actions.UndoRetargetAction;
+import org.eclipse.papyrus.core.Activator;
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.papyrus.sasheditor.editor.actionbarcontributor.ComposedActionBarContributor;
+import org.eclipse.papyrus.sasheditor.editor.actionbarcontributor.IMultiPageEditorActionBarContributor;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+
+/**
+ *
+ * An ActionBarContributor composed of ActionBarContributor from multi editor.
+ * This ActionBarContributor switch to the contributor dedicated to the active editor in
+ * a MultiPageEditor environement.
+ *
+ * @author dumoulin
+ *
+ */
+public class CoreComposedActionBarContributor extends ComposedActionBarContributor implements IMultiPageEditorActionBarContributor {
+
+ /**
+ * The registry. Used to initialize the registered actionBars.
+ */
+ protected ActionBarContributorRegistry actionBarContributorRegistry;
+
+ protected List<EditorActionBarContributor> contributors;
+
+ /**
+ * Constructor.
+ *
+ * @throws BackboneException
+ */
+ public CoreComposedActionBarContributor() throws BackboneException {
+ // Init the contributors
+ loadContributors();
+ }
+
+ /**
+ *
+ * @throws BackboneException
+ */
+ private void loadContributors() throws BackboneException {
+ actionBarContributorRegistry = new ActionBarContributorRegistry(Activator.PLUGIN_ID);
+
+ contributors = actionBarContributorRegistry.getActionBarContributors();
+ }
+
+
+ /**
+ * @return the actionBarContributorRegistry
+ */
+ public ActionBarContributorRegistry getActionBarContributorRegistry() {
+ return actionBarContributorRegistry;
+ }
+
+
+ /**
+ * Dispose all nested ActionBarContributors.
+ */
+ @Override
+ public void dispose() {
+ // Dispose nested contributors.
+ for(EditorActionBarContributor contributor : contributors) {
+ contributor.dispose();
+ }
+ super.dispose();
+ }
+
+ /**
+ * Call the same method on each registered nested ActionBarContributors.
+ */
+ @Override
+ public void init(IActionBars bars, IWorkbenchPage page) {
+ super.init(bars, page);
+ buildActions();
+
+ // init nested contributors.
+ for(EditorActionBarContributor contributor : contributors) {
+ contributor.init(bars, page);
+ }
+
+ }
+
+ /**
+ * Load default actions (undo/redo/delete)
+ *
+ * @see org.eclipse.gef.ui.actions.ActionBarContributor#buildActions()
+ */
+ protected void buildActions() {
+ //getActionBars().getToolBarManager().add(new UndoRetargetAction());
+ //getActionBars().getToolBarManager().add(new RedoRetargetAction());
+ }
+
+
+ public void setActiveEditor(IEditorPart targetEditor) {
+ super.setActiveEditor(targetEditor);
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/IActionBarContributorFactory.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/IActionBarContributorFactory.java
new file mode 100644
index 00000000000..66fe63e9a80
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/multidiagram/actionbarcontributor/IActionBarContributorFactory.java
@@ -0,0 +1,26 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.multidiagram.actionbarcontributor;
+
+import org.eclipse.papyrus.core.editor.BackboneException;
+import org.eclipse.ui.part.EditorActionBarContributor;
+
+
+/**
+ * Interface used to get an ActionBarContributor from its ID.
+ *
+ * @author dumoulin
+ *
+ */
+public interface IActionBarContributorFactory {
+
+ /**
+ * Get an ActionBarContributor by its key.
+ * If an ActionBarContributor already exists for this key, return it.
+ *
+ * @param key
+ * @return
+ */
+ public EditorActionBarContributor getActionBarContributor(Object key) throws BackboneException;
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/AbstractServiceEntry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/AbstractServiceEntry.java
new file mode 100644
index 00000000000..7ac28cd49e3
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/AbstractServiceEntry.java
@@ -0,0 +1,156 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.Platform;
+import org.osgi.framework.Bundle;
+
+
+/**
+ * Abstract ServiceEntry.
+ * A ServiceEntry make the link between the Service instance, its descriptor, the registry.
+ *
+ * @author cedric dumoulin
+ */
+public abstract class AbstractServiceEntry {
+
+ protected ServicesRegistry registry;
+
+ /**
+ * Descriptor of the service associated to this entry.
+ */
+ protected ServiceDescriptor serviceDescriptor;
+
+
+ /**
+ * Startup the services.
+ * This method is called by the registry at the beginning in order to start
+ * services marked as "STARTUP".
+ *
+ * @throws ServiceException
+ * If service can't be started.
+ */
+ public void startup() throws ServiceException {
+ // Start service if needed
+ if(serviceDescriptor.isStartAtStartup())
+ startService();
+ }
+
+ /**
+ * Get the descriptor of the service associated to this entry.
+ *
+ * @return
+ */
+ public ServiceDescriptor getDescriptor() {
+ return serviceDescriptor;
+ }
+
+ /**
+ * Create the service.
+ *
+ * @return the created service.
+ * @throws ServiceException
+ */
+ protected IService createService() throws ServiceException {
+
+ Object service = instanciateService();
+ // if(! (service instanceof IService) )
+ // {
+ // // Service is not of the right type. Provide a wrapper.
+ // return new ServiceWrapper(service);
+ // }
+
+ // Service is of the right type
+ return (IService)service;
+ }
+
+ /**
+ * Instanciate the service as specified in serviceClassname.
+ *
+ * @return the created service.
+ * @throws ServiceException
+ */
+ protected Object instanciateService() throws ServiceException {
+
+ // Load the Class of the service
+ String serviceClassname = serviceDescriptor.getServiceClassname();
+ Class<?> classname = loadClass();
+
+ // Try to get the one arg constructor.
+ try {
+ Constructor<?> constructor = classname.getConstructor(ServicesRegistry.class);
+ return constructor.newInstance(registry);
+ } catch (SecurityException e) {
+ // Do nothing, try next constructor
+ } catch (NoSuchMethodException e) {
+ // Do nothing, try next constructor
+ } catch (IllegalArgumentException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with args ServicesRegistry.", e);
+ } catch (InstantiationException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with args ServicesRegistry.", e);
+ } catch (IllegalAccessException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with args ServicesRegistry.", e);
+ } catch (InvocationTargetException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with args ServicesRegistry.", e);
+ }
+
+ // Try with zero arg constructor.
+ try {
+ return classname.newInstance();
+ } catch (SecurityException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e);
+ } catch (IllegalArgumentException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e);
+ } catch (InstantiationException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e);
+ } catch (IllegalAccessException e) {
+ throw new ServiceException("Can't instanciate '" + serviceClassname + "' with zero args.", e);
+ }
+ }
+
+
+ /**
+ * Load the Class object. Try from current ClassLoader, then try using the plugin referenced in the
+ * serviceDescriptor.PluginId
+ *
+ * @return
+ * @throws ServiceException
+ */
+ private Class<?> loadClass() throws ServiceException {
+ String serviceClassname = serviceDescriptor.getServiceClassname();
+ Class<?> serviceClass;
+ try {
+ serviceClass = Class.forName(serviceClassname);
+ } catch (ClassNotFoundException e1) {
+ // Try using bundle
+ try {
+ String bundleID = serviceDescriptor.getClassBundleID();
+ Bundle bundle = Platform.getBundle(bundleID);
+ serviceClass = bundle.loadClass(serviceClassname);
+ } catch (ClassNotFoundException e2) {
+ throw new ServiceException("Can't find class for the name '" + serviceClassname + "'.", e2);
+ }
+ }
+
+ return serviceClass;
+ }
+
+ /**
+ * Dispose associated service
+ */
+ public void disposeService() throws ServiceException {
+ }
+
+ abstract public Object getServiceInstance() throws ServiceException;
+
+ abstract public boolean isStarted();
+
+ public void startService() throws ServiceException {
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ExtensionServicesRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ExtensionServicesRegistry.java
new file mode 100644
index 00000000000..e32cec4dfbb
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ExtensionServicesRegistry.java
@@ -0,0 +1,145 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+
+
+/**
+ * ServiceRegistry reading and registering services declared in Eclipse Extensions.
+ *
+ * @author dumoulin
+ *
+ */
+public class ExtensionServicesRegistry extends ServicesRegistry {
+
+ /** ID of the extension (schema filename) */
+ public static final String SERVICE_EXTENSION_ID = "service";
+
+ /** Namespace where to look for the extension points. */
+ protected String extensionPointNamespace;
+
+ /** Extension point name inside the extension description **/
+ public final static String SERVICE_EXTENSIONPOINT = "service";
+
+ /** constant for the attribute factoryClass **/
+ public final static String CONTEXTCLASS_ATTRIBUTE = "contextClass";
+
+ /** extension point propertyname */
+ private final static String STARTKIND_PROPERTY = "startKind";
+
+ /**
+ * Constructor.
+ *
+ * @throws Exception
+ */
+ public ExtensionServicesRegistry(String extensionPointNamespace) throws ServiceException {
+ this.extensionPointNamespace = extensionPointNamespace;
+ registerDeclaredExtensions();
+ }
+
+ /**
+ * Register the services declared in Eclipse Extension.
+ *
+ * @throws Exception
+ */
+ private void registerDeclaredExtensions() throws ServiceException {
+
+ List<ServiceDescriptor> descriptors = new ArrayList<ServiceDescriptor>();
+ List<ServiceException> exceptions = null;
+
+ // Reading data from plugins
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, SERVICE_EXTENSION_ID);
+
+ for(IConfigurationElement ele : configElements) {
+ ServiceDescriptor desc;
+ if(SERVICE_EXTENSIONPOINT.equals(ele.getName())) {
+ // Read value from extension
+ try {
+ desc = readServiceDescriptor(ele);
+ // Add created desc
+ descriptors.add(desc);
+ } catch (ServiceException e) {
+ // record exceptions
+ if(exceptions == null)
+ exceptions = new ArrayList<ServiceException>();
+ exceptions.add(e);
+ }
+ }
+ }
+
+ // Add found descriptors
+ for(ServiceDescriptor desc : descriptors) {
+ add(desc);
+ }
+
+ // Throw exceptions if pb encountered
+ if(exceptions != null) {
+ if(exceptions.size() == 1)
+ throw exceptions.get(0);
+ else
+ throw new ServiceException("Somme services are not started (first is shown)", exceptions.get(0));
+
+ }
+
+ }
+
+ /**
+ * Read descriptor values from provided element.
+ *
+ * @param ele
+ * @return
+ * @throws ServiceException
+ */
+ private ServiceDescriptor readServiceDescriptor(IConfigurationElement ele) throws ServiceException {
+ //
+ String useTypeAsKeyStr = ele.getAttribute("useClassTypeAsKey");
+ boolean useTypeAsKey = Boolean.valueOf(useTypeAsKeyStr);
+
+ // classname
+ String serviceClassname = ele.getAttribute("classname");
+
+ // key
+ String key = ele.getAttribute("id");
+ if(key == null || key.length() == 0) {
+ key = serviceClassname;
+ }
+
+ // Service start kind
+ ServiceStartKind serviceStartKind = ServiceStartKind.LAZY;
+ String serviceStartKindStr = ele.getAttribute(STARTKIND_PROPERTY);
+ if(serviceStartKindStr != null && serviceStartKindStr.length() > 0) {
+ try {
+ serviceStartKind = ServiceStartKind.valueOf(serviceStartKindStr.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ // Can't convert property
+ throw new ServiceException("Can't convert property " + STARTKIND_PROPERTY
+ + "(plugin=" + ele.getContributor()
+ + "declaringExtension=" + ele.getDeclaringExtension()
+ + ")"
+ , e);
+ }
+ }
+
+ // priority
+ int priority = 1;
+ String priorityStr = ele.getAttribute("priority");
+ if(priorityStr == null || priorityStr.length() == 0) {
+ try {
+ priority = Integer.parseInt(priorityStr);
+ } catch (NumberFormatException e) {
+ }
+ }
+
+
+ ServiceDescriptor desc = new ServiceDescriptor(key, serviceClassname, serviceStartKind, priority);
+ desc.setClassBundleID(ele.getContributor().getName());
+ desc.setUseClassTypeAsKey(useTypeAsKey);
+ return desc;
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/IService.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/IService.java
new file mode 100644
index 00000000000..3a86d42f0d1
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/IService.java
@@ -0,0 +1,25 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+/**
+ * An Service that can be registered in the {@link ServicesRegistry}.
+ * A service is a singleton available throw the registry. A service can be shared across editors.
+ *
+ * @author dumoulin
+ *
+ */
+public interface IService {
+
+ /**
+ * Start the service. This method is called when the service is started.
+ */
+ public void startService();
+
+ /**
+ * Dispose the service.
+ */
+ public void disposeService();
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/PojoServiceEntry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/PojoServiceEntry.java
new file mode 100644
index 00000000000..20955361d58
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/PojoServiceEntry.java
@@ -0,0 +1,67 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+/**
+ * @author cedric dumoulin
+ */
+public class PojoServiceEntry extends AbstractServiceEntry {
+
+ /** Instance of the service, if started. */
+ private Object serviceInstance;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceDescriptor
+ * @param registry
+ */
+ public PojoServiceEntry(ServiceDescriptor serviceDescriptor, ServicesRegistry registry) {
+ this.serviceDescriptor = serviceDescriptor;
+ this.registry = registry;
+
+ }
+
+
+ /**
+ * Create an entry for an already created service.
+ * Constructor.
+ *
+ * @param descriptor
+ * Descriptor of the service. Key and priority should be set.
+ * @param serviceInstance
+ * The service Instance
+ */
+ public PojoServiceEntry(ServiceDescriptor descriptor, Object serviceInstance) {
+ this.serviceDescriptor = descriptor;
+ this.serviceInstance = serviceInstance;
+ }
+
+ /**
+ * Get the service instance.
+ *
+ * @return
+ * @throws ServiceException
+ * If service can't be started.
+ */
+ public Object getServiceInstance() throws ServiceException {
+ if(serviceInstance == null) {
+ startService();
+ }
+
+ return serviceInstance;
+ }
+
+ /**
+ * Return true if the service is instantiated. Return false otherwise.
+ *
+ * @return
+ */
+ public boolean isStarted() {
+ return serviceInstance != null;
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceDescriptor.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceDescriptor.java
new file mode 100644
index 00000000000..ac9d570fcbc
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceDescriptor.java
@@ -0,0 +1,159 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+
+/**
+ * Descriptor of a service.
+ * This descriptor describe a service.
+ *
+ * @author dumoulin
+ *
+ */
+public class ServiceDescriptor {
+
+ /** Classname of the service. USed to start the service */
+ private String serviceClassname;
+
+ /** Kind of start for this service */
+ private ServiceStartKind serviceStartKind;
+
+ /**
+ * Service priority. If two service are registered under the same key, only the one with the
+ * higher priority is started.
+ */
+ private int priority;
+
+ /**
+ * Key used to register the service.
+ */
+ private Object key;
+
+ /**
+ * Id of the bundle owning the .class that is referenced by serviceClassname.
+ * Requested when instanciating the class.
+ */
+ private String classBundleID;
+
+
+ /**
+ * If set to true, use the classType as key.
+ */
+ private boolean useClassTypeAsKey = false;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceClassname
+ * @param serviceStartKind
+ * @param priority
+ */
+ public ServiceDescriptor(String serviceClassname, ServiceStartKind serviceStartKind, int priority) {
+ this.key = serviceClassname;
+ this.serviceClassname = serviceClassname;
+ this.serviceStartKind = serviceStartKind;
+ this.priority = priority;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param key
+ * @param serviceClassname
+ * @param serviceStartKind
+ * @param priority
+ */
+ public ServiceDescriptor(Object key, String serviceClassname, ServiceStartKind serviceStartKind, int priority) {
+ this.key = key;
+ this.serviceClassname = serviceClassname;
+ this.serviceStartKind = serviceStartKind;
+ this.priority = priority;
+ }
+
+ /**
+ * @return the serviceStartKind
+ */
+ public ServiceStartKind getServiceStartKind() {
+ return serviceStartKind;
+ }
+
+ /**
+ * Return true if StartKind is 'always'.
+ *
+ * @return
+ */
+ public boolean isStartAtStartup() {
+ return serviceStartKind == ServiceStartKind.STARTUP;
+ }
+
+ /**
+ * @return the priority
+ */
+ public int getPriority() {
+ return priority;
+ }
+
+
+ /**
+ * @return the key
+ */
+ public Object getKey() {
+ return key;
+ }
+
+
+ /**
+ * @return the serviceClassname
+ */
+ public String getServiceClassname() {
+ return serviceClassname;
+ }
+
+
+ /**
+ * @return the classBundleID
+ */
+ public String getClassBundleID() {
+ return classBundleID;
+ }
+
+
+ /**
+ * @return the useClassTypeAsKey
+ */
+ public boolean isUseClassTypeAsKey() {
+ return useClassTypeAsKey;
+ }
+
+ /**
+ * @param classBundleId
+ * the classBundleID to set
+ */
+ public void setClassBundleID(String classBundleId) {
+ classBundleID = classBundleId;
+ }
+
+
+ /**
+ * @param useClassTypeAsKey
+ * the useClassTypeAsKey to set
+ */
+ public void setUseClassTypeAsKey(boolean useClassTypeAsKey) {
+ this.useClassTypeAsKey = useClassTypeAsKey;
+ }
+
+
+ /**
+ * @see java.lang.Object#toString()
+ * @return
+ *
+ */
+ @Override
+ public String toString() {
+ return "ServiceDescriptor [key=" + key + ", serviceClassname=" + serviceClassname + ", serviceStartKind=" + serviceStartKind + ", priority=" + priority + "]";
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceEntry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceEntry.java
new file mode 100644
index 00000000000..c45c1aa25d3
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceEntry.java
@@ -0,0 +1,108 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+
+
+/**
+ * Entry of a Service in the ServiceRegistry.
+ * This class provide methods to manage the Service life cycle.
+ *
+ * @author cedric dumoulin
+ *
+ */
+public class ServiceEntry extends AbstractServiceEntry {
+
+ /** Instance of the service, if started. */
+ private IService serviceInstance;
+
+ /**
+ * Constructor.
+ *
+ * @param serviceDescriptor
+ * @param registry
+ */
+ public ServiceEntry(ServiceDescriptor serviceDescriptor, ServicesRegistry registry) {
+ this.serviceDescriptor = serviceDescriptor;
+ this.registry = registry;
+
+ }
+
+
+ /**
+ * Create an entry for an already created service.
+ * Constructor.
+ *
+ * @param descriptor
+ * Descriptor of the service. Key and priority should be set.
+ * @param serviceInstance
+ * The service Instance
+ */
+ public ServiceEntry(ServiceDescriptor descriptor, IService serviceInstance) {
+ this.serviceDescriptor = descriptor;
+ this.serviceInstance = serviceInstance;
+ }
+
+ /**
+ * Start the service manually.
+ *
+ * @throws ServiceException
+ */
+ public void startService() throws ServiceException {
+ // Create the instance if needed
+ if(serviceInstance == null) {
+ serviceInstance = createService();
+ }
+ serviceInstance.startService();
+ }
+
+ /**
+ * Get the service instance.
+ *
+ * @return
+ * @throws ServiceException
+ * If service can't be started.
+ */
+ public Object getServiceInstance() throws ServiceException {
+ if(serviceInstance == null) {
+ startService();
+ }
+
+ return serviceInstance;
+ }
+
+
+ /**
+ * Dispose the service manually.
+ */
+ public void disposeService() throws ServiceException {
+ if(serviceInstance == null)
+ return;
+
+ serviceInstance.disposeService();
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ * @return
+ *
+ */
+ @Override
+ public String toString() {
+ return "ServiceEntry [serviceDescriptor=" + serviceDescriptor.toString() + ", serviceInstance=" + serviceInstance + "]";
+ }
+
+
+ /**
+ * Return true if the service is instantiated. Return false otherwise.
+ *
+ * @return
+ */
+ public boolean isStarted() {
+ return serviceInstance != null;
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceException.java
new file mode 100644
index 00000000000..8a48c7f1b50
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceException.java
@@ -0,0 +1,58 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+/**
+ * Root Exception of Services Exception.
+ *
+ * @author dumoulin
+ *
+ */
+public class ServiceException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor.
+ */
+ public ServiceException() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message
+ */
+ public ServiceException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public ServiceException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message
+ * @param cause
+ */
+ public ServiceException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceNotFoundException.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceNotFoundException.java
new file mode 100644
index 00000000000..164899a88a3
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceNotFoundException.java
@@ -0,0 +1,52 @@
+package org.eclipse.papyrus.core.services;
+
+
+/**
+ * Service is not found.
+ *
+ * @author dumoulin
+ *
+ */
+public class ServiceNotFoundException extends ServiceException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor.
+ */
+ public ServiceNotFoundException() {
+ super();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message
+ * @param cause
+ */
+ public ServiceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message
+ */
+ public ServiceNotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public ServiceNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceStartKind.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceStartKind.java
new file mode 100644
index 00000000000..7a772f6cd17
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServiceStartKind.java
@@ -0,0 +1,19 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+
+/**
+ * Kind of possible start method for a service.
+ * LAZY - The service start when it is requested for the first time.
+ * STARTUP - The service start as soon as the registry is started, or when the service is added is the
+ * registry is already started.
+ *
+ * @author dumoulin
+ *
+ */
+public enum ServiceStartKind {
+
+ LAZY, STARTUP;
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServicesRegistry.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServicesRegistry.java
new file mode 100644
index 00000000000..9d47eeadaa2
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/services/ServicesRegistry.java
@@ -0,0 +1,224 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * A registry of services.
+ * This registry allows to get a service by its identifier. The identifier is generally
+ * the classname of the service.
+ * Services can be added using the Eclipse extension mechanism.
+ * A Service is a class providing operations. A service is shared across the editors.
+ *
+ * @author dumoulin
+ *
+ */
+public class ServicesRegistry {
+
+ /** Log object */
+ protected Logger log = Logger.getLogger(getClass().getName());
+
+ /**
+ * Map of existing services.
+ */
+ private Map<Object, AbstractServiceEntry> services;
+
+
+ /**
+ * Constructor.
+ */
+ public ServicesRegistry() {
+ services = new HashMap<Object, AbstractServiceEntry>();
+ }
+
+ /**
+ * Add a service by its ServiceDescriptor.
+ *
+ * @param serviceDescriptor
+ * Descriptor describing the service.
+ * @throws ServiceException
+ * If an error occurs while initializing service.
+ */
+ public void add(ServiceDescriptor serviceDescriptor) {
+ // Check if the service already exist.
+ AbstractServiceEntry service = services.get(serviceDescriptor.getKey());
+ if(service != null) {
+ if(service.getDescriptor().getPriority() > serviceDescriptor.getPriority())
+ return;
+ else if(service.getDescriptor().getPriority() == serviceDescriptor.getPriority())
+ log.warning("Two services with same priority are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
+ }
+
+ // Add the service
+ services.put(serviceDescriptor.getKey(), new ServiceEntry(serviceDescriptor, this));
+ }
+
+ /**
+ * Add a service.
+ * The descriptor will be created.
+ *
+ * @param key
+ * Service key
+ * @param priority
+ * service priority
+ * @param serviceInstance
+ * The instance of the service
+ */
+ public void add(Object key, int priority, IService serviceInstance) {
+ // Check if the service already exist.
+ AbstractServiceEntry service = services.get(key);
+ if(service != null) {
+ if(service.getDescriptor().getPriority() > priority)
+ return;
+ else if(service.getDescriptor().getPriority() == priority)
+ log.warning("Two services with same priority are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
+ }
+
+ // Create descriptor and add service.
+ ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), ServiceStartKind.STARTUP, priority);
+ services.put(key, new ServiceEntry(descriptor, serviceInstance));
+
+ }
+
+ /**
+ * Add an already instanciated pojo (Plain Old Java Object) as Service.
+ * The descriptor will be created.
+ * No life cycle methods are called on the service.
+ *
+ * @param key
+ * Service key
+ * @param priority
+ * service priority
+ * @param serviceInstance
+ * The instance of the service
+ */
+ public void add(Object key, int priority, Object serviceInstance) {
+ // Check if the service already exist.
+ AbstractServiceEntry service = services.get(key);
+ if(service != null) {
+ if(service.getDescriptor().getPriority() > priority)
+ return;
+ else if(service.getDescriptor().getPriority() == priority)
+ log.warning("Two services with same priority are declared under key '" + service.getDescriptor().getKey() + "'. Keep the first encountered only.");
+ }
+
+ // Create descriptor and add service.
+ ServiceDescriptor descriptor = new ServiceDescriptor(key, serviceInstance.getClass().getName(), ServiceStartKind.STARTUP, priority);
+ services.put(key, new PojoServiceEntry(descriptor, serviceInstance));
+
+ }
+
+ /**
+ * Remove the specified service from the registry.
+ *
+ * @param key
+ */
+ public void remove(ServiceDescriptor serviceDescriptor) throws ServiceException {
+ remove(serviceDescriptor.getKey());
+ }
+
+ /**
+ * Remove the specified service from the registry.
+ *
+ * @param key
+ */
+ public void remove(Object key) throws ServiceException {
+ AbstractServiceEntry service = services.remove(key);
+ if(service == null) {
+ return;
+ }
+
+ // Stop the service
+ service.disposeService();
+ }
+
+ /**
+ * Get the requested service by its key.
+ * The key is usually the classname of the service.
+ *
+ * @param serviceClass
+ * @return
+ * @throws ServiceException
+ * If servive can't be started
+ */
+ public Object getService(Object key) throws ServiceException {
+ AbstractServiceEntry service = services.get(key);
+ if(service == null) {
+ throw new ServiceNotFoundException("No service registered under '" + key + "'");
+ }
+
+ return service.getServiceInstance();
+ }
+
+ /**
+ * Get the requested service by its class (the servce has to be registered by its class object).
+ *
+ * @param key
+ * The service class.
+ * @return The service.
+ * @throws ServiceException
+ * If service can't be started
+ */
+ @SuppressWarnings("unchecked")
+ public <S> S getService(Class<S> key) throws ServiceException {
+ AbstractServiceEntry service = services.get(key);
+ if(service == null) {
+ throw new ServiceNotFoundException("No service registered under '" + key + "'");
+ }
+
+ return (S)service.getServiceInstance();
+ }
+
+ /**
+ * Return true if the service is instantiated. Return false otherwise.
+ *
+ * @return
+ */
+ public boolean isStarted(Object key) throws ServiceNotFoundException {
+ AbstractServiceEntry service = services.get(key);
+ if(service == null) {
+ throw new ServiceNotFoundException("No service registered under '" + key + "'");
+ }
+
+ return service.isStarted();
+ }
+
+ /**
+ * Start the registry.
+ * Start all services marked as start = STARTUP are started.
+ * Then, method start() is called on all IService.
+ * Start services marked as start = STARTUP.
+ *
+ * @throws ServiceException
+ * If a service can't be started.
+ */
+ public void startRegistry() {
+ for(AbstractServiceEntry serviceEntry : services.values()) {
+ try {
+ serviceEntry.startup();
+ } catch (ServiceException e) {
+ log.log(Level.SEVERE, "Can't init service '" + serviceEntry + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Dispose all services.
+ */
+ public void disposeService() {
+ for(AbstractServiceEntry serviceDesc : services.values()) {
+ try {
+ serviceDesc.disposeService();
+ } catch (ServiceException e) {
+ log.log(Level.SEVERE, "Can't dispose service '" + serviceDesc + "'", e);
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/BusinessModelResolver.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/BusinessModelResolver.java
new file mode 100644
index 00000000000..bbd65bd5eae
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/BusinessModelResolver.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.core.utils;
+
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.notation.View;
+
+
+/**
+ * This class allows to retrieve the bussiness object from an object representing a graphical artefact in a diagram. Each diagram can register its
+ * resolver which will be added to the list of
+ * resolvers. Some common resolvers are already registered : gef.EditPart TODO Use extensions to register additional resolvers.
+ */
+public class BusinessModelResolver {
+
+ /**
+ * The unique instance
+ */
+ public static BusinessModelResolver instance = new BusinessModelResolver();
+
+ public BusinessModelResolver() {
+
+ }
+
+ /**
+ * Get the bussiness object associated to this object, if any. This method navigate throw the object if the object is an graphical artefact or a
+ * diagram artefact.
+ *
+ * @param object
+ * @return Object
+ */
+ public Object getBusinessModel(Object object) {
+ if(object instanceof EditPart) {
+ // Check model. It can be a GraphNode.
+ Object model = ((EditPart)object).getModel();
+ if(model instanceof View) { // Notation / GMF
+ return getBusinessElement((View)((EditPart)object).getModel());
+ } else
+ return model;
+ } else if(object instanceof View) {
+ return ((View)object).getElement();
+ }
+
+ else
+ return object;
+
+ }
+
+
+ /**
+ * Get the business object from a GraphElement.
+ *
+ * @param object
+ * @return
+ */
+ protected Object getBusinessElement(View object) {
+ try {
+ return object.getElement();
+ } catch (NullPointerException e) {
+ // no bussiness element
+ return null;
+ }
+ }
+
+ /**
+ * Get the graphical object accessible from to this diagram object, if any.
+ *
+ * @param object
+ * @return Object
+ */
+ public Object getGraphicalModel(Object object) {
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ /**
+ * @return BusinessModelResolver
+ */
+ public static BusinessModelResolver getInstance() {
+ return instance;
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/DiResourceSet.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/DiResourceSet.java
new file mode 100644
index 00000000000..d3b1e70f92a
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/DiResourceSet.java
@@ -0,0 +1,398 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+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.impl.ResourceSetImpl;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.papyrus.core.listenerservice.ModelListenerManager;
+
+/**
+ * ResourceSet Manager for UML and DI files, and also other loaded models.
+ *
+ * @author Cedric dumoulin
+ * @author <a href="mailto:jerome.benois@obeo.fr">Jerome Benois</a>
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
+ */
+public class DiResourceSet extends ResourceSetImpl {
+
+ /** File extension used for DI. */
+ public static final String DI_FILE_EXTENSION = "di"; //$NON-NLS-1$
+
+ /** File extension used for notation. */
+ public static final String NOTATION_FILE_EXTENSION = "notation"; //$NON-NLS-1$
+
+ /** File extension used for Model */
+ private String modelFileExtension; //$NON-NLS-1$
+
+ /** The model resource */
+ private Resource modelResource;
+
+ /** The DI resource */
+ private Resource diResource;
+
+ /** The notation resource */
+ private Resource notationResource;
+
+ /** URI of the model resource */
+ private URI modelURI;
+
+ /** URI of the notation resource */
+ private URI notationURI;
+
+ /** URI of the di resource */
+ private URI diURI;
+
+ /** The transactional editing domain. */
+ private TransactionalEditingDomain transactionalEditingDomain;
+
+ /** The proxy manager that loads the model according to a specific strategy. */
+ private ProxyManager proxyManager;
+
+ public DiResourceSet() {
+ super();
+ GMFResourceFactory gmfFactory = new GMFResourceFactory();
+ getResourceFactoryRegistry().getExtensionToFactoryMap().put(NOTATION_FILE_EXTENSION, gmfFactory);
+ proxyManager = new ProxyManager();
+ }
+
+ /**
+ * Just loads the model into the current resource set.
+ *
+ * @returns The loaded model.
+ */
+ public Resource loadModelResource(URI uri) {
+ // FIXME maybe check that model is null ?!
+ modelResource = getResource(uri, true);
+ modelFileExtension = modelResource.getURI().fileExtension();
+ return getModelResource();
+ }
+
+ /**
+ * Returns the extension of the model
+ */
+ public String getModelFileExtension() {
+ if(modelFileExtension == null) {
+ modelFileExtension = modelResource.getURI().fileExtension();
+ }
+ return modelFileExtension;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EObject getEObject(URI uri, boolean loadOnDemand) {
+ // do we have to override getResource ?
+ URI resourceURI = uri.trimFragment();
+ if(resourceURI.equals(modelURI) || resourceURI.equals(notationURI) || resourceURI.equals(diURI)) {
+ // do not manage eObject of the initial resources
+ return super.getEObject(uri, loadOnDemand);
+ } else {
+ // use ProxyManager to resolve proxies according to the strategy
+ String fragment = uri.fragment() ;
+ EObject result = null ;
+ // overrided method is called
+ loadOnDemand = proxyManager.loadResource(uri);
+ Resource r = getResource(resourceURI, loadOnDemand);
+ if (r != null)
+ {
+ result = r.getEObject(fragment);
+ }
+ // if load on demand = true and result = null it's time to start router exploration !
+ if (result == null && loadOnDemand)
+ {
+ // router manager
+ // retrieve di of the loaded resource
+ // browse route map and get the target resource
+ // !!! does the policy authorize the loading of the new resource ?
+ // is it normal to have object = null ?
+ }
+ // search element
+ return result;
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getResource(org.eclipse.emf.common.util.URI, boolean)
+ */
+ @Override
+ public Resource getResource(URI uri, boolean loadOnDemand) {
+ if (loadOnDemand)
+ {
+ loadOnDemand = proxyManager.loadResource(uri);
+ }
+ return super.getResource(uri, loadOnDemand);
+ }
+
+ /**
+ * Load both files (DI and UML) from an handle on one of the two files.
+ *
+ * @param file
+ * The file to load (no matter the extension)
+ */
+ public void loadResources(IFile file) {
+ // Extract file name, without extension
+ IPath fullPath = file.getFullPath().removeFileExtension();
+
+ // load DI2
+ diURI = getPlatformURI(fullPath.addFileExtension(DI_FILE_EXTENSION));
+ diResource = getResource(diURI, true);
+
+ // load notation
+ notationURI = getPlatformURI(fullPath.addFileExtension(NOTATION_FILE_EXTENSION));
+ notationResource = getResource(notationURI, true);
+
+ if(notationResource != null) {
+ // look for a model associated with a diagram in notation
+ for(EObject eObject : notationResource.getContents()) {
+ if(eObject instanceof Diagram) {
+ Diagram diagram = (Diagram)eObject;
+ if(diagram.getElement() != null) {
+ modelResource = diagram.getElement().eResource();
+ break;
+ }
+ }
+ }
+ }
+
+
+ // if modelResource is still null, we look for a file with the same name and a supported extension
+ if(modelResource == null) {
+ IContainer folder = file.getParent();
+ try {
+ IResource[] files = folder.members();
+ for(IResource r : files) {
+ String extension = r.getFullPath().getFileExtension();
+ if(r.getFullPath().removeFileExtension().lastSegment().equals(fullPath.lastSegment()) && !DI_FILE_EXTENSION.equalsIgnoreCase(extension) && !NOTATION_FILE_EXTENSION.equalsIgnoreCase(extension)) {
+ if(Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().get(extension) != null) {
+ modelURI = getPlatformURI(r.getFullPath());
+ modelResource = getResource(modelURI, true);
+ break;
+ }
+ }
+ }
+ } catch (CoreException e) {
+ // never happens.
+ }
+ }
+
+ modelFileExtension = modelResource.getURI().fileExtension();
+
+ // TODO move next line away from DiResourceSet ? Define a place
+ // where Resource initialization can take place.
+ modelResource.eAdapters().add(new ModelListenerManager());
+ }
+
+ /**
+ * Unload all the resources.
+ */
+ public void unload() {
+ for(Iterator<Resource> iter = getResources().iterator(); iter.hasNext();) {
+ iter.next().unload();
+ iter.remove();
+ }
+ diResource = null;
+ modelResource = null;
+ notationResource = null;
+ }
+
+ /**
+ * Create both files (DI and UML) from a filename.
+ *
+ * @param newFile
+ * The file from which path is extracted to create the new files
+ */
+ public void createModelResources(IFile newFile, String eContentType, String modelExtension) {
+
+ // create the di resource URI
+ URI diUri = getPlatformURI(newFile.getFullPath());
+ // Create the di Resource for the sashcontainer
+ // The model will be automatically initialized by the SashContainer if needed (if it is empty).
+ // Normally the resource should contains models set by previous use from the SashContainer
+ diResource = createResource(diUri);
+
+ IPath filenameWithoutExtension = newFile.getFullPath().removeFileExtension();
+ // if the model is not loaded, create resource
+ if(modelResource == null) {
+ // create the model URI
+ URI modelUri = getPlatformURI(filenameWithoutExtension.addFileExtension(modelExtension));
+ // create the model resource
+ modelResource = createResource(modelUri, eContentType);
+ this.modelFileExtension = modelExtension;
+ }
+ // create the notation URI
+ URI notationURI = getPlatformURI(filenameWithoutExtension.addFileExtension(NOTATION_FILE_EXTENSION));
+ // create the notation resource
+ notationResource = createResource(notationURI);
+
+ }
+
+ /**
+ * Get a platform resource URI of the given path
+ *
+ * @param path
+ * the path
+ * @return the uri
+ */
+ private URI getPlatformURI(IPath path) {
+ return URI.createPlatformResourceURI(path.toString(), true);
+ }
+
+ /**
+ * Save the resources.
+ *
+ * @param monitor
+ * The monitor.
+ * @throws IOException
+ * IO Error.
+ */
+ public void save(IProgressMonitor monitor) throws IOException {
+ monitor.beginTask("Saving resources", 3);
+ try {
+ // save associated resources
+ modelResource.save(null);
+ monitor.worked(1);
+ diResource.save(null);
+ monitor.worked(1);
+ notationResource.save(null);
+ monitor.worked(1);
+ } finally {
+ monitor.done();
+ }
+ }
+
+ /**
+ * The resources are already loaded, but we want to save them under another name.
+ *
+ * @param path
+ * @throws IOException
+ */
+ public void saveAs(IPath path) throws IOException {
+ IPath nameWithoutExt = path.removeFileExtension();
+ IPath modelPath = nameWithoutExt.addFileExtension(getModelFileExtension());
+ IPath notationPath = nameWithoutExt.addFileExtension(NOTATION_FILE_EXTENSION);
+ IPath diPath = nameWithoutExt.addFileExtension(DI_FILE_EXTENSION);
+
+ // Set model URI
+ URI modelUri = getPlatformURI(modelPath);
+ modelResource.setURI(modelUri);
+
+ // Set notation URI
+ URI notationURI = getPlatformURI(notationPath);
+ notationResource.setURI(notationURI);
+
+ // set di uri
+ URI diUri = getPlatformURI(diPath);
+ diResource.setURI(diUri);
+
+ save(new NullProgressMonitor());
+ }
+
+ /**
+ * Returns the notation resource.
+ *
+ * @return the notationResource
+ */
+ public Resource getNotationResource() {
+ return notationResource;
+ }
+
+ /**
+ *
+ *
+ * @return the diResource
+ */
+ public Resource getDiResource() {
+ return diResource;
+ }
+
+ /**
+ * Returns the model resource.
+ *
+ * @return the modelResource
+ */
+ public Resource getModelResource() {
+ return modelResource;
+ }
+
+ /**
+ * Returns the additional resources.
+ *
+ * @return The additional resources.
+ */
+ public List<Resource> getAdditionalResources() {
+ List<Resource> additionnalResources = new ArrayList<Resource>();
+ for(Resource resource : getResources()) {
+ // ignore di, notation and domain resources
+ if(resource != diResource && resource != notationResource && resource != modelResource) {
+ additionnalResources.add(resource);
+ }
+ }
+
+ return additionnalResources;
+ }
+
+ /**
+ * Create the transactional editing domain
+ */
+ public TransactionalEditingDomain getTransactionalEditingDomain() {
+ transactionalEditingDomain = TransactionalEditingDomain.Factory.INSTANCE.getEditingDomain(this);
+ if(transactionalEditingDomain == null) {
+ transactionalEditingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(this);
+ // What for?
+ transactionalEditingDomain.setID("SharedEditingDomain"); //$NON-NLS-1$
+ }
+ return transactionalEditingDomain;
+ }
+
+ /**
+ * Returns the related di file.
+ *
+ * @param file
+ * A file (di, model or notation).
+ * @return The associated DI file.
+ */
+ public static IFile getRelatedDiFile(IFile file) {
+ if(file == null) {
+ return null;
+ }
+ IFile diFile;
+ if(DI_FILE_EXTENSION.equalsIgnoreCase(file.getFileExtension())) {
+ diFile = file;
+ } else {
+ // Find the correct file
+ IPath diPath = file.getFullPath().removeFileExtension().addFileExtension(DiResourceSet.DI_FILE_EXTENSION);
+ diFile = file.getParent().getFile(diPath.makeRelativeTo(file.getParent().getFullPath()));
+ }
+ return diFile;
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/EditorUtils.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/EditorUtils.java
new file mode 100644
index 00000000000..065fc50f978
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/EditorUtils.java
@@ -0,0 +1,308 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>: Code simplification and NPE
+ * management.
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import static org.eclipse.papyrus.core.Activator.log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.papyrus.core.editor.CoreMultiDiagramEditor;
+import org.eclipse.papyrus.core.editor.IMultiDiagramEditor;
+import org.eclipse.papyrus.core.services.ServiceException;
+import org.eclipse.papyrus.core.services.ServicesRegistry;
+import org.eclipse.papyrus.sasheditor.contentprovider.ISashWindowsContentProvider;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.DiSashModelMngr;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.IPageMngr;
+import org.eclipse.papyrus.sasheditor.contentprovider.di.TransactionalDiSashModelMngr;
+import org.eclipse.papyrus.sasheditor.editor.IPage;
+import org.eclipse.papyrus.sasheditor.editor.ISashWindowsContainer;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Set of utility methods for the CoreEditor.
+ *
+ * WARNING : Some of these methods rely on PlatformUI.getWorkbench().getActiveWorkbenchWindow()getActivePage() to
+ * lookup for shared objects owned by the main editor. This doesn't work during the initialization of the main editor
+ * because the main editor is not yet registered in the Eclipse workbench. This can lead to a null or an exception,
+ * and sometime this can lead to getting the shared object of another main editor !
+ *
+ * @author cedric dumoulin
+ * @author <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>
+ */
+// FIXME throws Exception (eg: NotFoundException) instead of null
+public class EditorUtils {
+
+ /**
+ * Gets the multi diagram editor.
+ *
+ * @return Get the current {@link IMultiDiagramEditor} or null if not found.
+ */
+ public static IMultiDiagramEditor getMultiDiagramEditor() {
+ // Lookup ServiceRegistry
+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if(workbenchWindow == null) {
+ return null;
+ }
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ if(page == null) {
+ return null;
+ }
+ IEditorPart editor = page.getActiveEditor();
+ if(editor instanceof IMultiDiagramEditor) {
+ return (IMultiDiagramEditor)editor;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the opened multi-diagram editors.
+ *
+ * @return The opened {@link IMultiDiagramEditor} or null if an error occured.
+ */
+ public static IMultiDiagramEditor[] getMultiDiagramEditors() {
+ // Lookup ServiceRegistry
+ IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if(workbenchWindow == null) {
+ return null;
+ }
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ if(page == null) {
+ return null;
+ }
+ List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>();
+ for(IEditorReference editorRef : page.getEditorReferences()) {
+ IEditorPart editorPart = editorRef.getEditor(false);
+ if(editorPart instanceof IMultiDiagramEditor) {
+ list.add((IMultiDiagramEditor)editorPart);
+ }
+ }
+ return list.toArray(new IMultiDiagramEditor[list.size()]);
+ }
+
+ /**
+ * Returns the editors that are related to to given file.<BR>
+ *
+ * @param file
+ * The file (model, di or notation).
+ * @return The associated editors.
+ */
+ public static IMultiDiagramEditor[] getRelatedEditors(IFile file) {
+ // Get the DI file
+ IFile diFile = DiResourceSet.getRelatedDiFile(file);
+ if(diFile == null || !diFile.exists()) {
+ return new IMultiDiagramEditor[0];
+ }
+
+ IMultiDiagramEditor[] openedEditors = EditorUtils.getMultiDiagramEditors();
+ if(openedEditors == null) {
+ return new IMultiDiagramEditor[0];
+ }
+ List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>(openedEditors.length);
+
+ for(IMultiDiagramEditor editorPart : openedEditors) {
+ if(editorPart.getEditorInput() instanceof IFileEditorInput && diFile.equals(((IFileEditorInput)editorPart.getEditorInput()).getFile())) {
+ list.add(editorPart);
+ }
+ }
+ return list.toArray(new IMultiDiagramEditor[list.size()]);
+ }
+
+ /**
+ * Get the service registry of the currently active main editor.
+ * <br>
+ * WARNING - This method doesn't work during the initialization of the main editor. See note in class doc.
+ *
+ * @return The {@link ServicesRegistry} or null if not found.
+ */
+ static public ServicesRegistry getServiceRegistry() {
+ // Lookup ServiceRegistry
+ IMultiDiagramEditor editor = getMultiDiagramEditor();
+ return editor == null ? null : (ServicesRegistry)editor.getAdapter(ServicesRegistry.class);
+ }
+
+ /**
+ * Get the ISashWindowsContentProvider from the main editor.
+ *
+ * @return the ISashWindowsContentProvider from the main editor or null if not found.
+ */
+ static public ISashWindowsContentProvider getISashWindowsContentProvider() {
+ IEditorPart editorPart = getMultiDiagramEditor();
+ return editorPart == null ? null : (ISashWindowsContentProvider)editorPart.getAdapter(ISashWindowsContentProvider.class);
+
+ }
+
+ /**
+ * Get the ISashWindowsContentProvider from the main editor.
+ *
+ * @return the ISashWindowsContentProvider from the main editor or null if not found.
+ */
+ public static IPageMngr getIPageMngr() {
+ IMultiDiagramEditor editorPart = getMultiDiagramEditor();
+ return editorPart == null ? null : (IPageMngr)editorPart.getAdapter(IPageMngr.class);
+ }
+
+ /**
+ * Get the Eclipse ActiveEditor.
+ *
+ * @return The active {@link CoreMultiDiagramEditor} or null if not found.
+ * @deprecated Use {@link EditorUtils#getMultiDiagramEditor()}
+ */
+ @Deprecated
+ public static IEditorPart getWorkbenchActiveEditor() {
+ IMultiDiagramEditor editorPart = getMultiDiagramEditor();
+ if(editorPart instanceof CoreMultiDiagramEditor) {
+ return editorPart;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Create an instance of IPageMngr acting on the provided resource.
+ * This instance is suitable to add, remove, close or open diagrams.
+ *
+ * @param diResource
+ * @return The non transactional implementation of IPageMngr
+ */
+ public static IPageMngr getIPageMngr(Resource diResource) {
+ return DiSashModelMngr.createIPageMngr(diResource);
+ }
+
+ /**
+ * Create an instance of IPageMngr acting on the provided resource.
+ * This instance is suitable to add, remove, close or open diagrams.
+ *
+ * @param diResource
+ * @param editingDomain
+ *
+ * @return The transactional implementation of IPageMngr
+ */
+ public static IPageMngr getTransactionalIPageMngr(Resource diResource, TransactionalEditingDomain editingDomain) {
+ return TransactionalDiSashModelMngr.createIPageMngr(diResource, editingDomain);
+ }
+
+ /**
+ * Lookup the currently active Diagram from the Papyrus editor. Return the current Diagram
+ * or null if none is active.
+ * TODO This method introduce dependency on GMF. It can be moved to a GMF plugin.
+ *
+ * @return The active diagram or null if not found.
+ */
+ public static Diagram lookupEditorActiveDiagram() {
+ DiagramEditor diagEditor = lookupActiveDiagramEditor();
+ return diagEditor == null ? null : diagEditor.getDiagram();
+ }
+
+ /**
+ * Lookup the currently active Diagram from the Papyrus editor. Return the current Diagram or
+ * null if none is active.
+ * TODO This method introduce dependency on GMF. It can be moved to a GMF plugin.
+ *
+ * @return the active diagram editor or null if not found.
+ */
+ public static DiagramEditor lookupActiveDiagramEditor() {
+ // Get the active page within the sashcontainer
+ IEditorPart activeEditor = lookupSashSystemActiveIEditor();
+ // Check if it is a GMF DiagramEditor
+ if(activeEditor instanceof DiagramEditor) {
+ return ((DiagramEditor)activeEditor);
+ } else {
+ // Not found
+ return null;
+ }
+
+ }
+
+ /**
+ * Lookup the currently active Diagram from the Papyrus editor. Return the current Diagram
+ * or null if none is active.
+ * TODO This method introduce dependency on GMF. It can be moved to a GMF plugin.
+ *
+ * @return
+ */
+ private static IEditorPart lookupSashSystemActiveIEditor() {
+ // Get the sashwindow container
+ ISashWindowsContainer container = getSashWindowContainer();
+ // Get the active page within the sashcontainer
+ return container == null ? null : container.getActiveEditor();
+ }
+
+ /**
+ * Lookup the currently active IEditor in the SashSystem.
+ * If the currently eclipse active editor doesn't contains a {@link ISashWindowsContainer}, return null.
+ * If the current SashSystem page is not a IEditor, return null.
+ *
+ * @return
+ */
+ public static IPage lookupSashSystemActivePage() {
+ // Get the sashwindow container
+ ISashWindowsContainer container = getSashWindowContainer();
+ // Get the active page within the sashcontainer
+ return container == null ? null : container.getActiveSashWindowsPage();
+ }
+
+ private static ISashWindowsContainer getSashWindowContainer() {
+ // First, lookup the main editor.
+ IMultiDiagramEditor editorPart = getMultiDiagramEditor();
+ // Get the sashwindow container
+ return editorPart == null ? null : (ISashWindowsContainer)editorPart.getAdapter(ISashWindowsContainer.class);
+ }
+
+ /**
+ * Gets the di resource set.
+ *
+ * @return Get the current {@link DiResourceSet} or null if not found.
+ */
+ public static DiResourceSet getDiResourceSet() {
+ try {
+ ServicesRegistry registry = getServiceRegistry();
+ return registry == null ? null : registry.getService(DiResourceSet.class);
+ } catch (ServiceException e) {
+ log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Gets the transactional editing domain.
+ *
+ * @return Get the current {@link TransactionalEditingDomain} or null if not found
+ */
+ public static TransactionalEditingDomain getTransactionalEditingDomain() {
+ try {
+ ServicesRegistry registry = getServiceRegistry();
+ return registry == null ? null : registry.getService(TransactionalEditingDomain.class);
+ } catch (IllegalStateException e) {
+ // Registry can't be found, do nothing.
+ } catch (ServiceException e) {
+ log.error(e);
+ }
+ return null;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionView.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionView.java
new file mode 100644
index 00000000000..172aef6d65d
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionView.java
@@ -0,0 +1,213 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A unmodifiable view on a specified list. The view filters the original list according to the provided filter.
+ */
+public class FilteredCollectionView<T> extends AbstractCollection<T> implements Collection<T> {
+
+ /** The original collection */
+ private Collection<T> list;
+
+ /** The filter for the view */
+ private IFilter filter;
+
+ /**
+ * The cached size. Compute only once, so change in the underlying collection is not reflected
+ */
+ private int size = -1;
+
+ /**
+ * Creates a new FilteredCollectionView.
+ *
+ * @param list
+ * the list to filter
+ * @param filter
+ * the filter for the view
+ */
+ public FilteredCollectionView(Collection<T> list, IFilter filter) {
+ this.list = list;
+ this.filter = filter;
+ }
+
+ /**
+ * Sets the value of the list property.
+ *
+ * @param aList
+ * the new value of the list property
+ */
+ public void setBackupCollection(Collection<T> aList) {
+ list = aList;
+ }
+
+ /**
+ * Sets the value of the filter property.
+ *
+ * @param aFilter
+ * the new value of the filter property
+ */
+ public void setFilter(IFilter aFilter) {
+ filter = aFilter;
+ }
+
+ /**
+ * Returns the value of the filter property.
+ *
+ * @return the new value of the filter property
+ */
+ public IFilter getFilter() {
+ return filter;
+ }
+
+ /**
+ * The size of the filtered list.
+ *
+ * @return the number of elements in the filtered list
+ */
+ @Override
+ public int size() {
+ if(size == -1) { // compute the size
+ size = 0;
+ Iterator<T> i = iterator();
+ while(i.hasNext()) {
+ size++;
+ i.next();
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Return true if the filteredCollection contains the object.
+ *
+ * @see java.util.AbstractCollection#contains(java.lang.Object)
+ * @param o
+ * @return
+ *
+ */
+ @Override
+ public boolean contains(Object o) {
+ return list.contains(o);
+ }
+
+
+ /**
+ * remove the object.
+ * Throw an UnsupportedOperationException, as the FilteredCollection is ReadOnly.
+ *
+ * @see java.util.AbstractCollection#remove(java.lang.Object)
+ * @param o
+ * @return
+ *
+ */
+ @Override
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the value to be returned by the iterator.next() method. This method can be overloaded by subclasses in order to return another value
+ * than the objects belonging to the underlying list.
+ *
+ * @param ele
+ * The iterated object. This is the object iterated inside the underlying list.
+ * @return
+ */
+ protected T returnedValue(T ele) {
+ return ele;
+ }
+
+ /**
+ * listIterator.
+ *
+ * @return ListIterator
+ */
+ @Override
+ public Iterator<T> iterator() {
+ return new FilteredIterator();
+ }
+
+ /**
+ * Iterator other the filtered collection
+ */
+ private class FilteredIterator implements Iterator<T> {
+
+ /** the next object */
+ T next;
+
+ /** The original list iterator */
+ Iterator<T> listIterator;
+
+ /**
+ * Creates a new FilteredIterator
+ */
+ public FilteredIterator() {
+ listIterator = list.iterator();
+ next = nextFilteredObject();
+ }
+
+ /**
+ * Unsupported operation, as this is just a view of a list.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the next object of the list, when filter is applied
+ *
+ * @return
+ */
+ protected T nextFilteredObject() {
+ while(listIterator.hasNext()) {
+ T ele = listIterator.next();
+ if(filter.isAllowed(ele)) {
+ return returnedValue(ele);
+ }
+ } // end loop
+ return null;
+ }
+
+ /**
+ * hasNext.
+ *
+ * @return boolean
+ */
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ /**
+ * Compute the next field (null or next value), and return the previous value of the next field.
+ *
+ * @return Object
+ */
+ public T next() {
+ if(next == null) {
+ throw new NoSuchElementException();
+ }
+ T ele = next;
+ next = nextFilteredObject();
+ return ele;
+ }
+
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionViewFromIterator.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionViewFromIterator.java
new file mode 100644
index 00000000000..d9363d945f7
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredCollectionViewFromIterator.java
@@ -0,0 +1,248 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+//Source file: H:\\temp\\generated\\modTransf\\util\\FilteredListView.java
+package org.eclipse.papyrus.core.utils;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A unmodifiable view on a specified list from its iterator. The view filters the original list according to the provided filter.
+ *
+ * @param <E>
+ * the type of objects in the filtered collection
+ */
+public class FilteredCollectionViewFromIterator<E> extends AbstractCollection<E> implements Collection<E> {
+
+ /**
+ * The iterator provider linked to the backup list.
+ */
+ private IteratorProvider<E> iter;
+
+ /**
+ *
+ */
+ private IFilter filter;
+
+ /**
+ * The cached size. Compute only once, so change in the underlying collection is not reflected
+ */
+ private int size = -1;
+
+ /**
+ *
+ *
+ * @param filter
+ * @param list
+ * *
+ * @param iter
+ */
+ public FilteredCollectionViewFromIterator(IteratorProvider<E> iter, IFilter filter) {
+ this.iter = iter;
+ this.filter = filter;
+ }
+
+ /**
+ * Sets the value of the list property.
+ *
+ * @param iter
+ * the new value of the list property
+ */
+ public void setBackupCollection(IteratorProvider<E> iter) {
+ this.iter = iter;
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ Iterator<E> getBackupIterator() {
+ return iter.iterator();
+ }
+
+ /**
+ * Sets the value of the filter property.
+ *
+ * @param aFilter
+ * the new value of the filter property
+ */
+ public void setFilter(IFilter aFilter) {
+ filter = aFilter;
+ }
+
+ /**
+ * Sets the value of the filter property.
+ *
+ * @return the new value of the filter property
+ */
+ public IFilter getFilter() {
+ return filter;
+ }
+
+ /**
+ * size.
+ *
+ * @return int
+ */
+ @Override
+ public int size() {
+ if(size == -1) { // compute the size
+ size = 0;
+ Iterator<E> i = iterator();
+ while(i.hasNext()) {
+ size++;
+ i.next();
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Removes a single instance of the specified element from this collection, if it is present (optional operation). More formally, removes an
+ * element <tt>e</tt> such that <tt>(o==null ? e==null :
+ * o.equals(e))</tt>, if the collection contains one or more such elements. Returns <tt>true</tt> if the collection contained the specified
+ * element (or equivalently, if the collection changed as a
+ * result of the call).
+ * <p>
+ *
+ * This implementation call the remove method on the underlying collection.
+ * <p>
+ *
+ * @param o
+ * element to be removed from this collection, if present.
+ *
+ * @return <tt>true</tt> if the collection contained the specified element.
+ *
+ * @throws UnsupportedOperationException
+ * if the <tt>remove</tt> method is not supported by this collection.
+ */
+ @Override
+ public boolean remove(Object o) {
+ // return list.remove(o);
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Return the value to be returned by the iterator.next() method. This method can be overloaded by subclasses in order to return another value
+ * than the objects belonging to the underlying list.
+ *
+ * @param ele
+ * The iterated object. This is the object iterated inside the underlying list.
+ *
+ * @return
+ */
+ protected E returnedValue(E ele) {
+ return ele;
+ }
+
+ /**
+ * listIterator.
+ *
+ * @param index
+ * int
+ *
+ * @return ListIterator
+ */
+ @Override
+ public Iterator<E> iterator() {
+ return new FilteredIterator();
+ }
+
+ /**
+ *
+ */
+ private class FilteredIterator implements Iterator<E> {
+
+ /**
+ *
+ */
+ E next;
+
+ /**
+ *
+ */
+ Iterator<E> listIterator;
+
+ /**
+ *
+ */
+ public FilteredIterator() {
+ listIterator = getBackupIterator();
+ next = nextFilteredObject();
+ }
+
+ /**
+ * remove.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ protected E nextFilteredObject() {
+ while(listIterator.hasNext()) {
+ E ele = listIterator.next();
+ if(filter.isAllowed(ele)) {
+ return returnedValue(ele);
+ }
+ } // end loop
+ return null;
+ }
+
+ /**
+ * hasNext.
+ *
+ * @return boolean
+ */
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ /**
+ * Compute the next field (null or next value), and return the previous value of the next field.
+ *
+ * @return Object
+ */
+ public E next() {
+ if(next == null) {
+ throw new NoSuchElementException();
+ }
+ E ele = next;
+ next = nextFilteredObject();
+ return ele;
+ }
+
+ }
+
+ /**
+ * Inner class. Provide an iterator used internally in the unmodifiable collection view..
+ */
+ public interface IteratorProvider<E> {
+
+ /**
+ * provide a new iterator over the list.
+ *
+ * @return
+ */
+ Iterator<E> iterator();
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredListView.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredListView.java
new file mode 100644
index 00000000000..bfe10ce9d9d
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/FilteredListView.java
@@ -0,0 +1,369 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import java.util.AbstractSequentialList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A unmodifiable view on a specified list. The view filters the original list according to the provided filter.
+ */
+public class FilteredListView extends AbstractSequentialList<Object> implements List<Object> {
+
+ /**
+ *
+ */
+ private List<Object> list;
+
+ /**
+ *
+ */
+ private IFilter filter;
+
+ /**
+ * The cached size. Copute only once, so change in the underlying collection is not reflected
+ */
+ private int size = -1;
+
+ /**
+ *
+ *
+ * @param filter
+ * @param list
+ */
+ public FilteredListView(List<Object> list, IFilter filter) {
+ this.list = list;
+ this.filter = filter;
+ }
+
+ /**
+ * Sets the value of the list property.
+ *
+ * @param aList
+ * the new value of the list property
+ */
+ public void setBackupList(List aList) {
+ list = aList;
+ }
+
+ /**
+ * Sets the value of the filter property.
+ *
+ * @param aFilter
+ * the new value of the filter property
+ */
+ public void setFilter(IFilter aFilter) {
+ filter = aFilter;
+ }
+
+ /**
+ * size.
+ *
+ * @return int
+ */
+ @Override
+ public int size() {
+ if(size == -1) { // compute the size
+ size = 0;
+ Iterator<Object> i = iterator();
+ while(i.hasNext()) {
+ size++;
+ i.next();
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Returns <tt>true</tt> if this collection contains the specified element. More formally, returns <tt>true</tt> if and only if this collection
+ * contains at least one element <tt>e</tt> such that <tt>(o==null ? e==null : o.equals(e))</tt>.
+ * <p>
+ *
+ * @param o
+ * object to be checked for containment in this collection.
+ *
+ * @return <tt>true</tt> if this collection contains the specified element.
+ */
+ @Override
+ public boolean contains(Object o) {
+ return list.contains(o);
+ }
+
+ /**
+ * Removes a single instance of the specified element from this collection, if it is present (optional operation). More formally, removes an
+ * element <tt>e</tt> such that <tt>(o==null ? e==null :
+ * o.equals(e))</tt>, if the collection contains one or more such elements. Returns <tt>true</tt> if the collection contained the specified
+ * element (or equivalently, if the collection changed as a
+ * result of the call).
+ * <p>
+ *
+ * This implementation call the remove method on the underlying collection.
+ * <p>
+ *
+ * @param o
+ * element to be removed from this collection, if present.
+ *
+ * @return <tt>true</tt> if the collection contained the specified element.
+ *
+ * @throws UnsupportedOperationException
+ * if the <tt>remove</tt> method is not supported by this collection.
+ */
+ @Override
+ public boolean remove(Object o) {
+ // return list.remove(o);
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * listIterator.
+ *
+ * @param index
+ * int
+ *
+ * @return ListIterator
+ */
+ @Override
+ public ListIterator<Object> listIterator(int index) {
+ return new FilteredListIterator(index);
+ }
+
+ /**
+ *
+ */
+ private class FilteredListIterator implements ListIterator<Object> {
+
+ /**
+ *
+ */
+ Object current;
+
+ /**
+ *
+ */
+ Object next;
+
+ /**
+ *
+ */
+ Object previous;
+
+ /**
+ * Index of the current element (last returned) in the backup list.
+ */
+ int currentIndex;
+
+ /**
+ *
+ */
+ int previousIndex;
+
+ /**
+ *
+ */
+ int nextIndex;
+
+ /**
+ * Index of the last returned element.
+ */
+ int eleIndex = -1;
+
+ /**
+ * Index of the boundary.
+ */
+ int index = 0;
+
+ /**
+ *
+ */
+ ListIterator<Object> listIterator;
+
+ /**
+ *
+ *
+ * @param index
+ */
+ FilteredListIterator(int index) {
+ listIterator = list.listIterator(0);
+ nextIndex = -1;
+ next = nextFilteredObject();
+
+ previous = null;
+ previousIndex = -1;
+ current = next;
+ currentIndex = 0;
+
+ // Go to the specified index
+ while(hasNext() && (nextIndex() < index)) {
+ next();
+ }
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ protected Object nextFilteredObject() {
+ while(listIterator.hasNext()) {
+
+ int curIndex = listIterator.nextIndex(); // This is the current index in the list
+ Object ele = listIterator.next();
+ if(filter.isAllowed(ele) && (curIndex > nextIndex)) {
+ nextIndex = curIndex;
+ return ele;
+ }
+ } // end loop
+ return null;
+ }
+
+ /**
+ *
+ *
+ * @return
+ */
+ protected Object previousFilteredObject() {
+ while(listIterator.hasPrevious()) {
+ int curIndex = listIterator.previousIndex(); // This is the current index in the list
+ Object ele = listIterator.previous();
+ if(filter.isAllowed(ele) && (curIndex < previousIndex)) {
+ previousIndex = curIndex;
+ return ele;
+ }
+ } // end loop
+ return null;
+ }
+
+ /**
+ * /** nextIndex.
+ *
+ * @return int
+ */
+ public int nextIndex() {
+ return index;
+ }
+
+ /**
+ * previousIndex.
+ *
+ * @return int
+ */
+ public int previousIndex() {
+ return index - 1;
+ }
+
+ /**
+ * remove.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * hasNext.
+ *
+ * @return boolean
+ */
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ /**
+ * hasPrevious.
+ *
+ * @return boolean
+ */
+ public boolean hasPrevious() {
+ return previous != null;
+ }
+
+ /**
+ * next.
+ *
+ * @return Object
+ */
+ public Object next() {
+ if(next == null) {
+ throw new NoSuchElementException();
+ }
+
+ if(index > eleIndex) { // previous was up, continue
+ previous = current;
+ previousIndex = currentIndex;
+ current = next;
+ currentIndex = nextIndex;
+ next = nextFilteredObject();
+
+ index++;
+ eleIndex++;
+ return current;
+ } else { // previous was down, turn back
+ index++;
+ return current;
+ }
+ }
+
+ /**
+ * previous.
+ *
+ * @return Object
+ */
+ public Object previous() {
+ if(previous == null) {
+ throw new NoSuchElementException();
+ }
+
+ if(index > eleIndex) { // previous was up, turn back
+ index--;
+ return current;
+ } else { // previuos was done, continue
+ next = current;
+ nextIndex = currentIndex;
+ current = previous;
+ currentIndex = previousIndex;
+ previous = previousFilteredObject();
+
+ index--;
+ eleIndex--;
+ return current;
+
+ }
+
+ }
+
+ /**
+ * add.
+ *
+ * @param o
+ * Object
+ */
+ public void add(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * set.
+ *
+ * @param o
+ * Object
+ */
+ public void set(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IDebugChannel.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IDebugChannel.java
new file mode 100644
index 00000000000..79b9f462618
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IDebugChannel.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+/**
+ * This interface contains all channels to trace papyrus
+ *
+ * @author Patrick Tessier
+ */
+public interface IDebugChannel {
+
+ /**
+ * constant used to trace the core running
+ */
+ public static final String PAPYRUS_CORE = "org.eclipse.papyrus.core/debug/core";
+
+ /**
+ * constant used to trace the loading of extension point
+ */
+ public static final String PAPYRUS_EXTENSIONPOINT_LOADING = "org.eclipse.papyrus.core/debug/extensionpoint";
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IFilter.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IFilter.java
new file mode 100644
index 00000000000..8ac559c8571
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/IFilter.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cedric Dumoulin Cedric.dumoulin@lifl.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+/**
+ * A filter.
+ */
+public interface IFilter {
+
+ /**
+ * Is the specified object allowed ? Return true if the filter allow this object. Return false if the filter doesn't allows the object.
+ *
+ * @param object
+ *
+ * @return boolean
+ */
+ public boolean isAllowed(Object object);
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ILoadingStrategy.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ILoadingStrategy.java
new file mode 100644
index 00000000000..6f275c4bc9f
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ILoadingStrategy.java
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * Copyright (c) 2010 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import org.eclipse.emf.common.util.URI;
+
+
+/**
+ * The Interface ILoadingStrategy that manages several strategies to load the model
+ */
+public interface ILoadingStrategy {
+
+ boolean loadResource(URI uri);
+
+ // strategies:
+ // 1: ask the user which resource is loaded
+ // 2: load the model and all the controlled resources below
+ // 3: load the model and all the controlled resources below and the profiles
+ // 4: load the model and all the controlled resources below and the pathmaps and profiles
+ // 5: load all
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/NotationUtils.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/NotationUtils.java
new file mode 100644
index 00000000000..4d1de9878ef
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/NotationUtils.java
@@ -0,0 +1,119 @@
+/*****************************************************************************
+ * Copyright (c) 2009 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.gmf.runtime.notation.Diagram;
+
+/**
+ * Utilities method to manage notation models. Should be moved in a more suitable plugin
+ */
+public class NotationUtils {
+
+
+ /**
+ * Get the notation Resource.
+ *
+ * @return
+ */
+ public static Resource getNotationResource() {
+ return EditorUtils.getDiResourceSet().getNotationResource();
+ }
+
+ /**
+ * Gets the direct associated diagram of the specified eObject.
+ *
+ * @param eObject
+ * @param notationResource
+ *
+ * @return the associated diagram
+ */
+ public static Diagram getAssociatedDiagram(Resource notationResource, EObject eObject) {
+ if(notationResource != null) {
+ for(EObject obj : notationResource.getContents()) {
+ if(obj instanceof Diagram) {
+ Diagram diagram = (Diagram)obj;
+ if(eObject != null && eObject.equals(diagram.getElement())) {
+ return diagram;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the direct associated diagram of the specified eObject.
+ *
+ * @param eObject
+ * @param notationResource
+ * @param resolve
+ * the resource if true
+ *
+ * @return the associated diagram
+ */
+ public static Diagram getAssociatedDiagram(Resource notationResource, EObject eObject, boolean resolve) {
+ if(notationResource != null && resolve) {
+ EcoreUtil.resolveAll(notationResource);
+ }
+ return getAssociatedDiagram(notationResource, eObject);
+ }
+
+ /**
+ * Gets the all the diagrams contained in the specified ancestor eObject
+ *
+ * @param notationResource
+ * @param eObject
+ *
+ * @return all the contained diagrams
+ *
+ */
+ public static List<Diagram> getDiagrams(Resource notationResource, EObject eObject) {
+ List<Diagram> diagrams = new ArrayList<Diagram>();
+ if(notationResource != null) {
+ for(EObject obj : notationResource.getContents()) {
+ if(obj instanceof Diagram) {
+ Diagram diagram = (Diagram)obj;
+ if(EcoreUtil.isAncestor(eObject, diagram.getElement())) {
+ diagrams.add(diagram);
+ }
+ }
+ }
+ }
+ return diagrams;
+ }
+
+ /**
+ * Gets the all the diagrams contained in the specified ancestor eObject
+ *
+ * @param notationResource
+ * @param eObject
+ * @param resolve
+ * the resource if true
+ *
+ * @return all the contained diagrams
+ */
+ public static List<Diagram> getDiagrams(Resource notationResource, EObject eObject, boolean resolve) {
+ if(notationResource != null && resolve) {
+ EcoreUtil.resolveAll(notationResource);
+ }
+ return getDiagrams(notationResource, eObject);
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/PapyrusTrace.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/PapyrusTrace.java
new file mode 100644
index 00000000000..2d8452f174f
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/PapyrusTrace.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008 CEA LIST.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.core.Activator;
+import org.eclipse.papyrus.log.LogHelper;
+
+/**
+ * Utility class to log errors or debug information either in the plugin'log or in the console.
+ * <p>
+ * A set of channels is used to separate different traces for different aspects. A short list is displayed at the end of the file to give an example
+ * of channels
+ * @deprecated Use {@link LogHelper} instead
+ **/
+@Deprecated
+public class PapyrusTrace implements IDebugChannel {
+
+ public static final String PAPYRUS_CORE = "org.eclipse.papyrus.core/debug";
+
+ /**
+ * Display a debug trace.
+ *
+ * @param element
+ * that provides the trace
+ * @param text
+ * message to display
+ * @param traceOption
+ * channel of the trace (see {@link IDebugChannel})
+ */
+ public static void trace(String traceOption, Object element, String text) {
+ if(!Platform.inDebugMode()) {
+ return;
+ }
+ String globalTraceValue = Platform.getDebugOption(PAPYRUS_CORE);
+ String value = Platform.getDebugOption(traceOption);
+ if(null != globalTraceValue && globalTraceValue.equals("true") && null != value && value.equals("true")) {
+ if(element != null) {
+ log(IStatus.INFO, "[" + traceOption + "]: " + element.getClass() + " --> " + text);
+ } else {
+ log(IStatus.INFO, "[" + traceOption + "] --> " + text);
+ }
+ }
+ }
+
+ /**
+ * display error.
+ *
+ * @param element
+ * that provides the trace
+ * @param text
+ * to display
+ * @param traceOption
+ * channel of the trace
+ */
+ public static void error(String traceOption, Object element, String text) {
+ if(!Platform.inDebugMode()) {
+ return;
+ }
+ String globalTraceValue = Platform.getDebugOption(PAPYRUS_CORE);
+ String value = Platform.getDebugOption(traceOption);
+ if(null != globalTraceValue && globalTraceValue.equals("true") && null != value && value.equals("true")) {
+ if(element != null) {
+ log(IStatus.ERROR, "[" + traceOption + "]: " + element.getClass() + " --> " + text);
+ } else {
+ log(IStatus.ERROR, "[" + traceOption + "] --> " + text);
+ }
+ }
+ }
+
+ /**
+ * Log an exception into the plugin log.
+ *
+ * @param exception
+ * the exception to log.
+ * @param e
+ * the message to log
+ */
+ public static void log(Exception e) {
+ final IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
+ Activator.getDefault().getLog().log(status);
+ }
+
+ /**
+ * Log a message into the plugin log.
+ *
+ * @param message
+ * the message to log
+ * @param severity
+ * the severity : one of <code>OK</code>, <code>ERROR</code>, <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code>
+ */
+ public static void log(int severity, String message) {
+ final IStatus status = new Status(severity, Activator.PLUGIN_ID, IStatus.OK, message, null);
+ Activator.getDefault().getLog().log(status);
+ }
+}
diff --git a/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ProxyManager.java b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ProxyManager.java
new file mode 100644
index 00000000000..1a01c7df458
--- /dev/null
+++ b/org.eclipse.papyrus.core/src/org/eclipse/papyrus/core/utils/ProxyManager.java
@@ -0,0 +1,116 @@
+/*****************************************************************************
+ * Copyright (c) 2010 Atos Origin.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Emilien Perico (Atos Origin) emilien.perico@atosorigin.com - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.core.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.core.Activator;
+
+
+/**
+ * The Class ProxyManager that manages the proxy resolving according a specific strategy.
+ */
+public class ProxyManager {
+
+ /** extension point ID for loading strategy */
+ private static final String LOADING_STRATEGY_EXTENSION_POINT_ID = "org.eclipse.papyrus.core.loadingStrategy";
+
+ /** element ID for the loading strategy element */
+ private static final String LOADING_STRATEGY_ELEMENT_ID = "loadingStrategy";
+
+ /** attribute ID for identification of the strategy */
+ private static final String ID = "id";
+
+ /** attribute ID for the description of the strategy */
+ private static final String DESCRIPTION_ID = "description";
+
+ /** attribute ID for the implementation of the strategy */
+ private static final String STRATEGY_ID = "strategy";
+
+ /** custom commands from extensions */
+ private static Map<Integer, ILoadingStrategy> availableStrategies = getLoadingStrategyExtensions();
+
+ /** The strategies id and descriptions for preferences */
+ private static Map<Integer, String> strategiesAndDescriptions = new HashMap<Integer, String>();
+
+ /** The current strategy, default strategy id = 0 */
+ private static int currentStrategy = 0;
+
+ public ProxyManager() {
+ super();
+ // TODO load currentStrategy in preference
+ }
+
+ public boolean loadResource(URI uri) {
+ if (currentStrategy == -1)
+ {
+ return true ;
+ }
+ return availableStrategies.get(currentStrategy).loadResource(uri);
+ }
+
+ /**
+ * Sets the current strategy.
+ *
+ * @param id the new current strategy id
+ */
+ public static void setCurrentStrategy (int id)
+ {
+ currentStrategy = id ;
+ }
+
+ /**
+ * Gets the all strategies.
+ *
+ * @return the all strategies
+ */
+ public static Map<Integer, String> getAllStrategies() {
+ return strategiesAndDescriptions;
+ }
+
+ /**
+ * Gets the available strategies from extensions
+ *
+ * @return the strategies
+ */
+ private static Map<Integer, ILoadingStrategy> getLoadingStrategyExtensions() {
+ Map<Integer, ILoadingStrategy> strategies = new HashMap<Integer, ILoadingStrategy>();
+ IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(LOADING_STRATEGY_EXTENSION_POINT_ID);
+ for(IConfigurationElement element : extensions) {
+ if(LOADING_STRATEGY_ELEMENT_ID.equals(element.getName())) {
+ try {
+ // use description in extension to define preferences from the extensions
+ int id = Integer.valueOf(element.getAttribute(ID));
+ String description = element.getAttribute(DESCRIPTION_ID);
+ ILoadingStrategy strategy = (ILoadingStrategy)element.createExecutableExtension(STRATEGY_ID);
+ strategies.put(id, strategy);
+ strategiesAndDescriptions.put(id, description);
+ } catch (CoreException e1) {
+ Activator.log.error(e1.getMessage(), e1);
+ e1.printStackTrace();
+ } catch (NumberFormatException e2) {
+ Activator.log.error(e2.getMessage(), e2);
+ e2.printStackTrace();
+ }
+ }
+ }
+ return strategies;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEvent.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEvent.java
new file mode 100644
index 00000000000..cb7a4b19c38
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEvent.java
@@ -0,0 +1,28 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+import javax.imageio.spi.ServiceRegistry;
+
+import org.eclipse.papyrus.core.editor.IMultiDiagramEditor;
+
+
+/**
+ * @author dumoulin
+ *
+ */
+public class FakeSaveEvent extends DoSaveEvent {
+
+ /**
+ * Constructor.
+ *
+ * @param serviceRegistry
+ * @param multiDiagramEditor
+ */
+ public FakeSaveEvent() {
+ super(null, null);
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEventListener.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEventListener.java
new file mode 100644
index 00000000000..8454163686d
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/FakeSaveEventListener.java
@@ -0,0 +1,57 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * @author dumoulin
+ *
+ */
+public class FakeSaveEventListener implements ISaveEventListener {
+
+ List<DoSaveEvent> receivedEvents = new ArrayList<DoSaveEvent>();
+
+ /**
+ * @see org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener#doSave(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)
+ *
+ * @param event
+ */
+ public void doSave(DoSaveEvent event) {
+ receivedEvents.add(event);
+
+ }
+
+ /**
+ * @see org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener#doSaveAs(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)
+ *
+ * @param event
+ */
+ public void doSaveAs(DoSaveEvent event) {
+ receivedEvents.add(event);
+
+ }
+
+ /**
+ * Return true if the event has been received.
+ * @param event
+ * @return
+ */
+ public boolean isEventReceived(DoSaveEvent event) {
+ return receivedEvents.contains(event);
+ }
+
+
+ /**
+ * @return the receivedEvents
+ */
+ public List<DoSaveEvent> getReceivedEvents() {
+ return receivedEvents;
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProviderTest.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProviderTest.java
new file mode 100644
index 00000000000..1c1084236a9
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/lifecycleevents/LifeCycleEventsProviderTest.java
@@ -0,0 +1,232 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.lifecycleevents;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author cedric dumoulin
+ *
+ */
+public class LifeCycleEventsProviderTest extends TestCase {
+
+ /**
+ * Object under test.
+ */
+ protected LifeCycleEventsProvider eventProvider;
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ *
+ * @throws Exception
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ eventProvider = new LifeCycleEventsProvider();
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#addDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testAddSaveListener() {
+
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Add listener");
+ }
+
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#removeDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testRemoveSaveListener() {
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addDoSaveListener(listener);
+ eventProvider.removeDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Remove listener");
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#addAboutToDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testAddAboutToSaveListener() {
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addAboutToDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Add listener");
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#removeAboutToDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testRemoveAboutToSaveListener() {
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addAboutToDoSaveListener(listener);
+ eventProvider.removeAboutToDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Remove listener");
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#addPostDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testAddPostSaveListener() {
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addPostDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Add listener");
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#removePostDoSaveListener(org.eclipse.papyrus.core.lifecycleevents.ISaveEventListener)}.
+ */
+ public void testRemovePostSaveListener() {
+ ISaveEventListener listener = new FakeSaveEventListener();
+
+ try {
+ eventProvider.addPostDoSaveListener(listener);
+ eventProvider.removePostDoSaveListener(listener);
+ } catch (Exception e) {
+ fail("Remove listener");
+ }
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireAboutToDoSaveEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireAboutToSaveEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addAboutToDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireAboutToDoSaveEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireAboutToDoSaveAsEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireAboutToSaveAsEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addAboutToDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireAboutToDoSaveAsEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireDoSaveEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireSaveEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireDoSaveEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireDoSaveAsEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireSaveAsEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireDoSaveAsEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#firePostDoSaveEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFirePostSaveEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addPostDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.firePostDoSaveEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#firePostDoSaveAsEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFirePostSaveAsEvent() {
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+
+ eventProvider.addPostDoSaveListener(listener);
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.firePostDoSaveAsEvent(event);
+
+ assertTrue("event received", listener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireAllDoSaveEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireAllSaveEvent() {
+ FakeSaveEventListener preListener = new FakeSaveEventListener();
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+ FakeSaveEventListener postListener = new FakeSaveEventListener();
+
+ eventProvider.addAboutToDoSaveListener(preListener);
+ eventProvider.addDoSaveListener(listener);
+ eventProvider.addPostDoSaveListener(postListener);
+
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireAllDoSaveEvent(event);
+
+ assertTrue("event received", preListener.isEventReceived(event) );
+ assertTrue("event received", listener.isEventReceived(event) );
+ assertTrue("event received", postListener.isEventReceived(event) );
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.lifecycleevents.LifeCycleEventsProvider#fireAllDoSaveAsEvent(org.eclipse.papyrus.core.lifecycleevents.DoSaveEvent)}.
+ */
+ public void testFireAllSaveAsEvent() {
+ FakeSaveEventListener preListener = new FakeSaveEventListener();
+ FakeSaveEventListener listener = new FakeSaveEventListener();
+ FakeSaveEventListener postListener = new FakeSaveEventListener();
+
+ eventProvider.addAboutToDoSaveListener(preListener);
+ eventProvider.addDoSaveListener(listener);
+ eventProvider.addPostDoSaveListener(postListener);
+
+ DoSaveEvent event = new FakeSaveEvent();
+ eventProvider.fireAllDoSaveAsEvent(event);
+
+ assertTrue("event received", preListener.isEventReceived(event) );
+ assertTrue("event received", listener.isEventReceived(event) );
+ assertTrue("event received", postListener.isEventReceived(event) );
+ }
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA.java
new file mode 100644
index 00000000000..fc37ca7b3f6
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA.java
@@ -0,0 +1,18 @@
+package org.eclipse.papyrus.core.services;
+
+public class ServiceA implements IService {
+
+ public void initService(ServicesRegistry servicesRegistry) {
+
+ }
+
+ public void startService() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void disposeService() {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA10.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA10.java
new file mode 100644
index 00000000000..a36eb59ce2f
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceA10.java
@@ -0,0 +1,6 @@
+package org.eclipse.papyrus.core.services;
+
+
+public class ServiceA10 extends ServiceA {
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceB.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceB.java
new file mode 100644
index 00000000000..c8db40311b6
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceB.java
@@ -0,0 +1,6 @@
+package org.eclipse.papyrus.core.services;
+
+
+public class ServiceB extends ServiceA {
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceC.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceC.java
new file mode 100644
index 00000000000..31276d53126
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServiceC.java
@@ -0,0 +1,6 @@
+package org.eclipse.papyrus.core.services;
+
+
+public class ServiceC extends ServiceA {
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicePojoA.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicePojoA.java
new file mode 100644
index 00000000000..5602c3c6e12
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicePojoA.java
@@ -0,0 +1,6 @@
+package org.eclipse.papyrus.core.services;
+
+
+public class ServicePojoA extends ServiceA {
+
+}
diff --git a/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicesRegistryTest.java b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicesRegistryTest.java
new file mode 100644
index 00000000000..43bf01dc8da
--- /dev/null
+++ b/org.eclipse.papyrus.core/test/org/eclipse/papyrus/core/services/ServicesRegistryTest.java
@@ -0,0 +1,218 @@
+/**
+ *
+ */
+package org.eclipse.papyrus.core.services;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author dumoulin
+ *
+ */
+public class ServicesRegistryTest extends TestCase {
+
+ /** The registry to test */
+ ServicesRegistry servicesRegistry;
+
+ ServiceDescriptor serviceADesc = new LazyServiceADescriptor();
+
+ ServiceDescriptor serviceA10Desc = new LazyServiceA10Descriptor();
+
+ ServiceDescriptor serviceBDesc = new LazyServiceBDescriptor();
+
+ ServiceDescriptor serviceCDesc = new ServiceCDescriptor();
+
+ ServiceDescriptor servicePojoADesc = new LazyServicePojoADescriptor();
+
+ public ServicesRegistryTest(String name) {
+ super(name);
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ protected void setUp() throws Exception {
+ servicesRegistry = new ServicesRegistry();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ protected void tearDown() throws Exception {
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.services.ServicesRegistry#add(org.eclipse.papyrus.core.services.ServiceDescriptor)} .
+ */
+ public void testAdd() {
+
+ servicesRegistry.add(serviceADesc);
+ servicesRegistry.add(serviceBDesc);
+ servicesRegistry.add(serviceCDesc);
+ servicesRegistry.add(servicePojoADesc);
+
+
+ // Test entries creation
+ try {
+ assertFalse("serviceA stopped", servicesRegistry.isStarted(serviceADesc.getKey()));
+ assertFalse("serviceB stopped", servicesRegistry.isStarted(serviceBDesc.getKey()));
+ assertFalse("serviceC stopped", servicesRegistry.isStarted(serviceCDesc.getKey()));
+ assertFalse("servicePojoA stopped", servicesRegistry.isStarted(servicePojoADesc.getKey()));
+ } catch (ServiceNotFoundException e) {
+ fail("Service should exist.");
+ }
+
+ // Test startup
+ servicesRegistry.startRegistry();
+
+ // Test always started
+ try {
+ assertFalse("serviceA stopped", servicesRegistry.isStarted(serviceADesc.getKey()));
+ assertFalse("serviceB stopped", servicesRegistry.isStarted(serviceBDesc.getKey()));
+ assertTrue("serviceC started", servicesRegistry.isStarted(serviceCDesc.getKey()));
+ assertFalse("servicePojoA stopped", servicesRegistry.isStarted(servicePojoADesc.getKey()));
+ } catch (ServiceNotFoundException e) {
+ fail("Service should exist.");
+ }
+
+
+ }
+
+ /**
+ * Test method for {@link org.eclipse.papyrus.core.services.ServicesRegistry#getService(java.lang.Object)}.
+ *
+ * @throws ServiceException
+ */
+ public void testGetService() throws ServiceException {
+ servicesRegistry.add(serviceADesc);
+ servicesRegistry.add(serviceBDesc);
+ servicesRegistry.add(serviceCDesc);
+ servicesRegistry.add(servicePojoADesc);
+
+
+ // Test lazy service
+ Object serviceA = servicesRegistry.getService(serviceADesc.getKey());
+ assertNotNull("service created", serviceA);
+ assertEquals("right class", ServiceA.class, serviceA.getClass());
+
+ Object serviceA2 = servicesRegistry.getService(serviceADesc.getKey());
+ assertEquals("Second retrieve get the same service", serviceA, serviceA2);
+
+ // test startup service
+ Object serviceC = servicesRegistry.getService(serviceCDesc.getKey());
+ assertNotNull("service created", serviceC);
+ assertEquals("right class", ServiceC.class, serviceC.getClass());
+
+ Object serviceC2 = servicesRegistry.getService(serviceCDesc.getKey());
+ assertEquals("Second retrieve get the same service", serviceC, serviceC2);
+
+ // test pojo service
+ Object servicePojo = servicesRegistry.getService(servicePojoADesc.getKey());
+ assertNotNull("service created", servicePojo);
+ assertEquals("right class", ServicePojoA.class, servicePojo.getClass());
+
+ Object servicePojo2 = servicesRegistry.getService(servicePojoADesc.getKey());
+ assertEquals("Second retrieve get the same service", servicePojo, servicePojo2);
+
+
+ }
+
+ /**
+ * Try to register 2 services under the same name, but with different priorities.
+ *
+ * @throws ServiceException
+ */
+ public void testPriority() throws ServiceException {
+ servicesRegistry.add(serviceADesc);
+ servicesRegistry.add(serviceA10Desc);
+ servicesRegistry.add(serviceBDesc);
+
+ // Test creation
+ try {
+ assertFalse("serviceA stopped", servicesRegistry.isStarted(serviceADesc.getKey()));
+ assertFalse("serviceB stopped", servicesRegistry.isStarted(serviceBDesc.getKey()));
+ } catch (ServiceNotFoundException e) {
+ fail("Service should exist.");
+ }
+
+ Object serviceA = servicesRegistry.getService(serviceADesc.getKey());
+
+ assertNotNull("Service created", serviceA);
+ assertEquals("right class", ServiceA10.class, serviceA.getClass());
+
+
+ }
+
+ /**
+ * Test add for a direct instance of service.
+ *
+ * @throws ServiceException
+ */
+ public void testAddDirectInstance() throws ServiceException {
+ IService instanciatedService = new ServiceA();
+ String key = instanciatedService.getClass().getName();
+
+ servicesRegistry.add(key, 1, instanciatedService);
+
+ servicesRegistry.add(serviceCDesc);
+ servicesRegistry.add(serviceBDesc);
+
+ servicesRegistry.startRegistry();
+
+ Object serviceA = servicesRegistry.getService(key);
+
+ assertNotNull("Service created", serviceA);
+ assertEquals("right object", instanciatedService, serviceA);
+ assertEquals("right class", ServiceA.class, serviceA.getClass());
+
+
+ }
+
+ /* **************************************** */
+
+
+
+
+ public class LazyServiceADescriptor extends ServiceDescriptor {
+
+
+ public LazyServiceADescriptor() {
+ super(ServiceA.class.getName(), ServiceStartKind.LAZY, 1);
+ }
+ }
+
+ public class LazyServiceA10Descriptor extends ServiceDescriptor {
+
+
+ public LazyServiceA10Descriptor() {
+ super(ServiceA.class.getName(), ServiceA10.class.getName(), ServiceStartKind.LAZY, 10);
+ }
+ }
+
+ public class LazyServiceBDescriptor extends ServiceDescriptor {
+
+
+ public LazyServiceBDescriptor() {
+ super(ServiceB.class.getName(), ServiceStartKind.LAZY, 1);
+ }
+ }
+
+ public class ServiceCDescriptor extends ServiceDescriptor {
+
+
+ public ServiceCDescriptor() {
+ super(ServiceC.class.getName(), ServiceStartKind.STARTUP, 1);
+ }
+ }
+
+ public class LazyServicePojoADescriptor extends ServiceDescriptor {
+
+
+ public LazyServicePojoADescriptor() {
+ super(ServicePojoA.class.getName(), ServiceStartKind.LAZY, 1);
+ }
+ }
+
+
+}
diff --git a/org.eclipse.papyrus.core/todo.txt b/org.eclipse.papyrus.core/todo.txt
new file mode 100644
index 00000000000..dae0626d5ac
--- /dev/null
+++ b/org.eclipse.papyrus.core/todo.txt
@@ -0,0 +1,8 @@
+Complete the base editor with requested methods
+Separate model management in its own class
+ - crud
+ - change listener ?
+ - define provided services
+Separate UML and graphic models management ?
+Try editor with no registered diagrams
+Try to register a Papyrus diagram \ No newline at end of file

Back to the top