Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremie Tatibouet2015-03-24 09:15:15 -0400
committerCamille Letavernier2015-03-24 09:19:29 -0400
commit246b5ad5b70a9d974448ec9c2dfd8fdfe10553e2 (patch)
tree3fafa30290597619ed71bc13fafad1eb8d5f5bb1 /extraplugins/alf
parentdef2c21b7ea8a1529fa6b06a96dd1a30ddc4f6da (diff)
downloadorg.eclipse.papyrus-246b5ad5b70a9d974448ec9c2dfd8fdfe10553e2.tar.gz
org.eclipse.papyrus-246b5ad5b70a9d974448ec9c2dfd8fdfe10553e2.tar.xz
org.eclipse.papyrus-246b5ad5b70a9d974448ec9c2dfd8fdfe10553e2.zip
462954: [ALF] Integrate the new ALF grammar & tooling
https://bugs.eclipse.org/bugs/show_bug.cgi?id=462954 - Squash the committers/cletavernie/alf-integration branch Also-by: Ed Seidewitz <ed-s@modeldriven.com> Also-by: Arnaud Cuccuru <arnaud.cuccuru@cea.fr> Signed-off-by: Jeremie Tatibouet <jeremie.tatibouet@cea.fr>
Diffstat (limited to 'extraplugins/alf')
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.classpath7
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.project28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/META-INF/MANIFEST.MF23
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/about.html28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/build.properties6
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/pom.xml14
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/ActivatorText.java67
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/DefaultEditStringRetrievalStrategy.java121
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/EditStringRetrievalStrategy.java47
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/AlfCompareEditor.java46
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/MergeActionDialog.java137
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/AlfTextualRepresentation.java187
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/IAlfTextualRepresentation.java31
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/TextualRepresentation.java98
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/IAdvancedDifference.java41
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineComparator.java53
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineDifference.java102
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/RegionDifference.java77
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/StringUtil.java44
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/TokenDifference.java62
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParser.java98
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParsingError.java25
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.classpath7
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.project28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/META-INF/MANIFEST.MF28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/about.html28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/build.properties7
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/plugin.xml19
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/pom.xml14
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/ActivatorTransaction.java56
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommand.java51
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandFactory.java70
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandLabels.java25
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/CompileCommand.java62
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/SaveCommand.java54
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/VersioningSaveCommand.java35
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ChangeScenario.java46
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/CommitScenario.java96
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IChangeScenario.java17
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IScenario.java28
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ISyncScenario.java30
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SaveScenario.java100
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/Scenario.java53
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ScenarioFactory.java41
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SyncScenario.java163
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfAbstractJob.java50
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfCompilationJob.java69
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfJobObserver.java63
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/SaveTextualRepresentationJob.java49
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/FUMLElementService.java56
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/FUMLElementListener.java77
-rw-r--r--extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/filter/FUMLFilter.java289
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.classpath7
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.project28
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/META-INF/MANIFEST.MF35
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/about.html28
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/build.properties9
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/plugin.xml98
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/pom.xml14
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/resources/icons/incom_stat.gifbin0 -> 93 bytes
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/ActivatorALFProperties.java50
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/UndoRedoStack.java64
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/AbstractAlfXtextEditorConfiguration.java114
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/DefaultAlfXtextEditorConfiguration.java75
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/constraints/ALFFilterConstraint.java62
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/parser/GMFAlfParser.java109
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySection.java330
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySectionFilter.java64
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/CommitButtonSelectionListener.java46
-rw-r--r--extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/EditorFocusListener.java52
73 files changed, 4259 insertions, 0 deletions
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.classpath b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.classpath
new file mode 100644
index 00000000000..b1dabee3829
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.project b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.project
new file mode 100644
index 00000000000..116c74ef06e
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.uml.alf.text</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/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.settings/org.eclipse.jdt.core.prefs b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..11f6e462df7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/META-INF/MANIFEST.MF b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..2d00c973c03
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.papyrus.uml.alf.text
+Bundle-SymbolicName: org.eclipse.papyrus.uml.alf.text
+Bundle-Version: 1.1.0.qualifier
+Bundle-Activator: org.eclipse.papyrus.uml.alf.text.ActivatorText
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.uml2.uml,
+ org.eclipse.papyrus.uml.alf,
+ org.eclipse.papyrus.uml.alf.libraries,
+ org.eclipse.compare,
+ org.eclipse.gmf.runtime.common.core,
+ org.eclipse.swt,
+ org.eclipse.compare.core,
+ org.eclipse.papyrus.infra.core.log
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.papyrus.uml.alf.text.generation,
+ org.eclipse.papyrus.uml.alf.text.merge.manual,
+ org.eclipse.papyrus.uml.alf.text.representation,
+ org.eclipse.papyrus.uml.alf.text.representation.util
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/about.html b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/about.html
new file mode 100644
index 00000000000..209103075a7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 14, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/build.properties b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/build.properties
new file mode 100644
index 00000000000..785a40c0ec7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html
+src.includes = about.html
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/pom.xml b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/pom.xml
new file mode 100644
index 00000000000..a1e4f5b5532
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../../../../releng/top-pom-extras.xml</relativePath>
+ </parent>
+ <artifactId>org.eclipse.papyrus.uml.alf.text</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project> \ No newline at end of file
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/ActivatorText.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/ActivatorText.java
new file mode 100644
index 00000000000..c9089ee5ab1
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/ActivatorText.java
@@ -0,0 +1,67 @@
+package org.eclipse.papyrus.uml.alf.text;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.papyrus.uml.alf.AlfRuntimeModule;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ActivatorText extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.uml.alf.text"; //$NON-NLS-1$
+
+ // The shared instance
+ private static ActivatorText plugin;
+
+ private Injector injector;
+
+ public static LogHelper logger;
+
+ /**
+ * The constructor
+ */
+ public ActivatorText() {
+ }
+
+ /*
+ * (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;
+ this.injector = Guice.createInjector(new AlfRuntimeModule());
+ logger = new LogHelper(this);
+ }
+
+ /*
+ * (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);
+ logger = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static ActivatorText getDefault() {
+ return plugin;
+ }
+
+ public Injector getInjector() {
+ return this.injector;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/DefaultEditStringRetrievalStrategy.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/DefaultEditStringRetrievalStrategy.java
new file mode 100644
index 00000000000..85ad34e43bb
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/DefaultEditStringRetrievalStrategy.java
@@ -0,0 +1,121 @@
+package org.eclipse.papyrus.uml.alf.text.generation;
+
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet (CEA LIST);
+ *****************************************************************************/
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.uml.alf.Member;
+import org.eclipse.papyrus.uml.alf.PropertyDefinition;
+import org.eclipse.papyrus.uml.alf.text.ActivatorText;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.text.representation.util.RepresentationParser;
+import org.eclipse.papyrus.uml.alf.text.representation.util.RepresentationParsingError;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.xtext.resource.SaveOptions;
+import org.eclipse.xtext.serializer.ISerializer;
+
+public class DefaultEditStringRetrievalStrategy extends EditStringRetrievalStrategy {
+
+ /**
+ * The serializer associated to the ALF grammar
+ */
+ private ISerializer serializer;
+
+ public DefaultEditStringRetrievalStrategy() {
+ this.serializer = ActivatorText.getDefault().getInjector().getInstance(ISerializer.class);
+ }
+
+ /**
+ * Return the textual representation associated to a given model element
+ *
+ * @param element
+ * - the element for which the textual representation is computed
+ * @return generated - the textual representation computed for this element
+ */
+ public String getGeneratedEditString(Element element) {
+ String generated = "";
+ Resource alfModel = this.getAlfModel((NamedElement) element);
+ if (this.serializer != null) {
+ EObject serializationTarget = null;
+ if (element instanceof Property) {
+ serializationTarget = this.getPropertyDefinition((Property) element, alfModel);
+ } else {
+ serializationTarget = alfModel.getContents().get(0);
+ }
+ generated = this.serializer.serialize(serializationTarget, SaveOptions.newBuilder().noValidation().getOptions());
+ }
+ return generated;
+ }
+
+ /**
+ * When opened the editor retrieve the based string on which the user is going to work.
+ * There are two possibilities:
+ * 1 - The element already has a textual representation associated. Then the return string is the registered representation
+ * 2 - The element does not have an associated textual representation. Then the return string is the one dynamically calculated
+ *
+ * @param element
+ * - the element for which the textual representation is computed
+ * @return registered - the textual representation computed for this element
+ */
+ public String getEditString(Element element) {
+ AlfTextualRepresentation registeredRep = null;
+ /* 1. Parse the representation associated to model element */
+ try {
+ registeredRep = RepresentationParser.getInstance().
+ parse((NamedElement) element);
+ } catch (RepresentationParsingError e) {
+ e.printStackTrace();
+ }
+ /* 2. If the representation is in detached state (i.e. there is no model element owning it) then rely on the issued from a snapshot */
+ if (registeredRep != null && registeredRep.isDetached()) {
+ AlfTextualRepresentation generatedRep = null;
+ try {
+ generatedRep = RepresentationParser.getInstance().
+ getSnapshot((NamedElement) element);
+ } catch (RepresentationParsingError e) {
+ e.printStackTrace();
+ }
+ if (generatedRep != null) {
+ registeredRep.setText(generatedRep.getContent());
+ }
+ }
+ return registeredRep.getContent();
+ }
+
+
+ private EObject getPropertyDefinition(Property property, Resource alfModelResource) {
+ EObject memberDefinition = null;
+ Iterator<EObject> contentIterator = alfModelResource.getAllContents();
+ boolean found = false;
+ while (contentIterator.hasNext() && !found) {
+ EObject currentObject = contentIterator.next();
+ if (currentObject instanceof Member) {
+ Member member = (Member) currentObject;
+ if (member.getVisibility().equals(property.getVisibility().toString())
+ && member.getDefinition() instanceof PropertyDefinition) {
+ PropertyDefinition definition = (PropertyDefinition) member.getDefinition();
+ if (definition.getName().equals(property.getName())) {
+ found = (definition.getTypePart().isIsAny() && property.getType() == null)
+ || definition.getTypePart().getTypeName().toString().equals(property.getType().toString());
+ memberDefinition = member;
+ }
+ }
+ }
+ }
+ return memberDefinition;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/EditStringRetrievalStrategy.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/EditStringRetrievalStrategy.java
new file mode 100644
index 00000000000..752469be8e5
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/generation/EditStringRetrievalStrategy.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.generation;
+
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.uml.alf.MappingError;
+import org.eclipse.papyrus.uml.alf.UMLMapper;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Property;
+
+public abstract class EditStringRetrievalStrategy {
+
+ /**
+ * Provide a resource containing the ALF model corresponding to the given UML element
+ *
+ * @param UMLelement
+ * - the element from which the ALF model is computed
+ * @return alfModelResource - the resource containing the ALF model
+ */
+ protected Resource getAlfModel(NamedElement UMLelement) {
+ UMLMapper mapper = new UMLMapper();
+ Resource alfModelResource = null;
+ try {
+ if (UMLelement instanceof Property) {
+ alfModelResource = mapper.map(((Property) UMLelement).getNamespace());
+ } else {
+ alfModelResource = mapper.map(UMLelement);
+ }
+ } catch (MappingError e) {
+ e.printStackTrace();
+ }
+ return alfModelResource;
+ }
+
+ public abstract String getEditString(Element element);
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/AlfCompareEditor.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/AlfCompareEditor.java
new file mode 100644
index 00000000000..9388f4f7de1
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/AlfCompareEditor.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.merge.manual;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+public class AlfCompareEditor extends CompareEditorInput {
+
+ protected final AlfTextualRepresentation registeredRep;
+
+ protected final AlfTextualRepresentation generatedRep;
+
+ public AlfCompareEditor(AlfTextualRepresentation registeredTextualRepresentation,
+ AlfTextualRepresentation generatedTextualRepresentation) {
+ super(new CompareConfiguration());
+ this.registeredRep = registeredTextualRepresentation;
+ this.generatedRep = generatedTextualRepresentation;
+ }
+
+ @Override
+ protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ return null;
+ }
+
+ @Override
+ public void saveChanges(IProgressMonitor monitor) throws CoreException {
+ super.saveChanges(monitor);
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/MergeActionDialog.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/MergeActionDialog.java
new file mode 100644
index 00000000000..66d79baa526
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/merge/manual/MergeActionDialog.java
@@ -0,0 +1,137 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.merge.manual;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.uml2.uml.NamedElement;
+
+public class MergeActionDialog extends TitleAreaDialog {
+
+ protected NamedElement modelElement;
+
+ protected final int WIDTH = 590;
+
+ protected final int HEIGHT = 280;
+
+ private List<Button> checkboxes;
+
+ private int returnCode;
+
+ private final String REBASE_MSG = "Abandon the modifications you previously saved for this element";
+ private final String MERGE_MSG = "Merge your ongoing modifications with the current state of this element [under construction]";
+ private final String RECONCILE_MSG = "Try to automatically reconcile your ongoing modifications with the current state of this element (risky)";
+
+ public static final int REBASE = 0;
+ public static final int MERGE = 1;
+ public static final int RECONCILE = 2;
+
+ public MergeActionDialog(Shell parent, NamedElement modelElement) {
+ super(parent);
+ this.returnCode = 0;
+ this.modelElement = modelElement;
+ this.checkboxes = new ArrayList<Button>();
+ }
+
+ public void create() {
+ super.create();
+ this.setTitle("Warning");
+ String value = "You have ongoing changes this model element: ";
+ value += this.modelElement.getName() == null ? "<unknown>" : this.modelElement.getName();
+ value += " (" + this.modelElement.eClass().getInstanceTypeName() + ")";
+ this.setMessage(value, IMessageProvider.WARNING);
+ this.getShell().setText("Potential conflict(s) detected");
+ this.getShell().setSize(WIDTH, HEIGHT);
+ Rectangle parentShellBounds = this.getParentShell().getBounds();
+ this.getShell().setLocation((parentShellBounds.width - WIDTH) / 2 + parentShellBounds.x,
+ (parentShellBounds.height - HEIGHT) / 2 + parentShellBounds.y);
+ }
+
+ protected Control createDialogArea(Composite parent) {
+ Composite area = (Composite) super.createDialogArea(parent);
+ Composite container = new Composite(area, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ container.setLayoutData(data);
+ container.setLayout(layout);
+ this.createActionGroup(container);
+ return area;
+ }
+
+ private void createActionGroup(Composite parent) {
+ Group actionsGroup = new Group(parent, SWT.NONE);
+ actionsGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ RowLayout layout = new RowLayout();
+ layout.type = SWT.VERTICAL;
+ layout.spacing = 12;
+ actionsGroup.setLayout(layout);
+ this.checkboxes.add(this.createAction(actionsGroup, true, REBASE_MSG));
+ Button merge = this.createAction(actionsGroup, false, MERGE_MSG);
+ merge.setEnabled(false);
+ this.checkboxes.add(merge);
+ this.checkboxes.add(this.createAction(actionsGroup, false, RECONCILE_MSG));
+ this.returnCode = REBASE;
+ }
+
+ private Button createAction(Composite parent, final boolean checked, final String message) {
+ Button checkbox = new Button(parent, SWT.CHECK);
+ checkbox.setSelection(checked);
+ checkbox.setText(message);
+ checkbox.addSelectionListener(new CheckboxSelectionListener());
+ return checkbox;
+ }
+
+ @Override
+ public int getReturnCode() {
+ if (super.getReturnCode() != 0) {
+ this.returnCode = super.getReturnCode();
+ }
+ return this.returnCode;
+ }
+
+ private class CheckboxSelectionListener extends SelectionAdapter {
+
+ public void widgetSelected(SelectionEvent e) {
+ for (Button checkbox : MergeActionDialog.this.checkboxes) {
+ if (checkbox == e.getSource()) {
+ checkbox.setSelection(true);
+ if (checkbox.getText().equals(REBASE_MSG)) {
+ MergeActionDialog.this.returnCode = REBASE;
+ } else if (checkbox.getText().equals(MERGE_MSG)) {
+ MergeActionDialog.this.returnCode = MERGE;
+ } else {
+ MergeActionDialog.this.returnCode = RECONCILE;
+ }
+ } else {
+ checkbox.setSelection(false);
+ }
+ }
+ }
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/AlfTextualRepresentation.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/AlfTextualRepresentation.java
new file mode 100644
index 00000000000..16f0c0992c7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/AlfTextualRepresentation.java
@@ -0,0 +1,187 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.compare.IModificationDate;
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.compare.rangedifferencer.RangeDifferencer;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState.EditionStatus;
+import org.eclipse.papyrus.uml.alf.text.representation.compare.LineComparator;
+import org.eclipse.papyrus.uml.alf.text.representation.compare.LineDifference;
+import org.eclipse.papyrus.uml.alf.text.representation.compare.StringUtil;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.uml2.uml.NamedElement;
+
+public class AlfTextualRepresentation extends TextualRepresentation
+ implements IAlfTextualRepresentation, IModificationDate {
+
+ protected BackupState editionState;
+
+ public AlfTextualRepresentation(NamedElement owner) {
+ super(owner);
+ this.editionState = new BackupState();
+ }
+
+ public boolean isSaved() {
+ return this.editionState.status.equals(EditionStatus.SAVED);
+ }
+
+ public boolean isMerged() {
+ return this.editionState.status.equals(EditionStatus.MERGED);
+ }
+
+ public void setEditionState(BackupState state) {
+ this.editionState.timestamp = state.timestamp;
+ this.editionState.status = state.status;
+ }
+
+ public BackupState getEditionState() {
+ return this.editionState;
+ }
+
+ public EditionStatus getStatus() {
+ if (this.editionState != null) {
+ return this.editionState.status;
+ }
+ return null;
+ }
+
+ public long getModificationDate() {
+ return this.editionState.timestamp.getTime();
+ }
+
+ /**
+ * Two representations are considered as different since the set of differences is not empty
+ */
+ public boolean isDifferent(AlfTextualRepresentation representation) {
+ return !this.compare(representation).isEmpty();
+ }
+
+ /**
+ * Returns the set of differences found between two representations
+ */
+ public List<LineDifference> compare(AlfTextualRepresentation representation) {
+ /* 1. Build comparator for each representation */
+ IRangeComparator left = this.getRangeComparator();
+ IRangeComparator right = representation.getRangeComparator();
+ /* 2. Perform the differencing */
+ RangeDifference[] differences = RangeDifferencer.findDifferences(left, right);
+ /* 3. Build the result list */
+ List<LineDifference> results = new ArrayList<LineDifference>();
+ for (RangeDifference difference : differences) {
+ results.add(new LineDifference(difference, this, representation, left, right));
+ }
+ return results;
+ }
+
+ public boolean merge(AlfTextualRepresentation representation) {
+ // TODO
+ return true;
+ }
+
+ /**
+ * Heuristic to reconcile to different textual representation of the same model element.
+ * If possible changes in <code>representation</code> are propagated into the current textual representation.
+ * There is no guarantee that the reconciliation phase does not introduce loss of data.
+ *
+ * @return this - the current textual representation
+ */
+ public AlfTextualRepresentation reconcile(AlfTextualRepresentation representation) {
+ StringBuilder builder = new StringBuilder(this.text);
+ int offset = 0;
+ /* 1. Compute the list of differences */
+ Iterator<LineDifference> differenceIterator = this.compare(representation).iterator();
+ /* 2. Try to reconcile differences */
+ while (differenceIterator.hasNext()) {
+
+ /* 2.1. Retrieve the current difference and extract the position of the region to change (left) */
+ LineDifference difference = differenceIterator.next();
+ Point leftFragmentPosition = difference.getLeftFragmentPosition();
+
+ /* 2.2. Split the regions impacted by the difference into lines */
+ StringBuilder leftHandSideBuilder = new StringBuilder();
+ String[] leftLines = difference.getLeftState().split(StringUtil.EOL);
+ String[] rightLines = difference.getRightState().split(StringUtil.EOL);
+ int maxLineCount = Math.max(leftLines.length, rightLines.length);
+
+ /*
+ * 2.3. Integrate changes from left to right. In case where left hand side and right side
+ * have different sizes:
+ * A. right > left -> remaining lines in the right are preserved
+ * B. left > right -> remaining lines are integrated to the right
+ */
+ for (int i = 0; i < maxLineCount; i++) {
+
+ /* 2.3.1 Both sides have a definition of the same line */
+ if (i < leftLines.length && i < rightLines.length) {
+ if (!StringUtil.isNegligible(rightLines[i])) {
+ leftHandSideBuilder.append(rightLines[i] + StringUtil.EOL);
+ } else {
+ leftHandSideBuilder.append(leftLines[i] + StringUtil.EOL);
+ }
+ } else {
+ /* 2.3.2. The left side is larger than the right hand side */
+ if (i < leftLines.length) {
+ leftHandSideBuilder.append(leftLines[i] + StringUtil.EOL);
+ } else {
+ leftHandSideBuilder.append(rightLines[i] + StringUtil.EOL);
+ }
+ }
+ }
+
+ /* 2.4. Apply the change in the original representation */
+ builder.delete(leftFragmentPosition.x + offset, leftFragmentPosition.y + offset);
+ builder.insert(leftFragmentPosition.x + offset, leftHandSideBuilder);
+ offset += leftHandSideBuilder.length() - difference.getLeftState().length();
+ }
+
+ /* 3. Delete the EOF separator added previously at the end and replace text of the current representation */
+ if (builder.charAt(builder.length() - 1) == StringUtil.CHAR_EOL) {
+ builder.deleteCharAt(builder.length());
+ }
+ this.setText(builder.toString());
+ return this;
+ }
+
+ /**
+ * Rebase the current ALF representation onto the representation provided as parameter
+ * A rebase can only work if two representation concerns the same model element
+ *
+ * @return this - the current textual representation
+ */
+ public AlfTextualRepresentation rebase(AlfTextualRepresentation representation) {
+ if (this.getOwner() == representation.getOwner()) {
+ BackupState state = new BackupState();
+ state.status = representation.getStatus();
+ state.timestamp = new Timestamp(representation.getModificationDate());
+ this.setEditionState(state);
+ this.setText(representation.getContent());
+ }
+ return this;
+ }
+
+ /**
+ * Provide the comparator to be used to compare two textual representation
+ */
+ protected IRangeComparator getRangeComparator() {
+ return new LineComparator(this.text);
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/IAlfTextualRepresentation.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/IAlfTextualRepresentation.java
new file mode 100644
index 00000000000..234607fe31c
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/IAlfTextualRepresentation.java
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation;
+
+import java.util.List;
+
+import org.eclipse.papyrus.uml.alf.text.representation.compare.LineDifference;
+
+public interface IAlfTextualRepresentation {
+
+ public boolean isDifferent(AlfTextualRepresentation representation);
+
+ public List<LineDifference> compare(AlfTextualRepresentation representation);
+
+ public boolean merge(AlfTextualRepresentation representation);
+
+ public AlfTextualRepresentation reconcile(AlfTextualRepresentation representation);
+
+ public AlfTextualRepresentation rebase(AlfTextualRepresentation representation);
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/TextualRepresentation.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/TextualRepresentation.java
new file mode 100644
index 00000000000..b634c83ec9a
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/TextualRepresentation.java
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation;
+
+import java.io.InputStream;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.xtext.util.StringInputStream;
+
+public abstract class TextualRepresentation
+ implements IStreamContentAccessor, ITypedElement {
+
+ protected NamedElement owner;
+
+ protected Comment source;
+
+ protected String text;
+
+ public TextualRepresentation() {
+ }
+
+ public TextualRepresentation(NamedElement owner) {
+ this.owner = owner;
+ }
+
+ public Comment getSource() {
+ return this.source;
+ }
+
+ public void setSource(Comment source) {
+ this.source = source;
+ }
+
+ public NamedElement getOwner() {
+ return this.owner;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public String getContent() {
+ return this.text;
+ }
+
+ public String getName() {
+ if (this.getOwner() != null) {
+ return this.getOwner().getName();
+ }
+ return null;
+ }
+
+ public Image getImage() {
+ return null;
+ }
+
+ public String getType() {
+ return ITypedElement.TEXT_TYPE;
+ }
+
+ public InputStream getContents() throws CoreException {
+ return new StringInputStream(this.text);
+ }
+
+ /**
+ * Be detached means the textual representation is not attached to a particular comment
+ *
+ * @return true if no source exists false otherwise
+ */
+ public boolean isDetached() {
+ return this.source == null;
+ }
+
+ /**
+ * Obtain a comparator from the textual representation in order to let the text
+ * be compared using range differencing strategy to another textual representation
+ *
+ * @return
+ */
+ protected abstract IRangeComparator getRangeComparator();
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/IAdvancedDifference.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/IAdvancedDifference.java
new file mode 100644
index 00000000000..0a289fa903d
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/IAdvancedDifference.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+import org.eclipse.swt.graphics.Point;
+
+public interface IAdvancedDifference {
+
+ /**
+ * Provide the start index and the end index of the region concerned by the modification (at the left)
+ */
+ Point getLeftFragmentPosition();
+
+ /**
+ * Provide the start index and the end index of the region concerned by the modification (at the right)
+ */
+ Point getRightFragmentPosition();
+
+ /**
+ * Returns the region of the left hand side representation concerned by the difference
+ */
+ String getLeftState();
+
+ /**
+ * Returns the region of the right hand side representation concerned by the difference
+ */
+ String getRightState();
+
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineComparator.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineComparator.java
new file mode 100644
index 00000000000..9647b1a854e
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineComparator.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+
+public class LineComparator implements IRangeComparator {
+
+ private List<String> lines;
+
+ public LineComparator(final String content) {
+ this.lines = new ArrayList<String>();
+ for (String line : content.split("\n")) {
+ lines.add(line);
+ }
+ }
+
+ public String getLine(int index) {
+ return this.lines.get(index);
+ }
+
+ @Override
+ public int getRangeCount() {
+ return this.lines.size();
+ }
+
+ @Override
+ public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) {
+ String l1 = this.lines.get(thisIndex);
+ String l2 = ((LineComparator) other).lines.get(otherIndex);
+ return l1.equals(l2);
+ }
+
+ @Override
+ public boolean skipRangeComparison(int length, int maxLength, IRangeComparator other) {
+ return false;
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineDifference.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineDifference.java
new file mode 100644
index 00000000000..d3c7952b405
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/LineDifference.java
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.compare.contentmergeviewer.ITokenComparator;
+import org.eclipse.compare.contentmergeviewer.TokenComparator;
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.compare.rangedifferencer.RangeDifferencer;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * This class represent a difference between regions of two representations
+ */
+public class LineDifference extends RegionDifference implements IAdvancedDifference {
+
+ public LineDifference(RangeDifference d, AlfTextualRepresentation leftR,
+ AlfTextualRepresentation rightR, IRangeComparator leftC, IRangeComparator rightC) {
+ super(d, leftR, rightR, leftC, rightC);
+ }
+
+ public String getLeftState() {
+ Point position = this.getLeftFragmentPosition();
+ return this.leftR.getContent().substring(position.x, position.y);
+ }
+
+ public String getRightState() {
+ Point position = this.getRightFragmentPosition();
+ return this.rightR.getContent().substring(position.x, position.y);
+ }
+
+ public Point getLeftFragmentPosition() {
+ String[] leftLines = this.leftR.getContent().split(StringUtil.EOL);
+ int startIndex = 0;
+ for (int i = 0; i < this.leftStart; i++) {
+ startIndex += leftLines[i].length() + 1;
+ }
+ int endIndex = startIndex;
+ for (int i = this.leftStart; i < this.leftEnd(); i++) {
+ if (this.leftEnd() == leftLines.length) {
+ endIndex += leftLines[i].length();
+ } else {
+ endIndex += leftLines[i].length() + 1;
+ }
+ }
+ return new Point(startIndex, endIndex);
+ }
+
+ public Point getRightFragmentPosition() {
+ String[] rightLines = this.rightR.getContent().split(StringUtil.EOL);
+ int startIndex = 0;
+ for (int i = 0; i < this.rightStart; i++) {
+ startIndex += rightLines[i].length() + 1;
+ }
+ int endIndex = startIndex;
+ for (int i = this.rightStart; i < this.rightEnd(); i++) {
+ if (this.rightEnd() == rightLines.length) {
+ endIndex += rightLines[i].length();
+ } else {
+ endIndex += rightLines[i].length() + 1;
+ }
+ }
+ return new Point(startIndex, endIndex);
+ }
+
+ /**
+ * return all the differences between tokens present in the left line and
+ * those present at the right line
+ *
+ * @return tokenDifferences - the list of differences
+ */
+ public List<TokenDifference> getChildren() {
+ ITokenComparator leftTokenComparator = new TokenComparator(this.getLeftState());
+ ITokenComparator rightTokenComparator = new TokenComparator(this.getRightState());
+ AlfTextualRepresentation leftRepresentation = new AlfTextualRepresentation(null);
+ leftRepresentation.setText(this.getLeftState());
+ AlfTextualRepresentation rightRepresentation = new AlfTextualRepresentation(null);
+ leftRepresentation.setText(this.getRightState());
+ RangeDifference[] differences = RangeDifferencer.findDifferences(leftTokenComparator, rightTokenComparator);
+ List<TokenDifference> tokenDifferences = new ArrayList<TokenDifference>();
+ for (RangeDifference difference : differences) {
+ tokenDifferences.add(new TokenDifference(difference, leftRepresentation, rightRepresentation, leftTokenComparator, rightTokenComparator));
+ }
+ return tokenDifferences;
+ }
+
+} \ No newline at end of file
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/RegionDifference.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/RegionDifference.java
new file mode 100644
index 00000000000..7d6d101033b
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/RegionDifference.java
@@ -0,0 +1,77 @@
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+public abstract class RegionDifference extends RangeDifference implements IAdvancedDifference {
+
+ /**
+ * The left hand side comparator
+ */
+ protected IRangeComparator leftC;
+
+ /**
+ * The right hand side comparator
+ */
+ protected IRangeComparator rightC;
+
+ /**
+ * The left side representation
+ */
+ protected AlfTextualRepresentation leftR;
+
+ /**
+ * The right side representation
+ */
+ protected AlfTextualRepresentation rightR;
+
+ protected RegionDifference(RangeDifference d, AlfTextualRepresentation leftR,
+ AlfTextualRepresentation rightR, IRangeComparator leftC, IRangeComparator rightC) {
+ this(d.kind(), d.rightStart(), d.rightLength(), d.leftStart(),
+ d.leftLength(), d.ancestorStart(), d.ancestorLength());
+ this.leftC = leftC;
+ this.rightC = rightC;
+ this.leftR = leftR;
+ this.rightR = rightR;
+ }
+
+ public RegionDifference(int kind, int rightStart, int rightLength, int leftStart, int leftLength,
+ int ancestorStart, int ancestorLength) {
+ super(kind, rightStart, rightLength, leftStart, leftLength, ancestorStart, ancestorLength);
+ }
+
+ /**
+ * Return true if the current difference represents a deletion. Typically a deletion means
+ * a member in the right state disappeared in the left state
+ */
+ public boolean isDeletion() {
+ return !StringUtil.isNegligible(this.getLeftState()) && StringUtil.isNegligible(this.getRightState());
+ }
+
+ /**
+ * Return true if the current difference represents an addition. An addition is the exact reverse
+ * of a deletion (i.e. we have a member in the left that does exists in the right states).
+ */
+ public boolean isAddition() {
+ return StringUtil.isNegligible(this.getLeftState()) && !StringUtil.isNegligible(this.getRightState());
+ }
+
+ /**
+ * Return true if the current difference represents a change. A change is an update of a member
+ * existing in the right state
+ */
+ public boolean isChange() {
+ return !StringUtil.isNegligible(this.getLeftState()) && !StringUtil.isNegligible(this.getRightState());
+ }
+
+ public String toString() {
+ String serialization = "\n=======================DIFF=======================\n";
+ serialization += this.getLeftState();
+ serialization += "\n==================================================\n";
+ serialization += this.getRightState();
+ serialization += "\n=====================END DIFF=====================\n";
+ return serialization;
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/StringUtil.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/StringUtil.java
new file mode 100644
index 00000000000..e3120567d8d
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/StringUtil.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+public class StringUtil {
+
+ public static final char CHAR_EOL = '\n';
+ public static final String EOL = "\n";
+
+ /**
+ * Return true if the given string is not negligible to be used in a comparison
+ *
+ * @param str
+ * - the assessed string
+ * @return negligible
+ */
+ public static final boolean isNegligible(String str) {
+ boolean negligible = true;
+ if (!str.isEmpty()) {
+ int i = 0;
+ while (negligible && i < str.length()) {
+ if (str.charAt(i) != '\n'
+ && str.charAt(i) != '\r'
+ && str.charAt(i) != ' '
+ && str.charAt(i) != '\t') {
+ negligible = false;
+ }
+ i++;
+ }
+ }
+ return negligible;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/TokenDifference.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/TokenDifference.java
new file mode 100644
index 00000000000..f1ffebdd9de
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/compare/TokenDifference.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.compare;
+
+import org.eclipse.compare.contentmergeviewer.ITokenComparator;
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.swt.graphics.Point;
+
+public class TokenDifference extends RegionDifference implements IAdvancedDifference {
+
+ public TokenDifference(RangeDifference d, AlfTextualRepresentation leftR,
+ AlfTextualRepresentation rightR, IRangeComparator leftC, IRangeComparator rightC) {
+ super(d, leftR, rightR, leftC, rightC);
+ }
+
+ public String getLeftState() {
+ String result = "";
+ int startIndex = ((ITokenComparator) this.leftC).getTokenStart(this.leftStart);
+ int endIndex = 0;
+ for (int i = this.leftStart; i <= this.leftEnd(); i++) {
+ endIndex += ((ITokenComparator) this.leftC).getTokenLength(i);
+ }
+ result = this.leftR.getContent().substring(startIndex, startIndex + endIndex);
+ return result;
+ }
+
+ @Override
+ public String getRightState() {
+ String result = "";
+ int endIndex = 0;
+ int startIndex = ((ITokenComparator) this.rightC).getTokenStart(this.rightStart);
+ for (int i = this.rightStart; i <= this.rightEnd(); i++) {
+ endIndex += ((ITokenComparator) this.rightC).getTokenLength(i);
+ }
+ result = this.rightR.getContent().substring(startIndex, startIndex + endIndex);
+ return result;
+ }
+
+ public Point getLeftFragmentPosition() {
+ return new Point(((ITokenComparator) this.leftC).getTokenStart(this.leftStart),
+ ((ITokenComparator) this.leftC).getTokenStart(this.leftEnd()) + ((ITokenComparator) this.leftC).getTokenLength(this.leftEnd()));
+ }
+
+ public Point getRightFragmentPosition() {
+ return new Point(((ITokenComparator) this.rightC).getTokenStart(this.rightStart),
+ ((ITokenComparator) this.rightC).getTokenStart(this.rightEnd()) + ((ITokenComparator) this.rightC).getTokenLength(this.rightEnd()));
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParser.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParser.java
new file mode 100644
index 00000000000..5aab9dfecd9
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParser.java
@@ -0,0 +1,98 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.util;
+
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+import org.eclipse.papyrus.uml.alf.libraries.helper.AlfUtil;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupUtil;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState.EditionStatus;
+import org.eclipse.papyrus.uml.alf.text.generation.DefaultEditStringRetrievalStrategy;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Stereotype;
+
+public class RepresentationParser {
+
+ private static RepresentationParser parser;
+
+ private BackupUtil helperBackup;
+
+ private AlfUtil helperAlf;
+
+ private RepresentationParser() {
+ this.helperBackup = BackupUtil.getInstance();
+ this.helperAlf = AlfUtil.getInstance();
+ }
+
+ public static RepresentationParser getInstance() {
+ if (parser == null) {
+ parser = new RepresentationParser();
+ }
+ return parser;
+ }
+
+ /**
+ * Load the textual representation attached to a model element which is a NamedElement
+ *
+ * @param modelElement
+ * @return representation
+ * @throws RepresentationParsingError
+ */
+ public AlfTextualRepresentation parse(NamedElement modelElement) throws RepresentationParsingError {
+ if (modelElement == null) {
+ throw new RepresentationParsingError(
+ "The model element for which the representation is calculated cannot be null");
+ }
+ AlfTextualRepresentation representation = new AlfTextualRepresentation(modelElement);
+ Comment comment = helperAlf.getTextualRepresentationComment(modelElement);
+ if (comment != null) {
+ representation.setSource(comment);
+ representation.setText(comment.getBody());
+ if (helperBackup.isBackup(comment)) {
+ Stereotype backup = helperBackup.getBackuStereotype(modelElement);
+ if (backup != null) {
+ representation.setEditionState(helperBackup.getBackupState(comment));
+ }
+ }
+ } else {
+ representation.setText(new DefaultEditStringRetrievalStrategy().getGeneratedEditString(modelElement));
+ }
+ return representation;
+ }
+
+ /**
+ * Capture the textual representation of a model element. It does not returns an already registered representation
+ * associated to this element. It captures the current state of a model element.
+ *
+ * @param modelElement
+ * @return representation
+ * @throws RepresentationParsingError
+ */
+ public AlfTextualRepresentation getSnapshot(NamedElement modelElement) throws RepresentationParsingError {
+ if (modelElement == null) {
+ throw new RepresentationParsingError(
+ "The model element for which the representation is calculated cannot be null");
+ }
+ AlfTextualRepresentation representation = new AlfTextualRepresentation(modelElement);
+ representation.setText(new DefaultEditStringRetrievalStrategy().getGeneratedEditString(modelElement));
+ representation.setEditionState(new BackupState(
+ new Timestamp(Calendar.getInstance().getTimeInMillis()),
+ EditionStatus.MERGED));
+ return representation;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParsingError.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParsingError.java
new file mode 100644
index 00000000000..fbc6e82baef
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.text/src/org/eclipse/papyrus/uml/alf/text/representation/util/RepresentationParsingError.java
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * J�r�mie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.text.representation.util;
+
+@SuppressWarnings("serial")
+public class RepresentationParsingError extends Exception {
+
+ public RepresentationParsingError() {
+ }
+
+ public RepresentationParsingError(String arg0) {
+ super(arg0);
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.classpath b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.classpath
new file mode 100644
index 00000000000..b1dabee3829
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.project b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.project
new file mode 100644
index 00000000000..578c14e5c99
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.uml.alf.transaction</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/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.settings/org.eclipse.jdt.core.prefs b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..11f6e462df7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/META-INF/MANIFEST.MF b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..1f5439aabb5
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.papyrus.uml.alf.transaction
+Bundle-SymbolicName: org.eclipse.papyrus.uml.alf.transaction;singleton:=true
+Bundle-Version: 1.1.0.qualifier
+Bundle-Activator: org.eclipse.papyrus.uml.alf.transaction.ActivatorTransaction
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.uml2.uml;bundle-version="5.1.0",
+ org.eclipse.papyrus.uml.alf.libraries;bundle-version="1.1.0",
+ org.eclipse.gmf.runtime.emf.commands.core,
+ org.eclipse.papyrus.infra.core,
+ org.eclipse.papyrus.infra.emf,
+ org.eclipse.gmf.runtime.common.ui.services,
+ org.eclipse.papyrus.infra.gmfdiag.commands,
+ org.eclipse.papyrus.uml.xtext.integration.ui,
+ org.eclipse.xtext.ui;bundle-version="2.8.0",
+ org.eclipse.papyrus.uml.alf,
+ org.eclipse.papyrus.uml.alf.text,
+ org.eclipse.papyrus.infra.core.log,
+ org.eclipse.compare
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-ActivationPolicy: lazy
+Export-Package: org.eclipse.papyrus.uml.alf.transaction,
+ org.eclipse.papyrus.uml.alf.transaction.commands,
+ org.eclipse.papyrus.uml.alf.transaction.commit,
+ org.eclipse.papyrus.uml.alf.transaction.job
+Bundle-Vendor: %providerName
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/about.html b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/about.html
new file mode 100644
index 00000000000..209103075a7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>November 14, 2008</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/build.properties b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/build.properties
new file mode 100644
index 00000000000..e3693a3b66e
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html,\
+ plugin.xml
+src.includes = about.html
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/plugin.xml b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/plugin.xml
new file mode 100644
index 00000000000..fb44258b67e
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/plugin.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.papyrus.infra.core.service">
+ <service
+ classname="org.eclipse.papyrus.uml.alf.transaction.observation.FUMLElementService"
+ description="Service to register a listener onto model elements that are in the fUML subset"
+ id="org.eclipse.papyrus.uml.alf.transaction.observation.FUMLElementService"
+ priority="1"
+ startKind="startup">
+ <dependsOn
+ description="Editing domain which will receive the fUML listener"
+ serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
+ </dependsOn>
+ </service>
+ </extension>
+
+</plugin>
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/pom.xml b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/pom.xml
new file mode 100644
index 00000000000..d9fb7a8b0fb
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../../../../releng/top-pom-extras.xml</relativePath>
+ </parent>
+ <artifactId>org.eclipse.papyrus.uml.alf.transaction</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project> \ No newline at end of file
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/ActivatorTransaction.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/ActivatorTransaction.java
new file mode 100644
index 00000000000..fd7eff3f384
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/ActivatorTransaction.java
@@ -0,0 +1,56 @@
+package org.eclipse.papyrus.uml.alf.transaction;
+
+import org.eclipse.papyrus.infra.core.log.LogHelper;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ActivatorTransaction extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.uml.alf.transaction"; //$NON-NLS-1$
+
+ // The shared instance
+ private static ActivatorTransaction plugin;
+
+ public static LogHelper logger;
+
+ /**
+ * The constructor
+ */
+ public ActivatorTransaction() {
+ }
+
+ /*
+ * (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;
+ logger = 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;
+ logger = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static ActivatorTransaction getDefault() {
+ return plugin;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommand.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommand.java
new file mode 100644
index 00000000000..37109581d15
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommand.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * Transaction used by the ALF framework to persist modification of UML model
+ */
+public abstract class AlfCommand extends RecordingCommand {
+
+ /**
+ * The state of a particular model element given as text
+ */
+ protected AlfTextualRepresentation modelElementState;
+
+
+ public AlfCommand(String commandLabel, AlfTextualRepresentation state) {
+ super(TransactionUtil.getEditingDomain(state.getOwner()));
+ this.modelElementState = state;
+ }
+
+ /**
+ * Returns the UML named element target by the command execution
+ */
+ public NamedElement getCommandTarget() {
+ return this.modelElementState.getOwner();
+ }
+
+ /**
+ * Returns the modification that need to be applied to a particular model element
+ */
+ public AlfTextualRepresentation getModelElementState() {
+ return this.modelElementState;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandFactory.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandFactory.java
new file mode 100644
index 00000000000..9c1f484dd61
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandFactory.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jrmie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+/**
+ * Factory providing facilities to instantiate ALF commands.
+ */
+public class AlfCommandFactory {
+
+ /** The factory. */
+ private static AlfCommandFactory factory;
+
+ /**
+ * Instantiates a new alf command factory.
+ */
+ private AlfCommandFactory() {
+ }
+
+ /**
+ * Gets the single instance of AlfCommandFactory.
+ *
+ * @return single instance of AlfCommandFactory
+ */
+ public static AlfCommandFactory getInstance() {
+ if (factory == null) {
+ factory = new AlfCommandFactory();
+ }
+ return factory;
+ }
+
+ /**
+ * Creates a new AlfCommand object.
+ *
+ * @param element
+ * the element
+ * @param textualRepresentation
+ * the textual representation
+ * @return the abstract transactional command
+ */
+ public AlfCommand createCompilationCommand(AlfTextualRepresentation representation) {
+ return new CompileCommand(representation);
+ }
+
+ /**
+ * Creates a new AlfCommand object.
+ *
+ * @param element
+ * the element
+ * @param textualRepresentation
+ * the textual representation
+ * @return the abstract transactional command
+ */
+ public AlfCommand creatSaveCommand(AlfTextualRepresentation representation) {
+ return new VersioningSaveCommand(representation);
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandLabels.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandLabels.java
new file mode 100644
index 00000000000..727c1a02ee8
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/AlfCommandLabels.java
@@ -0,0 +1,25 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+/**
+ * Provides ALF commands labels.
+ */
+public class AlfCommandLabels {
+
+ public static final String COMPILATION = "Compilation";
+
+ public static final String CREATE_OR_UPDATE_TEXTUAL_REPRESENTATION = "Create Or Update Textual Representation";
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/CompileCommand.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/CompileCommand.java
new file mode 100644
index 00000000000..d9455109ec7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/CompileCommand.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+import org.eclipse.core.runtime.AssertionFailedException;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.papyrus.uml.alf.AlfCompiler;
+import org.eclipse.papyrus.uml.alf.MappingError;
+import org.eclipse.papyrus.uml.alf.ParsingError;
+import org.eclipse.papyrus.uml.alf.libraries.helper.AlfUtil;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * This command enables the compilation (ALF->fUML) of the given textual representation
+ */
+public class CompileCommand extends AlfCommand {
+
+ protected CompileCommand(AlfTextualRepresentation modelElementState) {
+ super(AlfCommandLabels.COMPILATION, modelElementState);
+ }
+
+ /**
+ * Compile the description provided by the textual representation and merge
+ * them within the current model element
+ */
+ protected void doExecute() {
+ NamedElement context = this.modelElementState.getOwner();
+ Model root = context.getModel();
+ if (root != null) {
+ AlfCompiler alfCompiler = new AlfCompiler(
+ (NamedElement) this.modelElementState.getOwner(),
+ AlfUtil.getInstance().getStandardProfile(root),
+ AlfUtil.getInstance().getActionLanguageProfile(root));
+ try {
+ alfCompiler.compile(this.modelElementState.getContent());
+ } catch (ParsingError e) {
+ e.printStackTrace();
+ throw new WrappedException(e);
+ } catch (MappingError e) {
+ e.printStackTrace();
+ throw new WrappedException(e);
+ } catch (AssertionFailedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/SaveCommand.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/SaveCommand.java
new file mode 100644
index 00000000000..af4fe98714d
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/SaveCommand.java
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+import org.eclipse.papyrus.uml.alf.libraries.helper.AlfUtil;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.uml2.uml.Comment;
+import org.eclipse.uml2.uml.UMLFactory;
+
+/**
+ * This command enables the backup of the specification of particular model element
+ * in a comment owned by this latter
+ */
+public class SaveCommand extends AlfCommand {
+
+ protected SaveCommand(AlfTextualRepresentation representation) {
+ super(AlfCommandLabels.CREATE_OR_UPDATE_TEXTUAL_REPRESENTATION, representation);
+ }
+
+ /**
+ * Saves the specification in a comment stereotyped TextualRepresentation
+ */
+ protected void doExecute() {
+ AlfUtil helper = AlfUtil.getInstance();
+ /* 1. Make sure it exists a comment to save the model element description */
+ Comment comment = this.modelElementState.getSource();
+ if (comment == null) {
+ comment = UMLFactory.eINSTANCE.createComment();
+ this.modelElementState.setSource(comment);
+ }
+ /* 2. Make sure the comment used to save the model element description has a owner */
+ if (comment.getOwner() == null) {
+ this.modelElementState.getOwner().getOwnedComments().add(comment);
+ }
+ /* 3. Set the body of the comment with the model element description */
+ comment.setBody(this.modelElementState.getContent());
+ /* 4. Make sure the TextualRepresentation stereotype is applied onto the comment */
+ if (!helper.isATextualRepresentationComment(comment)) {
+ helper.applyTextualRepresentation(comment);
+ }
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/VersioningSaveCommand.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/VersioningSaveCommand.java
new file mode 100644
index 00000000000..5d67da750ee
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commands/VersioningSaveCommand.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commands;
+
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupUtil;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+public class VersioningSaveCommand extends SaveCommand {
+
+ protected VersioningSaveCommand(AlfTextualRepresentation representation) {
+ super(representation);
+ }
+
+ /**
+ * In addition to save the specification of a model element, this command
+ * also serialization about edition time and status (i.e. is the specification
+ * merged into the model or is it just saved in the comment waiting to be propagated).
+ */
+ protected void doExecute() {
+ /* 1. Saves the stereotyped comment in the model */
+ super.doExecute();
+ /* 2. Save time and edition status */
+ BackupUtil.getInstance().applyBackup(this.modelElementState.getSource(), this.modelElementState.getEditionState());
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ChangeScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ChangeScenario.java
new file mode 100644
index 00000000000..406951252e7
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ChangeScenario.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import org.eclipse.papyrus.uml.alf.libraries.helper.AlfUtil;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupUtil;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+public abstract class ChangeScenario extends Scenario implements IChangeScenario {
+
+ /**
+ * The model state that is taken as reference to perform a change
+ */
+ protected AlfTextualRepresentation modelStateToBeCommitted;
+
+ public ChangeScenario() {
+ super();
+ this.modelStateToBeCommitted = null;
+ }
+
+ public void before() {
+ /* 1. Apply action language profile if it is not already applied */
+ if (!AlfUtil.getInstance().isActionLanguageProfileApplied(this.currentModelState.getOwner())) {
+ AlfUtil.getInstance().applyActionLanguageProfile(this.currentModelState.getOwner());
+ }
+ /* 2. Apply standard profile if it is not already applied */
+ if (!AlfUtil.getInstance().isStandardProfileApplied(this.currentModelState.getOwner())) {
+ AlfUtil.getInstance().applyStandardProfile(this.currentModelState.getOwner());
+ }
+ /* 3. Apply backup profile if it is not already applied */
+ if (!BackupUtil.getInstance().isBackupProfileApplied(this.currentModelState.getOwner())) {
+ BackupUtil.getInstance().applyBackupProfile(this.currentModelState.getOwner());
+ }
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/CommitScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/CommitScenario.java
new file mode 100644
index 00000000000..b3017c20764
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/CommitScenario.java
@@ -0,0 +1,96 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import static org.eclipse.papyrus.uml.alf.transaction.ActivatorTransaction.logger;
+
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState.EditionStatus;
+import org.eclipse.papyrus.uml.alf.transaction.job.AlfCompilationJob;
+import org.eclipse.uml2.uml.NamedElement;
+
+
+/**
+ * This class describes the process of propagating the state of a particular
+ * model element in a given UML model
+ */
+public class CommitScenario extends ChangeScenario {
+
+ /**
+ * Flag use to know if the commit is required. it may change in the before method
+ */
+ private boolean isCommitRequired;
+
+ public CommitScenario() {
+ super();
+ this.isCommitRequired = true;
+ }
+
+ /**
+ * Update the user model state edition status
+ */
+ public void before() {
+ /* 1. Check parent constraints */
+ super.before();
+ /* 2. Update user model state meta-data */
+ BackupState editionState = new BackupState();
+ editionState.status = EditionStatus.MERGED;
+ editionState.timestamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
+ this.userModelState.setEditionState(editionState);
+ this.modelStateToBeCommitted = this.userModelState;
+ }
+
+ /**
+ * Propagate the model state specified in text within the model
+ *
+ * @param - the model element to update with the specified changes
+ */
+ public void execute(NamedElement target, final String lastEditedVersion) {
+ /* 1. Load the states of the target */
+ this.init(target);
+ if (!this.userModelState.getContent().equals(lastEditedVersion)) {
+ this.userModelState.setText(lastEditedVersion);
+ }
+ /* 2. Realize before actions */
+ this.before();
+ if (this.isCommitRequired) {
+ /* 3.1. Schedule a job in charge of propagated the changes in the model */
+ Job job = new AlfCompilationJob(this.modelStateToBeCommitted);
+ job.setPriority(Job.SHORT);
+ job.addJobChangeListener(new JobChangeAdapter() {
+ @Override
+ public void done(IJobChangeEvent event) {
+ CommitScenario.this.after();
+ }
+ });
+ job.schedule();
+ } else {
+ this.isCommitRequired = true;
+ }
+ }
+
+ /**
+ * This method is automatically called after the job scheduled by this scenario terminates.
+ */
+ public void after() {
+ logger.info("Compilation Job Done");
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IChangeScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IChangeScenario.java
new file mode 100644
index 00000000000..bedb1638a9a
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IChangeScenario.java
@@ -0,0 +1,17 @@
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import org.eclipse.uml2.uml.NamedElement;
+
+public interface IChangeScenario {
+
+ /**
+ * The core method of a scenario
+ *
+ * @param target
+ * - the element for which the scenario is executed
+ * @param lastEditedVersion
+ * - the last version of the textual representation (usually in an editor)
+ */
+ public void execute(NamedElement target, final String lastEditedVersion);
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IScenario.java
new file mode 100644
index 00000000000..55f4b014bc3
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/IScenario.java
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+public abstract interface IScenario {
+
+ /**
+ * Computations that need to be realized before the main method of the scenario
+ */
+ public void before();
+
+ /**
+ * Computations that need to be realized after the main method of the scenario
+ */
+ public void after();
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ISyncScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ISyncScenario.java
new file mode 100644
index 00000000000..188833c40b5
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ISyncScenario.java
@@ -0,0 +1,30 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.uml2.uml.Element;
+
+public interface ISyncScenario {
+ /**
+ * The core method of a scenario
+ *
+ * @param target
+ * - the element for which the scenario is executed
+ * @return command - a command (that may be compound) to be executed in order to perform the synchronization
+ */
+ public Command synchronize(Element target, List<Notification> changes);
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SaveScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SaveScenario.java
new file mode 100644
index 00000000000..f877869e1fa
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SaveScenario.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import static org.eclipse.papyrus.uml.alf.transaction.ActivatorTransaction.logger;
+
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupState.EditionStatus;
+import org.eclipse.papyrus.uml.alf.transaction.job.SaveTextualRepresentationJob;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * This class describes the process of persisting the state description
+ * attached to a particular model element.
+ */
+public class SaveScenario extends ChangeScenario {
+
+ /**
+ * Flag use to know if the backup is required. It may change in the before method
+ */
+ private boolean isBackupRequired;
+
+ public SaveScenario() {
+ super();
+ this.isBackupRequired = true;
+ }
+
+ /**
+ * If the <code>userModelState<code> and the <code>currentModelState<code> are not different
+ * then consider the textual specification was MERGED. Otherwise, the user model stand point
+ * is considered as SAVED. Typically it diverges from state of the current model.
+ */
+ public void before() {
+ super.before();
+ if (!this.userModelState.isDifferent(this.currentModelState)) {
+ this.userModelState.rebase(this.currentModelState);
+ } else {
+ BackupState editionState = new BackupState();
+ editionState.status = EditionStatus.SAVED;
+ editionState.timestamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
+ this.userModelState.setEditionState(editionState);
+ }
+ this.modelStateToBeCommitted = this.userModelState;
+ }
+
+ /**
+ * Persist in the model the state of the target as a comment
+ *
+ * @param target
+ * - the model element state to persist
+ */
+ public void execute(NamedElement target, final String lastEditedVersion) {
+ /* 1. Load the states of the target */
+ this.init(target);
+ if (!this.userModelState.getContent().equals(lastEditedVersion)) {
+ this.userModelState.setText(lastEditedVersion);
+ }
+ /* 2. Realize before actions */
+ this.before();
+ /* 3. Is a backup required */
+ if (this.isBackupRequired) {
+ /* 3.1. Schedule a job in charge of saving target state */
+ Job job = new SaveTextualRepresentationJob(this.modelStateToBeCommitted);
+ job.setPriority(Job.SHORT);
+ job.addJobChangeListener(new JobChangeAdapter() {
+ @Override
+ public void done(IJobChangeEvent event) {
+ SaveScenario.this.after();
+ }
+ });
+ job.schedule();
+ } else {
+ this.isBackupRequired = true;
+ }
+ }
+
+ /**
+ * This method is automatically called after the job scheduled by this scenario terminates.
+ */
+ public void after() {
+ logger.info("Save Job Done");
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/Scenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/Scenario.java
new file mode 100644
index 00000000000..bcc79b83562
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/Scenario.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.text.representation.util.RepresentationParser;
+import org.eclipse.papyrus.uml.alf.text.representation.util.RepresentationParsingError;
+import org.eclipse.uml2.uml.NamedElement;
+
+public abstract class Scenario implements IScenario {
+
+ /**
+ * The textual representation of a model element from the user stand point
+ */
+ protected AlfTextualRepresentation userModelState;
+
+ /**
+ * The textual representation of a model element from the semantic model stand point
+ */
+ protected AlfTextualRepresentation currentModelState;
+
+ public Scenario() {
+ this.userModelState = null;
+ this.currentModelState = null;
+ }
+
+ protected void init(NamedElement target) throws IllegalArgumentException {
+ if (target == null) {
+ throw new IllegalArgumentException("The model element provided to the scenario cannot be null");
+ }
+ try {
+ this.userModelState = RepresentationParser.getInstance().parse(target);
+ } catch (RepresentationParsingError e) {
+ e.printStackTrace();
+ }
+ try {
+ this.currentModelState = RepresentationParser.getInstance().getSnapshot(target);
+ } catch (RepresentationParsingError e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ScenarioFactory.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ScenarioFactory.java
new file mode 100644
index 00000000000..ced2cf605ed
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/ScenarioFactory.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+public class ScenarioFactory {
+
+ private static ScenarioFactory INSTANCE;
+
+ private ScenarioFactory() {
+ }
+
+ public static ScenarioFactory getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new ScenarioFactory();
+ }
+ return INSTANCE;
+ }
+
+ public IChangeScenario createSaveScenario() {
+ return new SaveScenario();
+ }
+
+ public IChangeScenario createCommitScenario() {
+ return new CommitScenario();
+ }
+
+ public ISyncScenario createSyncScenario() {
+ return new SyncScenario();
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SyncScenario.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SyncScenario.java
new file mode 100644
index 00000000000..370ca87a7ab
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/commit/SyncScenario.java
@@ -0,0 +1,163 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.commit;
+
+import static org.eclipse.papyrus.uml.alf.transaction.ActivatorTransaction.logger;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.compare.CompareUI;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.uml.alf.text.merge.manual.AlfCompareEditor;
+import org.eclipse.papyrus.uml.alf.text.merge.manual.MergeActionDialog;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.transaction.commands.AlfCommandFactory;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Generalization;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.Package;
+
+public class SyncScenario extends Scenario implements ISyncScenario {
+
+ /**
+ * The model state that is taken as reference to perform the synchronization
+ */
+ protected AlfTextualRepresentation modelStateToBeCommitted;
+
+ public SyncScenario() {
+ super();
+ this.modelStateToBeCommitted = null;
+ }
+
+ /**
+ * Checks required before to perform a synchronization
+ */
+ public void before() {
+ /* 1. It means the user model has not been saved in the current model */
+ if (this.userModelState.isSaved()) {
+ /* 1.1. The two models diverge */
+ if (this.userModelState.isDifferent(this.currentModelState)) {
+ MergeActionDialog mergeActionDialog = new MergeActionDialog(Display.getCurrent().getActiveShell(), this.currentModelState.getOwner());
+ /* 1.1.1. The user has to choose what to do */
+ if (mergeActionDialog.open() == Window.OK) {
+ if (mergeActionDialog.getReturnCode() == MergeActionDialog.REBASE) {
+ this.userModelState.rebase(this.currentModelState);
+ this.modelStateToBeCommitted = this.userModelState;
+ } else if (mergeActionDialog.getReturnCode() == MergeActionDialog.MERGE) {
+ CompareUI.openCompareDialog(new AlfCompareEditor(this.userModelState, this.currentModelState));
+ } else {
+ this.currentModelState.reconcile(this.userModelState);
+ this.currentModelState.setSource(this.userModelState.getSource());
+ this.modelStateToBeCommitted = this.currentModelState;
+ }
+ }
+ }
+ } else {
+ this.modelStateToBeCommitted = this.userModelState.rebase(this.currentModelState);
+ }
+ }
+
+ protected Set<NamedElement> getRealTargets(Element target, List<Notification> changes) {
+ Set<NamedElement> realTargets = new HashSet<NamedElement>();
+ Iterator<Notification> changesIterator = changes.iterator();
+ /* 1. Handle model modifications implied by Generalization */
+ if (target instanceof Generalization) {
+ while (changesIterator.hasNext()) {
+ Notification notification = changesIterator.next();
+ switch (notification.getEventType()) {
+ /* Handle the case where Class::superClass derived feature changed but no notification was emitted */
+ case Notification.SET: {
+ /* The specific feature has changed (deletion / update) */
+ if (notification.getFeature() == UMLPackage.eINSTANCE.getGeneralization_Specific()
+ && notification.getOldValue() != null) {
+ realTargets.add((NamedElement) notification.getOldValue());
+ }
+ /* The general feature has changed (deletion / update) */
+ else if (notification.getFeature() == UMLPackage.eINSTANCE.getGeneralization_General()
+ && ((Generalization) target).getSpecific() != null) {
+ realTargets.add(((Generalization) target).getSpecific());
+ }
+ }
+ break;
+ }
+ }
+ }
+ /* 2. Handle model modifications implied by Packages */
+ else if (target instanceof Package) {
+ while (changesIterator.hasNext()) {
+ Notification notification = changesIterator.next();
+ switch (notification.getEventType()) {
+ case Notification.ADD: {
+ if (notification.getFeature() == UMLPackage.eINSTANCE.getPackage_PackagedElement()) {
+ realTargets.add((NamedElement) notification.getNewValue());
+ }
+ }
+ break;
+ case Notification.REMOVE: {
+ if (notification.getFeature() == UMLPackage.eINSTANCE.getPackage_PackagedElement()) {
+ NamedElement oldValue = (NamedElement) notification.getOldValue();
+ /* In case a element is deleted from the package */
+ if (oldValue.getModel() != null) {
+ realTargets.add((NamedElement) notification.getOldValue());
+ }
+ }
+ }
+ break;
+ }
+ }
+ realTargets.add((Package) target);
+ }
+ /* 3. */
+ else {
+ realTargets.add((NamedElement) target);
+ }
+ return realTargets;
+ }
+
+ public Command synchronize(Element target, List<Notification> changes) {
+ CompoundCommand compoundCommand = new CompoundCommand("synchronize");
+ for (NamedElement affectedElement : this.getRealTargets(target, changes)) {
+ compoundCommand.append(this._synchronize(affectedElement));
+ }
+ return compoundCommand;
+ }
+
+ /**
+ * Provide a synchronization command for the given target
+ *
+ * @param target
+ * - the model element on which textual specification must be aligned
+ * @return command - a command to synchronize the model element and the text
+ */
+ protected Command _synchronize(NamedElement target) {
+ /* 1. Load the target states */
+ this.init(target);
+ /* 2. Do before checks */
+ this.before();
+ /* 3. Provide save command */
+ return AlfCommandFactory.getInstance().creatSaveCommand(this.modelStateToBeCommitted);
+ }
+
+ public void after() {
+ logger.info("Synchronization Done");
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfAbstractJob.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfAbstractJob.java
new file mode 100644
index 00000000000..29e91c3e593
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfAbstractJob.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.job;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForResource;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+
+public abstract class AlfAbstractJob extends Job {
+
+ protected AlfTextualRepresentation modelElementState;
+
+ protected TransactionalEditingDomain getEditingDomain() {
+ ServicesRegistry registry = null;
+ try {
+ registry = ServiceUtilsForResource.getInstance().getServiceRegistry(this.modelElementState.getOwner().eResource());
+ } catch (ServiceException e) {
+ e.printStackTrace();
+ }
+ TransactionalEditingDomain domain = null;
+ if (registry != null) {
+ try {
+ domain = ServiceUtils.getInstance().getTransactionalEditingDomain(registry);
+ } catch (ServiceException e) {
+ e.printStackTrace();
+ }
+ }
+ return domain;
+ }
+
+ public AlfAbstractJob(String name, AlfTextualRepresentation modelElemtState) {
+ super(name);
+ this.modelElementState = modelElemtState;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfCompilationJob.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfCompilationJob.java
new file mode 100644
index 00000000000..cf87db6d3e1
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfCompilationJob.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.alf.transaction.job;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.uml.alf.text.generation.DefaultEditStringRetrievalStrategy;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.transaction.commands.AlfCommandFactory;
+
+public class AlfCompilationJob extends AlfAbstractJob {
+
+ public static final String NAME = "Compile";
+
+ public AlfCompilationJob(AlfTextualRepresentation representation) {
+ super(NAME, representation);
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ IStatus jobStatus = Status.OK_STATUS;
+ TransactionalEditingDomain domain = this.getEditingDomain();
+ if (domain != null) {
+ /* Protect the resource in case of concurrent jobs */
+ Resource resource = this.modelElementState.getOwner().eResource();
+ synchronized (resource) {
+ /* 1. Do not listen to modifications that occur on the resource during compilation */
+ resource.setTrackingModification(false);
+ /* 2. Do compilation phase */
+ try {
+ domain.getCommandStack().execute(AlfCommandFactory.getInstance().createCompilationCommand(this.modelElementState));
+ } catch (Exception e) {
+ e.printStackTrace();
+ jobStatus = Status.CANCEL_STATUS;
+ }
+ /* 3. Save the textual representation within the model */
+ if (jobStatus.equals(Status.OK_STATUS)) {
+ this.modelElementState.setText(new DefaultEditStringRetrievalStrategy().getGeneratedEditString(this.modelElementState.getOwner()));
+ /* 3. Execute the commands */
+ try {
+ domain.getCommandStack().execute(AlfCommandFactory.getInstance().creatSaveCommand(this.modelElementState));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ /* 4. Restore the modification tracking */
+ resource.setTrackingModification(true);
+ }
+ } else {
+ jobStatus = Status.CANCEL_STATUS;
+ }
+ return jobStatus;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfJobObserver.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfJobObserver.java
new file mode 100644
index 00000000000..f686076de20
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/AlfJobObserver.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.job;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.papyrus.uml.xtext.integration.job.XtextValidationJob;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+
+public class AlfJobObserver extends JobChangeAdapter {
+
+ private Button commitButtton;
+
+ public AlfJobObserver(Button commitButton) {
+ this.commitButtton = commitButton;
+ }
+
+ public void done(IJobChangeEvent event) {
+ if (event.getJob() instanceof XtextValidationJob) {
+ XtextValidationJob job = (XtextValidationJob) event.getJob();
+ this.setCommitButtonState(job.hasValidationIssues());
+ }
+ }
+
+ protected void setCommitButtonState(boolean validationIssues) {
+ Display ui = Display.getDefault();
+ if (ui != null) {
+ if (!validationIssues) {
+ ui.syncExec(new Runnable() {
+ public void run() {
+ if (!AlfJobObserver.this.commitButtton.isDisposed() &&
+ !AlfJobObserver.this.commitButtton.isEnabled()) {
+ AlfJobObserver.this.commitButtton.setEnabled(true);
+ }
+ }
+ });
+ }
+ else {
+ ui.syncExec(new Runnable() {
+ public void run() {
+ if (!AlfJobObserver.this.commitButtton.isDisposed() &&
+ AlfJobObserver.this.commitButtton.isEnabled()) {
+ AlfJobObserver.this.commitButtton.setEnabled(false);
+ }
+ }
+ });
+ }
+ }
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/SaveTextualRepresentationJob.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/SaveTextualRepresentationJob.java
new file mode 100644
index 00000000000..5f90f77671f
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/job/SaveTextualRepresentationJob.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.job;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.transaction.commands.AlfCommandFactory;
+
+public class SaveTextualRepresentationJob extends AlfAbstractJob {
+
+ public static final String NAME = "Save";
+
+ public SaveTextualRepresentationJob(AlfTextualRepresentation representation) {
+ super(NAME, representation);
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ /* 1. Retrieve the editing domain */
+ TransactionalEditingDomain domain = this.getEditingDomain();
+ /* 3. Ask for the execution of the command */
+ if (domain != null) {
+ /* Protect the resource in case of concurrent jobs */
+ Resource resource = this.modelElementState.getOwner().eResource();
+ synchronized (resource) {
+ domain.getCommandStack().execute(AlfCommandFactory.getInstance().creatSaveCommand(this.modelElementState));
+ }
+ } else {
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ }
+
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/FUMLElementService.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/FUMLElementService.java
new file mode 100644
index 00000000000..7a1ac24fc4b
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/FUMLElementService.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.observation;
+
+import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.services.IService;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
+import org.eclipse.papyrus.infra.core.utils.ServiceUtils;
+import org.eclipse.papyrus.uml.alf.transaction.observation.listener.FUMLElementListener;
+
+public class FUMLElementService implements IService {
+
+ protected TransactionalEditingDomain editingDomain;
+
+ protected ResourceSetListenerImpl listener;
+
+ public FUMLElementService() {
+ this.editingDomain = null;
+ this.listener = null;
+ }
+
+ public void init(ServicesRegistry servicesRegistry) throws ServiceException {
+ this.editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(servicesRegistry);
+ this.listener = new FUMLElementListener(this.editingDomain);
+ }
+
+ public TransactionalEditingDomain getEditingDomain() {
+ return this.editingDomain;
+ }
+
+ public void startService() throws ServiceException {
+ this.editingDomain.addResourceSetListener(this.listener);
+ }
+
+ public void disposeService() throws ServiceException {
+ this.editingDomain.removeResourceSetListener(this.listener);
+ this.listener = null;
+ }
+
+ public ResourceSetListenerImpl getListener() {
+ return this.listener;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/FUMLElementListener.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/FUMLElementListener.java
new file mode 100644
index 00000000000..99091e7d039
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/FUMLElementListener.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Copyright (c) 2015 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:
+ * Jeremie Tatibouet
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.observation.listener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListenerImpl;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.uml.alf.transaction.commit.ISyncScenario;
+import org.eclipse.papyrus.uml.alf.transaction.commit.ScenarioFactory;
+import org.eclipse.papyrus.uml.alf.transaction.observation.listener.filter.FUMLFilter;
+import org.eclipse.uml2.uml.Element;
+
+public class FUMLElementListener extends ResourceSetListenerImpl {
+
+ public FUMLElementListener(TransactionalEditingDomain editingDomain) {
+ this(editingDomain.getResourceSet());
+ }
+
+ protected FUMLElementListener(ResourceSet resourceSet) {
+ super();
+ }
+
+ public NotificationFilter getFilter() {
+ return new FUMLFilter();
+ }
+
+ /**
+ * If a changes occurs on a model element supported by fUML then
+ * 1. If this change is implied by the ALF framework then we do nothing
+ * 2. If this change is not implied by the ALF framework then we try to automatically
+ * align the textual representation onto the current state of the edited model element.
+ * Note this is not always possible (e.g. the user has ongoing changes in the text)
+ */
+ public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
+ /* 1. Initialization */
+ CompoundCommand subCommands = new CompoundCommand("Synchronization");
+ HashMap<Element, List<Notification>> modifications = new HashMap<Element, List<Notification>>();
+ /* 2. Notification handling */
+ if (!event.getNotifications().isEmpty()) {
+ /* 2.1. Notification registration phase */
+ for (Notification notification : event.getNotifications()) {
+ Element target = (Element) notification.getNotifier();
+ if (modifications.get(target) == null) {
+ modifications.put(target, new ArrayList<Notification>());
+ }
+ modifications.get(target).add(notification);
+ }
+ /* 2.2. Calculate synchronization actions through a synchronization scenario */
+ ISyncScenario scenario = ScenarioFactory.getInstance().createSyncScenario();
+ for (Element key : modifications.keySet()) {
+ subCommands.append(scenario.synchronize(key, modifications.get(key)));
+ }
+ }
+ return subCommands;
+ }
+}
diff --git a/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/filter/FUMLFilter.java b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/filter/FUMLFilter.java
new file mode 100644
index 00000000000..6f0a6dbca83
--- /dev/null
+++ b/extraplugins/alf/core/org.eclipse.papyrus.uml.alf.transaction/src/org/eclipse/papyrus/uml/alf/transaction/observation/listener/filter/FUMLFilter.java
@@ -0,0 +1,289 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.transaction.observation.listener.filter;
+
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.uml2.uml.Association;
+import org.eclipse.uml2.uml.AssociationClass;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.CommunicationPath;
+import org.eclipse.uml2.uml.Component;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Extension;
+import org.eclipse.uml2.uml.Generalization;
+import org.eclipse.uml2.uml.Model;
+import org.eclipse.uml2.uml.Node;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.Signal;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.UMLPackage;
+import org.eclipse.uml2.uml.resource.UMLResource;
+
+public class FUMLFilter extends NotificationFilter.Custom {
+
+ public FUMLFilter() {
+ }
+
+ /**
+ * Filter starting point
+ */
+ public boolean matches(Notification notification) {
+ Object notifier = notification.getNotifier();
+ if (!this.isNotifierAllowed(notifier)) {
+ return false;
+ }
+ Object feature = notification.getFeature();
+ if (notifier != null && feature != null) {
+ if (this.isEnumeration(notifier)) {
+ return this.isEnumerationFeatureListened((EStructuralFeature) feature);
+ } else if (this.isDataType(notifier)) {
+ return this.isDatatypeFeatureListened((EStructuralFeature) feature);
+ } else if (this.isPackage(notifier)) {
+ return this.isPackageFeatureListened((EStructuralFeature) feature);
+ } else if (this.isAssociation(notifier)) {
+ return this.isAssociationFeatureListener((EStructuralFeature) feature);
+ } else if (this.isSignal(notifier)) {
+ return this.isSignalFeatureListened((EStructuralFeature) feature);
+ } else if (this.isClass(notifier)) {
+ return this.isClassFeatureListened((EStructuralFeature) feature);
+ } else if (this.isGeneralization(notifier)) {
+ return this.isGeneralizationtFeatureListened((EStructuralFeature) feature);
+ }
+ }
+ return false;
+ }
+
+ private boolean isNotifierAllowed(Object notifier) {
+ boolean allowed = false;
+ if (notifier instanceof Element) {
+ EObject target = (EObject) notifier;
+ if (target.eResource() != null && target.eResource() instanceof UMLResource) {
+ allowed = target.eResource().isTrackingModification();
+ }
+ }
+ return allowed;
+ }
+
+ /*----------------------------------------------------------------------------*/
+ /* Enforce the filter to respect the fUML subset */
+ /*----------------------------------------------------------------------------*/
+
+ private boolean isGeneralization(Object notifier) {
+ return notifier instanceof Generalization;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isClass(Object notifier) {
+ if (notifier instanceof Class &&
+ (!(notifier instanceof AssociationClass) &&
+ !(notifier instanceof Component) &&
+ !(notifier instanceof Node) &&
+ !(notifier instanceof Stereotype) &&
+ !(notifier instanceof Behavior))) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isSignal(Object notifier) {
+ return notifier instanceof Signal;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isDataType(Object notifier) {
+ if (notifier instanceof DataType
+ && !(notifier instanceof Enumeration)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isPackage(Object notifier) {
+ if (notifier != null
+ && notifier instanceof Package
+ && !(notifier instanceof Model)
+ && !(notifier instanceof Profile)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isEnumeration(Object notifier) {
+ return notifier instanceof Enumeration;
+ }
+
+ /**
+ *
+ * @param notifier
+ * @return
+ */
+ private boolean isAssociation(Object notifier) {
+ if (notifier instanceof Association
+ && !(notifier instanceof AssociationClass)
+ && !(notifier instanceof Extension)
+ && !(notifier instanceof CommunicationPath)) {
+ return true;
+ }
+ return false;
+ }
+
+ /*----------------------------------------------------------------------------*/
+ /* Low level checks encoding the UML meta-model hierarchy */
+ /*----------------------------------------------------------------------------*/
+
+ private boolean isGeneralizationtFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getGeneralization_General() == feature
+ || UMLPackage.eINSTANCE.getGeneralization_Specific() == feature) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isNamedElementFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getNamedElement_Name() == feature
+ || UMLPackage.eINSTANCE.getNamedElement_QualifiedName() == feature
+ || UMLPackage.eINSTANCE.getNamedElement_Namespace() == feature
+ || UMLPackage.eINSTANCE.getNamedElement_Visibility() == feature
+ || UMLPackage.eINSTANCE.getNamedElement_Namespace() == feature) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isTypeFeatureListened(EStructuralFeature feature) {
+ return UMLPackage.eINSTANCE.getType_Package() == feature || this.isPackageableElementFeatureListened(feature);
+ }
+
+ private boolean isNamespaceFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getNamespace_ElementImport() == feature
+ || UMLPackage.eINSTANCE.getNamespace_ImportedMember() == feature
+ || UMLPackage.eINSTANCE.getNamespace_Member() == feature
+ || UMLPackage.eINSTANCE.getNamespace_OwnedMember() == feature
+ || UMLPackage.eINSTANCE.getNamespace_PackageImport() == feature
+ || this.isNamedElementFeatureListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isPackageableElementFeatureListened(EStructuralFeature feature) {
+ return this.isNamedElementFeatureListened(feature);
+ }
+
+ private boolean isPackageFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getPackage_URI() == feature
+ || UMLPackage.eINSTANCE.getPackage_NestedPackage() == feature
+ || UMLPackage.eINSTANCE.getPackage_NestingPackage() == feature
+ || UMLPackage.eINSTANCE.getPackage_OwnedType() == feature
+ || UMLPackage.eINSTANCE.getPackage_PackagedElement() == feature
+ || this.isPackageableElementFeatureListened(feature)
+ || this.isNamespaceFeatureListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isClassifierFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getClassifier_IsFinalSpecialization() == feature
+ || UMLPackage.eINSTANCE.getClassifier_IsAbstract() == feature
+ || UMLPackage.eINSTANCE.getClassifier_Attribute() == feature
+ || UMLPackage.eINSTANCE.getClassifier_Feature() == feature
+ || UMLPackage.eINSTANCE.getClassifier_General() == feature
+ || UMLPackage.eINSTANCE.getClassifier_Generalization() == feature
+ || this.isNamespaceFeatureListened(feature)
+ || this.isTypeFeatureListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isStructuredClassifierFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getStructuredClassifier_OwnedAttribute() == feature
+ || this.isClassifierFeatureListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isEncapsulatedClassifierFeatureListened(EStructuralFeature feature) {
+ return this.isStructuredClassifierFeatureListened(feature);
+ }
+
+ private boolean isBehavioredClassifierListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getBehavioredClassifier_ClassifierBehavior() == feature
+ || UMLPackage.eINSTANCE.getBehavioredClassifier_OwnedBehavior() == feature
+ || this.isClassifierFeatureListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isClassFeatureListened(EStructuralFeature feature) {
+ if (UMLPackage.eINSTANCE.getClass_IsActive() == feature
+ || UMLPackage.eINSTANCE.getClass_NestedClassifier() == feature
+ || UMLPackage.eINSTANCE.getClass_OwnedOperation() == feature
+ || UMLPackage.eINSTANCE.getClass_OwnedReception() == feature
+ || UMLPackage.eINSTANCE.getClass_SuperClass() == feature
+ || this.isEncapsulatedClassifierFeatureListened(feature)
+ || this.isBehavioredClassifierListened(feature)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isAssociationFeatureListener(EStructuralFeature feature) {
+ return UMLPackage.eINSTANCE.getAssociation_OwnedEnd() == feature || this.isClassifierFeatureListened(feature);
+ }
+
+ private boolean isSignalFeatureListened(EStructuralFeature feature) {
+ return UMLPackage.eINSTANCE.getSignal_OwnedAttribute() == feature || this.isClassifierFeatureListened(feature);
+ }
+
+ private boolean isDatatypeFeatureListened(EStructuralFeature feature) {
+ return UMLPackage.eINSTANCE.getDataType_OwnedAttribute() == feature || this.isClassifierFeatureListened(feature);
+ }
+
+ private boolean isEnumerationFeatureListened(EStructuralFeature feature) {
+ return UMLPackage.eINSTANCE.getEnumeration_OwnedLiteral() == feature || this.isDatatypeFeatureListened(feature);
+ }
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.classpath b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.classpath
new file mode 100644
index 00000000000..b1dabee3829
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.project b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.project
new file mode 100644
index 00000000000..ab93d1f965a
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.uml.alf.properties.xtext</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/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.settings/org.eclipse.jdt.core.prefs b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..11f6e462df7
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/META-INF/MANIFEST.MF b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..3696d1b0b7b
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/META-INF/MANIFEST.MF
@@ -0,0 +1,35 @@
+Manifest-Version: 1.0
+Require-Bundle: org.eclipse.ui;bundle-version="3.105.0",
+ org.eclipse.ui.forms;bundle-version="3.6.0",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.6.0",
+ org.eclipse.emf.ecore;bundle-version="2.9.0",
+ org.eclipse.gmf.runtime.common.core;bundle-version="1.7.0",
+ org.eclipse.gmf.runtime.common.ui.services;bundle-version="1.7.0",
+ org.eclipse.gmf.runtime.diagram.ui;bundle-version="1.7.0",
+ org.eclipse.gmf.runtime.diagram.ui.properties;bundle-version="1.7.0",
+ org.eclipse.papyrus.infra.core;bundle-version="1.1.0",
+ org.eclipse.papyrus.infra.gmfdiag.commands;bundle-version="1.1.0",
+ org.eclipse.papyrus.extensionpoints.editors;bundle-version="1.1.0",
+ org.eclipse.papyrus.uml.xtext.integration.ui;bundle-version="1.1.0",
+ org.eclipse.xtext;bundle-version="2.4.2",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.1.0",
+ org.eclipse.papyrus.uml.properties;bundle-version="1.1.0",
+ org.eclipse.papyrus.views.properties;bundle-version="1.1.0",
+ org.eclipse.core.jobs,
+ org.eclipse.uml2.uml,
+ org.eclipse.papyrus.uml.alf,
+ org.eclipse.swt,
+ org.eclipse.papyrus.uml.alf.ui;bundle-version="1.1.0",
+ org.eclipse.papyrus.uml.alf.libraries;bundle-version="1.1.0",
+ org.eclipse.papyrus.uml.alf.transaction;bundle-version="1.0.0",
+ org.eclipse.papyrus.uml.alf.text,
+ org.eclipse.compare
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.1.0.qualifier
+Bundle-Name: %pluginName
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.papyrus.uml.alf.properties.xtext;singleton:=true
+Bundle-RequiredExecutionEnvironment: JavaSE-1.7
+Bundle-Activator: org.eclipse.papyrus.uml.alf.properties.xtext.ActivatorALFProperties
+
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/about.html b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/about.html
new file mode 100644
index 00000000000..82d49bf5f81
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/build.properties b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/build.properties
new file mode 100644
index 00000000000..34513f24e58
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/build.properties
@@ -0,0 +1,9 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ build.properties,\
+ resources/
+src.includes = about.html
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/plugin.xml b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/plugin.xml
new file mode 100644
index 00000000000..302c5d51946
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/plugin.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.views.properties.tabbed.propertySections">
+ <propertySections
+ contributorId="TreeOutlinePage">
+ <propertySection
+ class="org.eclipse.papyrus.uml.alf.properties.xtext.sheet.AdvancedEditingPropertySection"
+ filter="org.eclipse.papyrus.uml.alf.properties.xtext.sheet.AdvancedEditingPropertySectionFilter"
+ id="alf.property.section.AdvancedEditingPropertySection"
+ tab="alf_editing">
+ <input
+ type="org.eclipse.gmf.runtime.notation.View">
+ </input>
+ <input
+ type="org.eclipse.gef.EditPart">
+ </input>
+ </propertySection>
+ </propertySections>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
+ <propertyTabs
+ contributorId="TreeOutlinePage">
+ <propertyTab
+ afterTab="uml"
+ category="org.eclipse.papyrus"
+ id="alf_editing"
+ indented="true"
+ label="ALF">
+ </propertyTab>
+ </propertyTabs>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.extensionpoints.editors.DirectEditor">
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.Class">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.Enumeration">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.Signal">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.DataType">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.Package">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ <DirectEditor
+ language="Alf"
+ objectToEdit="org.eclipse.uml2.uml.Association">
+ <popupeditor
+ editorConfiguration="org.eclipse.papyrus.uml.alf.properties.xtext.configuration.DefaultAlfXtextEditorConfiguration">
+ </popupeditor>
+ <Priority
+ name="Highest">
+ </Priority>
+ </DirectEditor>
+ </extension>
+</plugin>
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/pom.xml b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/pom.xml
new file mode 100644
index 00000000000..b332dcf4494
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.papyrus</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <relativePath>../../../../releng/top-pom-extras.xml</relativePath>
+ </parent>
+ <artifactId>org.eclipse.papyrus.uml.alf.properties.xtext</artifactId>
+ <groupId>org.eclipse.papyrus</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+</project> \ No newline at end of file
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/resources/icons/incom_stat.gif b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/resources/icons/incom_stat.gif
new file mode 100644
index 00000000000..4f419106dc4
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/resources/icons/incom_stat.gif
Binary files differ
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/ActivatorALFProperties.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/ActivatorALFProperties.java
new file mode 100644
index 00000000000..b8fa0b95bde
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/ActivatorALFProperties.java
@@ -0,0 +1,50 @@
+package org.eclipse.papyrus.uml.alf.properties.xtext;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class ActivatorALFProperties extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.uml.alf.properties.xtext"; //$NON-NLS-1$
+
+ // The shared instance
+ private static ActivatorALFProperties plugin;
+
+ /**
+ * The constructor
+ */
+ public ActivatorALFProperties() {
+ }
+
+ /*
+ * (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;
+ }
+
+ /*
+ * (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 ActivatorALFProperties getDefault() {
+ return plugin;
+ }
+
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/UndoRedoStack.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/UndoRedoStack.java
new file mode 100644
index 00000000000..5ef65f2634f
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/UndoRedoStack.java
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Petr Bodnar
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.properties.xtext;
+
+import java.util.Stack;
+
+/**
+ * Encapsulation of the Undo and Redo stack(s)
+ *
+ */
+public class UndoRedoStack<T> {
+
+ private Stack<T> undo;
+ private Stack<T> redo;
+
+ public UndoRedoStack() {
+ undo = new Stack<T>();
+ redo = new Stack<T>();
+ }
+
+ public void pushUndo(T delta) {
+ undo.add(delta);
+ }
+
+ public void pushRedo(T delta) {
+ redo.add(delta);
+ }
+
+ public T popUndo() {
+ T res = undo.pop();
+ return res;
+ }
+
+ public T popRedo() {
+ T res = redo.pop();
+ return res;
+ }
+
+ public void clearUndo() {
+ undo.clear();
+ }
+
+ public void clearRedo() {
+ redo.clear();
+ }
+
+ public boolean hasUndo() {
+ return !undo.isEmpty();
+ }
+
+ public boolean hasRedo() {
+ return !redo.isEmpty();
+ }
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/AbstractAlfXtextEditorConfiguration.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/AbstractAlfXtextEditorConfiguration.java
new file mode 100644
index 00000000000..f700bdb05f2
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/AbstractAlfXtextEditorConfiguration.java
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jeremie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.properties.xtext.configuration;
+
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.uml.alf.impl.ModelNamespaceImpl;
+import org.eclipse.papyrus.uml.alf.libraries.helper.AlfUtil;
+import org.eclipse.papyrus.uml.alf.libraries.helper.BackupUtil;
+import org.eclipse.papyrus.uml.alf.parser.antlr.MutableAlfParser;
+import org.eclipse.papyrus.uml.alf.ui.internal.AlfActivator;
+import org.eclipse.papyrus.uml.alf.properties.xtext.parser.GMFAlfParser;
+import org.eclipse.papyrus.uml.xtext.integration.DefaultXtextDirectEditorConfiguration;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+
+import com.google.inject.Injector;
+
+public abstract class AbstractAlfXtextEditorConfiguration extends DefaultXtextDirectEditorConfiguration {
+
+ private void loadProfiles(Element context) {
+ AlfUtil alfProfileHelper = AlfUtil.getInstance();
+ BackupUtil backupProfileHelper = BackupUtil.getInstance();
+ if (!alfProfileHelper.isActionLanguageProfileApplied(context)) {
+ alfProfileHelper.applyActionLanguageProfile(context);
+ }
+ if (!backupProfileHelper.isBackupProfileApplied(context)) {
+ backupProfileHelper.applyBackupProfile(context);
+ }
+ }
+
+ /**
+ * Update the context in which the Alf representation will be validated.
+ * The context is the namespace of the editedObject if any
+ *
+ * @param editedObject
+ */
+ protected void updateAlfModelContext(EObject editedObject) {
+ if (editedObject instanceof NamedElement) {
+ NamedElement element = (NamedElement) editedObject;
+ ModelNamespaceImpl.setContext(element.getNamespace());
+ this.loadProfiles(element);
+ }
+ }
+
+ /**
+ * Provide the injector with the location of the implementation of the Alf Language
+ */
+ @Override
+ public Injector getInjector() {
+ return AlfActivator.getInstance().getInjector(AlfActivator.ORG_ECLIPSE_PAPYRUS_UML_ALF_ALF);
+ }
+
+ /**
+ * Provide a GMF wrapped parser
+ */
+ public IParser createParser(final EObject semanticObject) {
+ return new GMFAlfParser(semanticObject, this);
+ }
+
+ /**
+ * Not used - see GMFCompatibleAlfParser
+ */
+ public String getEditString(IAdaptable element, int flags) {
+ return null;
+ }
+
+ /**
+ * Not used - see GMFCompatibleAlfParser
+ */
+ @Override
+ protected ICommand getParseCommand(EObject umlObject, EObject xtextObject) {
+ return null;
+ }
+
+ /**
+ * Executed before the editor opens
+ */
+ public Object preEditAction(Object objectToEdit) {
+ /* 1. Save a reference to the object to edit */
+ this.setObjectToEdit(objectToEdit);
+ /* 2. Change the compilation context */
+ this.updateAlfModelContext((EObject) objectToEdit);
+ /* 3. Let the parser access to the semantic element for which a textual representation is parsed */
+ MutableAlfParser.SEMANTIC_ELEMENT = (EObject) objectToEdit; /* FIXME */
+ return null;
+ }
+
+
+ /**
+ * Not used
+ */
+ public ICommand createInvalidStringCommand(final String newString, EObject semanticElement) {
+ return null;
+ }
+
+ public abstract String getEditString(EObject semanticObject);
+
+ public abstract ICommand getParseCommand(String textualRepresentation, EObject umlObject, EObject xtextObject);
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/DefaultAlfXtextEditorConfiguration.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/DefaultAlfXtextEditorConfiguration.java
new file mode 100644
index 00000000000..0daf2a21f2e
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/configuration/DefaultAlfXtextEditorConfiguration.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jérémie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.properties.xtext.configuration;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.papyrus.commands.wrappers.EMFtoGMFCommandWrapper;
+import org.eclipse.papyrus.uml.alf.text.generation.DefaultEditStringRetrievalStrategy;
+import org.eclipse.papyrus.uml.alf.text.representation.AlfTextualRepresentation;
+import org.eclipse.papyrus.uml.alf.transaction.commands.AlfCommandFactory;
+import org.eclipse.papyrus.uml.xtext.integration.XtextFakeResourceContext;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter.IContextElementProvider;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter.IContextElementProviderWithInit;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.xtext.EcoreUtil2;
+import org.eclipse.xtext.util.CancelIndicator;
+import org.eclipse.xtext.util.StringInputStream;
+
+/**
+ * Configuration used by the DirectEditor for Alf
+ */
+public class DefaultAlfXtextEditorConfiguration extends
+ AbstractAlfXtextEditorConfiguration {
+
+ /**
+ * Called each time the editor using the configuration is refreshed
+ *
+ * @param semanticObject
+ * @return the textual representation of a specific semantic object
+ */
+ @Override
+ public String getEditString(EObject semanticObject) {
+ this.updateAlfModelContext(semanticObject);
+ return new DefaultEditStringRetrievalStrategy().getEditString((NamedElement) semanticObject);
+ }
+
+ /**
+ * Build the parse command required to launch the compilation of the textual representation (only if it has no syntax errors).
+ *
+ */
+ @Override
+ public ICommand getParseCommand(String textualRepresentation,
+ EObject semanticObject, EObject xtextObject) {
+ AlfTextualRepresentation representation = new AlfTextualRepresentation((NamedElement) semanticObject);
+ IContextElementProvider provider = this.getContextProvider();
+ XtextFakeResourceContext context = new XtextFakeResourceContext(this.getInjector());
+ context.getFakeResource().eAdapters().add(new ContextElementAdapter(provider));
+ try {
+ context.getFakeResource().load(new StringInputStream(textualRepresentation), Collections.EMPTY_MAP);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (provider instanceof IContextElementProviderWithInit) {
+ ((IContextElementProviderWithInit) provider).initResource(context.getFakeResource());
+ }
+ EcoreUtil2.resolveLazyCrossReferences(context.getFakeResource(), CancelIndicator.NullImpl);
+ return new EMFtoGMFCommandWrapper(AlfCommandFactory.getInstance().createCompilationCommand(representation));
+ }
+} \ No newline at end of file
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/constraints/ALFFilterConstraint.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/constraints/ALFFilterConstraint.java
new file mode 100644
index 00000000000..2f7ca130029
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/constraints/ALFFilterConstraint.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Jeremie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.alf.properties.xtext.constraints;
+
+import org.eclipse.uml2.uml.Association;
+import org.eclipse.uml2.uml.AssociationClass;
+import org.eclipse.uml2.uml.CommunicationPath;
+import org.eclipse.uml2.uml.Extension;
+
+/**
+ * This class implements the opening constraints for the ALF editor
+ */
+public class ALFFilterConstraint {
+
+ private ALFFilterConstraint() {
+ }
+
+ /**
+ * Checks if an association can edited using ALF
+ *
+ * @param association
+ * the association evaluated against the constraints
+ *
+ * @return conforms
+ * true if the association respects the constraints
+ */
+ public static boolean conforms(Association association) {
+ boolean conforms = true;
+ /* The editor can only be opened for associations owning all of their ends */
+ if (association != null && isStrictAssociation(association)) {
+ conforms = association.getOwnedEnds().size() == association.getMemberEnds().size();
+ }
+ return conforms;
+ }
+
+ /**
+ * Checks if a given association is strictly an Association and not an instance of one of the sub-classes
+ *
+ * @param association
+ * the association for which we verifies that it is not a sub-class instance
+ *
+ * @return true if the association is only an instance of Association, false otherwise
+ */
+ private static boolean isStrictAssociation(Association association) {
+ return !(association instanceof AssociationClass) &&
+ !(association instanceof CommunicationPath) &&
+ !(association instanceof Extension);
+ }
+
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/parser/GMFAlfParser.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/parser/GMFAlfParser.java
new file mode 100644
index 00000000000..72e19f7caea
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/parser/GMFAlfParser.java
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ * Jérémie Tatibouet
+ * Arnaud Cuccuru
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.properties.xtext.parser;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
+import org.eclipse.gmf.runtime.common.ui.services.parser.IParserEditStatus;
+import org.eclipse.gmf.runtime.common.ui.services.parser.ParserEditStatus;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.uml.alf.properties.xtext.configuration.AbstractAlfXtextEditorConfiguration;
+import org.eclipse.uml2.uml.NamedElement;
+
+/**
+ * Provide the possibility to use the ALF parser directly in the context of GMF.
+ */
+public class GMFAlfParser implements IParser {
+
+ protected final static String TEXTUAL_REPRESENTATION_ERROR = "/*String representation could not be computed*/";
+
+ protected final EObject semanticObject;
+
+ protected AbstractAlfXtextEditorConfiguration configuration;
+
+ /**
+ * Retrieve the NamedElement hidden behind the adapter
+ *
+ * @param adaptable
+ * @return the adapted element
+ */
+ protected NamedElement adapt(IAdaptable adaptable) {
+ Object o = EMFHelper.getEObject(adaptable);
+ if (o != null && o instanceof NamedElement) {
+ return (NamedElement) o;
+ }
+ return null;
+ }
+
+ /**
+ * Initializes the context in which type names are going to be resolved
+ */
+
+ public GMFAlfParser(final EObject semanticObject, final AbstractAlfXtextEditorConfiguration configuration) {
+ this.semanticObject = semanticObject;
+ this.configuration = configuration;
+ }
+
+ /***
+ * Delegate computation of the textual representation to the configuration
+ */
+ public String getEditString(IAdaptable element, int flags) {
+ NamedElement target = this.adapt(element);
+ if (target != null) {
+ return this.configuration.getEditString(target);
+ } else if (this.semanticObject != null) {
+ return this.configuration.getEditString(this.semanticObject);
+ } else {
+ return TEXTUAL_REPRESENTATION_ERROR;
+ }
+ }
+
+ public IParserEditStatus isValidEditString(IAdaptable element, String editString) {
+ return ParserEditStatus.EDITABLE_STATUS;
+ }
+
+ /**
+ * Delegate creation of the parse command to the configuration
+ */
+ public ICommand getParseCommand(IAdaptable element, String newString, int flags) {
+ NamedElement target = this.adapt(element);
+ if (target != null) {
+ return this.configuration.getParseCommand(newString, target, null);
+ } else if (this.semanticObject != null) {
+ return this.configuration.getParseCommand(newString, this.semanticObject, null);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * No differences between results returned by getPrintString or getEditString
+ */
+ public String getPrintString(IAdaptable element, int flags) {
+ return this.getEditString(element, flags);
+ }
+
+ public boolean isAffectingEvent(Object event, int flags) {
+ return false;
+ }
+
+ public IContentAssistProcessor getCompletionProcessor(IAdaptable element) {
+ return null;
+ }
+
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySection.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySection.java
new file mode 100644
index 00000000000..154dce39d28
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySection.java
@@ -0,0 +1,330 @@
+/*****************************************************************************
+ * Copyright (c) 2013, 2014 Itemis AG, CEA LIST, and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Itemis - Initial API and implementation
+ * Ansgar Radermacher - added undo/redo support (inspired by code from Petr Bodnar)
+ * Christian W. Damus (CEA) - bug 323802
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.alf.properties.xtext.sheet;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.properties.sections.AbstractModelerPropertySection;
+import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.papyrus.extensionpoints.editors.Activator;
+import org.eclipse.papyrus.extensionpoints.editors.configuration.IDirectEditorConfiguration;
+import org.eclipse.papyrus.extensionpoints.editors.utils.DirectEditorsUtil;
+import org.eclipse.papyrus.extensionpoints.editors.utils.IDirectEditorsIds;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.uml.alf.transaction.job.AlfJobObserver;
+import org.eclipse.papyrus.uml.alf.properties.xtext.UndoRedoStack;
+import org.eclipse.papyrus.uml.alf.properties.xtext.sheet.ui.listeners.CommitButtonSelectionListener;
+import org.eclipse.papyrus.uml.alf.properties.xtext.sheet.ui.listeners.EditorFocusListener;
+import org.eclipse.papyrus.uml.xtext.integration.DefaultXtextDirectEditorConfiguration;
+import org.eclipse.papyrus.uml.xtext.integration.StyledTextXtextAdapter;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter.IContextElementProvider;
+import org.eclipse.papyrus.uml.xtext.integration.core.ContextElementAdapter.IContextElementProviderWithInit;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ExtendedModifyEvent;
+import org.eclipse.swt.custom.ExtendedModifyListener;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * Attention: class has been deactivated, since the additional tab is redundant with the
+ * body editor in the standard UML property tab.
+ */
+public class AdvancedEditingPropertySection extends
+ AbstractModelerPropertySection implements IContextElementProvider {
+
+ private FormToolkit toolkit;
+
+ private Form form;
+
+ private StyledText textControl;
+
+ private Button commitButton;
+
+ private DefaultXtextDirectEditorConfiguration configuration;
+
+ private StyledTextXtextAdapter xtextAdapter;
+
+ final private ContextElementAdapter contextElementAdapter = new ContextElementAdapter(
+ this);
+
+ UndoRedoStack<ExtendedModifyEvent> undoRedoStack;
+
+ protected boolean isUndo;
+
+ protected boolean isRedo;
+
+ protected EObject currentEObj;
+
+ public AdvancedEditingPropertySection() {
+ undoRedoStack = new UndoRedoStack<ExtendedModifyEvent>();
+ }
+
+ public StyledText getEditor() {
+ return this.textControl;
+ }
+
+ @Override
+ public void refresh() {
+ updateXtextAdapters(this.textControl);
+ IParser parser = getParser();
+ if (parser != null) {
+ this.textControl.setText(parser.getEditString(new EObjectAdapter(eObject), 0));
+ }
+
+ if (textControl != null) {
+ textControl.setEnabled(!isReadOnly());
+ }
+ }
+
+ @Override
+ public void aboutToBeHidden() {
+ super.aboutToBeHidden();
+ if (xtextAdapter != null) {
+ xtextAdapter.getFakeResourceContext().getFakeResource().eAdapters()
+ .remove(contextElementAdapter);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ if (toolkit != null) {
+ toolkit.dispose();
+ }
+ }
+
+ @Override
+ public final void createControls(Composite parent,
+ TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ toolkit = new FormToolkit(parent.getDisplay());
+ toolkit.setBorderStyle(SWT.BORDER);
+ super.createControls(parent, aTabbedPropertySheetPage);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
+ parent.setLayout(new GridLayout(1, true));
+ form = toolkit.createForm(parent);
+ toolkit.decorateFormHeading(form);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(form);
+ form.getBody().setLayout(new GridLayout(1, false));
+ createTextControl(form.getBody());
+ this.createPushButton(form.getBody());
+ }
+
+
+ protected void createPushButton(final Composite parent) {
+ final AlfJobObserver observer = new AlfJobObserver(this.commitButton);
+ this.commitButton = new Button(parent, SWT.PUSH);
+ this.commitButton.setText("Commit");
+ this.commitButton.setToolTipText("Commit the modifications in your model");
+ this.commitButton.setImage(new Image(Display.getDefault(), getClass().getResourceAsStream("/resources/icons/incom_stat.gif")));
+ this.commitButton.addSelectionListener(new CommitButtonSelectionListener(this));
+ this.commitButton.addDisposeListener(new DisposeListener() {
+
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ Job.getJobManager().removeJobChangeListener(observer);
+ }
+ });
+ Job.getJobManager().addJobChangeListener(new AlfJobObserver(this.commitButton));
+ }
+
+ protected void createTextControl(final Composite parent) {
+
+ textControl = new StyledText(parent, SWT.MULTI | SWT.BORDER
+ | SWT.V_SCROLL | SWT.WRAP);
+
+ textControl.setAlwaysShowScrollBars(false);
+ GridDataFactory.fillDefaults().grab(true, true).hint(parent.getSize())
+ .applyTo(textControl);
+ textControl.addExtendedModifyListener(new ExtendedModifyListener() {
+
+ public void modifyText(ExtendedModifyEvent event) {
+ if (isUndo) {
+ undoRedoStack.pushRedo(event);
+ } else { // is Redo or a normal user action
+ undoRedoStack.pushUndo(event);
+ if (!isRedo) {
+ undoRedoStack.clearRedo();
+ // TODO Switch to treat consecutive characters as one event?
+ }
+ }
+ }
+ });
+
+ textControl.addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ boolean isCtrl = (e.stateMask & SWT.CTRL) > 0;
+ boolean isAlt = (e.stateMask & SWT.ALT) > 0;
+ if (isCtrl && !isAlt) {
+ boolean isShift = (e.stateMask & SWT.SHIFT) > 0;
+ if (e.keyCode == 'z') {
+ if (isShift) {
+ redo();
+ }
+ else {
+ undo();
+ }
+ }
+ }
+ }
+ });
+
+ textControl.addFocusListener(new EditorFocusListener(this));
+ }
+
+ protected void undo() {
+ if (undoRedoStack.hasUndo()) {
+ isUndo = true;
+ revertEvent(undoRedoStack.popUndo());
+ isUndo = false;
+ }
+ }
+
+ protected void redo() {
+ if (undoRedoStack.hasRedo()) {
+ isRedo = true;
+ revertEvent(undoRedoStack.popRedo());
+ isRedo = false;
+ }
+ }
+
+ /**
+ * Reverts the given modify event, in the way as the Eclipse text editor
+ * does it.
+ *
+ * @param event
+ */
+ private void revertEvent(ExtendedModifyEvent event) {
+ textControl.replaceTextRange(event.start, event.length, event.replacedText);
+ // (causes the modifyText() listener method to be called)
+
+ textControl.setSelectionRange(event.start, event.replacedText.length());
+ }
+
+
+ protected DefaultXtextDirectEditorConfiguration getConfigurationFromSelection() {
+ EObject semanticElement = getSemanticObjectFromSelection();
+ if (semanticElement != null) {
+ IPreferenceStore store = Activator.getDefault()
+ .getPreferenceStore();
+ String semanticClassName = semanticElement.eClass()
+ .getInstanceClassName();
+ String key = IDirectEditorsIds.EDITOR_FOR_ELEMENT
+ + semanticClassName;
+ String languagePreferred = store.getString(key);
+
+ if (languagePreferred != null && !languagePreferred.equals("")) { //$NON-NLS-1$
+ IDirectEditorConfiguration configuration = DirectEditorsUtil
+ .findEditorConfiguration(languagePreferred,
+ semanticClassName);
+ if (configuration instanceof DefaultXtextDirectEditorConfiguration) {
+
+ DefaultXtextDirectEditorConfiguration xtextConfiguration = (DefaultXtextDirectEditorConfiguration) configuration;
+ xtextConfiguration.preEditAction(semanticElement);
+ return xtextConfiguration;
+ }
+ }
+ }
+ return null;
+ }
+
+ protected EObject getSemanticObjectFromSelection() {
+ Object selection = getPrimarySelection();
+ if (selection instanceof IGraphicalEditPart) {
+ return ((IGraphicalEditPart) selection).resolveSemanticElement();
+ }
+ else if (selection instanceof IAdaptable) {
+ return (EObject) ((IAdaptable) selection).getAdapter(EObject.class);
+ }
+ return null;
+ }
+
+ public IParser getParser() {
+ final EObject semanticElement = getSemanticObjectFromSelection();
+ if (configuration != null && semanticElement != null) {
+ return configuration.createParser(semanticElement);
+ }
+ return null;
+ }
+
+ protected void updateXtextAdapters(Control styledText) {
+ final Object oldObjectToEdit = configuration != null ? configuration.getObjectToEdit() : null;
+
+ final DefaultXtextDirectEditorConfiguration newConfiguration = getConfigurationFromSelection();
+ // Check if configuration has changed and update adapters
+ if (newConfiguration != null && newConfiguration != configuration) {
+ if (xtextAdapter != null) {
+ xtextAdapter.getFakeResourceContext().getFakeResource()
+ .eAdapters().remove(contextElementAdapter);
+ }
+ configuration = newConfiguration;
+ xtextAdapter = new StyledTextXtextAdapter(
+ configuration.getInjector());
+
+ EObject semanticElement = getSemanticObjectFromSelection();
+ if (semanticElement != null) {
+ newConfiguration.preEditAction(semanticElement);
+ }
+
+ xtextAdapter.getFakeResourceContext().getFakeResource().eAdapters()
+ .add(contextElementAdapter);
+ xtextAdapter.adapt((StyledText) styledText);
+ }
+
+ if (configuration.getObjectToEdit() != oldObjectToEdit) {
+ IContextElementProvider provider = configuration.getContextProvider();
+ if (provider instanceof IContextElementProviderWithInit) {
+ // update resource, if required by text editor
+ if (xtextAdapter != null) {
+ ((IContextElementProviderWithInit) provider).initResource(
+ xtextAdapter.getFakeResourceContext().getFakeResource());
+ }
+ }
+ Object semanticObject = configuration.getObjectToEdit();
+ if (semanticObject instanceof EObject) {
+ currentEObj = (EObject) semanticObject;
+ }
+ }
+ }
+
+ public EObject getContextObject() {
+ return getEObject();
+ }
+
+ @Override
+ protected boolean isReadOnly() {
+ EObject context = getContextObject();
+ return (context == null) || EMFHelper.isReadOnly(context) || super.isReadOnly();
+ }
+} \ No newline at end of file
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySectionFilter.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySectionFilter.java
new file mode 100644
index 00000000000..9ccf1c8fefa
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/AdvancedEditingPropertySectionFilter.java
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Copyright (c) 2014 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:
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.uml.alf.properties.xtext.sheet;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.papyrus.extensionpoints.editors.Activator;
+import org.eclipse.papyrus.extensionpoints.editors.configuration.ICustomDirectEditorConfiguration;
+import org.eclipse.papyrus.extensionpoints.editors.configuration.IDirectEditorConfiguration;
+import org.eclipse.papyrus.extensionpoints.editors.utils.DirectEditorsUtil;
+import org.eclipse.papyrus.extensionpoints.editors.utils.IDirectEditorsIds;
+import org.eclipse.papyrus.uml.alf.properties.xtext.constraints.ALFFilterConstraint;
+import org.eclipse.uml2.uml.Association;
+
+public class AdvancedEditingPropertySectionFilter implements IFilter {
+
+ public boolean select(Object toTest) {
+ EObject semanticElement = null;
+ if (toTest instanceof IAdaptable) {
+ semanticElement = (EObject) ((IAdaptable) toTest).getAdapter(EObject.class);
+ }
+ else if (toTest instanceof GraphicalEditPart) {
+ GraphicalEditPart part = (GraphicalEditPart) toTest;
+ semanticElement = part.resolveSemanticElement();
+ }
+ if (semanticElement != null) {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+ String key = IDirectEditorsIds.EDITOR_FOR_ELEMENT
+ + semanticElement.eClass().getInstanceClassName();
+
+ String languagePreferred = store.getString(key);
+
+ if (languagePreferred != null && !languagePreferred.equals("")) {
+ IDirectEditorConfiguration configuration = null;
+ if (languagePreferred.equals("Alf") && semanticElement instanceof Association) {
+ if (ALFFilterConstraint.conforms((Association) semanticElement)) {
+ configuration = DirectEditorsUtil.findEditorConfiguration(
+ languagePreferred, semanticElement.eClass()
+ .getInstanceClassName());
+ }
+ } else {
+ configuration = DirectEditorsUtil.findEditorConfiguration(
+ languagePreferred, semanticElement.eClass()
+ .getInstanceClassName());
+ }
+ return configuration instanceof ICustomDirectEditorConfiguration;
+ }
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/CommitButtonSelectionListener.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/CommitButtonSelectionListener.java
new file mode 100644
index 00000000000..537a5adc47c
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/CommitButtonSelectionListener.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Jrmie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.alf.properties.xtext.sheet.ui.listeners;
+
+import org.eclipse.papyrus.uml.alf.transaction.commit.ScenarioFactory;
+import org.eclipse.papyrus.uml.alf.properties.xtext.sheet.AdvancedEditingPropertySection;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.uml2.uml.NamedElement;
+
+public class CommitButtonSelectionListener extends SelectionAdapter {
+
+
+ private AdvancedEditingPropertySection propertySection;
+
+ public CommitButtonSelectionListener(AdvancedEditingPropertySection propertySection) {
+ this.propertySection = propertySection;
+ }
+
+ /**
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ public void widgetSelected(SelectionEvent event) {
+ /* 1. Retrieved the current model element */
+ NamedElement semanticObject = (NamedElement) this.propertySection.getContextObject();
+ /* 2. Retrieved its currently edited representation */
+ StyledText editor = this.propertySection.getEditor();
+ /* 3. Compile without blocking URI */
+ if (semanticObject != null && editor != null) {
+ ScenarioFactory.getInstance().createCommitScenario().execute(semanticObject, editor.getText());
+ }
+ }
+}
diff --git a/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/EditorFocusListener.java b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/EditorFocusListener.java
new file mode 100644
index 00000000000..fe0f9715813
--- /dev/null
+++ b/extraplugins/alf/ui/org.eclipse.papyrus.uml.alf.properties.xtext/src/org/eclipse/papyrus/uml/alf/properties/xtext/sheet/ui/listeners/EditorFocusListener.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2015 CEA LIST and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ * Jrmie Tatibouet (CEA LIST)
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.alf.properties.xtext.sheet.ui.listeners;
+
+import org.eclipse.papyrus.uml.alf.transaction.commit.ScenarioFactory;
+import org.eclipse.papyrus.uml.alf.properties.xtext.sheet.AdvancedEditingPropertySection;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.uml2.uml.NamedElement;
+
+public class EditorFocusListener extends FocusAdapter {
+
+
+ private AdvancedEditingPropertySection section;
+
+ public EditorFocusListener(AdvancedEditingPropertySection section) {
+ this.section = section;
+ }
+
+ /**
+ * When the ALF editor looses the focus, this triggers the execution of a backup sequence.
+ * This backup sequence saves the current state of the textual definition of the current model element.
+ * Modifications introduced in text are not propagated in the current model element.
+ */
+ @Override
+ public void focusLost(FocusEvent event) {
+ /* 1. Retrieve the alf editor */
+ StyledText alfEditor = null;
+ if (event.getSource() instanceof StyledText) {
+ alfEditor = (StyledText) event.getSource();
+ }
+ /* 2. Save the textual representation */
+ if (alfEditor != null) {
+ ScenarioFactory.getInstance().createSaveScenario().
+ execute((NamedElement) this.section.getContextObject(), alfEditor.getText());
+ }
+
+ }
+}

Back to the top